diff options
author | Yaniv Kamay <ykamay@redhat.com> | 2010-01-11 19:57:29 +0200 |
---|---|---|
committer | Yaniv Kamay <ykamay@redhat.com> | 2010-01-11 19:57:29 +0200 |
commit | 8ceb531958cb649b7cc7f16f2f504125cb430fe4 (patch) | |
tree | 847f4325a37ce7bfccf6a469659b11f775cc3e62 | |
parent | 3c1ff6448d847e6e96425fa166446b99bac5e592 (diff) | |
download | spice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.tar.gz spice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.tar.xz spice-8ceb531958cb649b7cc7f16f2f504125cb430fe4.zip |
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.
-rw-r--r-- | client/application.cpp | 66 | ||||
-rw-r--r-- | client/application.h | 9 | ||||
-rw-r--r-- | client/cmd_line_parser.cpp | 29 | ||||
-rw-r--r-- | client/platform.h | 1 | ||||
-rw-r--r-- | client/windows/main.cpp | 28 | ||||
-rw-r--r-- | client/windows/platform.cpp | 64 | ||||
-rw-r--r-- | client/x11/platform.cpp | 8 | ||||
-rw-r--r-- | common/red_error_codes.h | 1 |
8 files changed, 134 insertions, 72 deletions
diff --git a/client/application.cpp b/client/application.cpp index 839885d8..7655809d 100644 --- a/client/application.cpp +++ b/client/application.cpp @@ -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; } diff --git a/client/application.h b/client/application.h index e1c702db..47cf29ef 100644 --- a/client/application.h +++ b/client/application.h @@ -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(); diff --git a/client/cmd_line_parser.cpp b/client/cmd_line_parser.cpp index 65ae404a..caa4b034 100644 --- a/client/cmd_line_parser.cpp +++ b/client/cmd_line_parser.cpp @@ -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()); } diff --git a/client/platform.h b/client/platform.h index ec335540..5eb909dd 100644 --- a/client/platform.h +++ b/client/platform.h @@ -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(); diff --git a/client/windows/main.cpp b/client/windows/main.cpp index a1575e90..afc98c97 100644 --- a/client/windows/main.cpp +++ b/client/windows/main.cpp @@ -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; } diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index 67bb1a02..c364b35d 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -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); +} diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index 02250f11..6f550135 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -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); diff --git a/common/red_error_codes.h b/common/red_error_codes.h index c08fd510..0c068997 100644 --- a/common/red_error_codes.h +++ b/common/red_error_codes.h @@ -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 |