1
0
Fork 0

fixes for windows

This commit is contained in:
Frank Celler 2016-03-10 09:25:54 +00:00
parent ce28f5492f
commit dd36dd55e6
7 changed files with 207 additions and 94 deletions

View File

@ -24,6 +24,7 @@
#include <iostream>
#include "Basics/Common.h"
#include "Basics/build.h"
#include "Basics/files.h"
#include "Basics/messages.h"
#include "Logger/Logger.h"

View File

@ -178,8 +178,8 @@ bool V8ShellFeature::printHello(V8ClientConnection* v8connection) {
s << "arangosh (" << rest::Version::getVerboseVersionString() << ")\n"
<< "Copyright (c) ArangoDB GmbH";
_console->printLine(s.str(), true);
_console->printLine("", true);
_console->printLine(s.str());
_console->printLine("");
_console->printWelcomeInfo();
@ -194,7 +194,7 @@ bool V8ShellFeature::printHello(V8ClientConnection* v8connection) {
<< v8connection->databaseName() << "', username: '"
<< v8connection->username() << "'";
_console->printLine(is.str(), true);
_console->printLine(is.str());
} else {
std::ostringstream is;
@ -216,7 +216,7 @@ bool V8ShellFeature::printHello(V8ClientConnection* v8connection) {
promptError = true;
}
_console->printLine("", true);
_console->printLine("");
}
}

View File

@ -101,6 +101,7 @@ const optionsDocumentation = [
' - `benchargs`: additional commandline arguments to arangob',
'',
' - `build`: the directory containing the binaries',
' - `buildType`: Windows build type (Debug, Release), leave empty on linux',
'',
' - `sanitizer`: if set the programs are run with enabled sanitizer',
' and need longer tomeouts',
@ -121,6 +122,7 @@ const optionsDocumentation = [
const optionsDefaults = {
"build": "",
"buildType": "",
"cleanup": true,
"cluster": false,
"clusterNodes": 2,
@ -4164,6 +4166,13 @@ function unitTest(cases, options) {
}
BIN_DIR = fs.join(TOP_DIR, builddir, "bin");
UNITTESTS_DIR = fs.join(TOP_DIR, fs.join(builddir, "tests"));
if (options.buildType !== "") {
BIN_DIR = fs.join(BIN_DIR, options.buildType);
UNITTESTS_DIR = fs.join(UNITTESTS_DIR, options.buildType);
}
CONFIG_DIR = fs.join(TOP_DIR, builddir, "etc", "arangodb");
ARANGOB_BIN = fs.join(BIN_DIR, "arangob");
ARANGODUMP_BIN = fs.join(BIN_DIR, "arangodump");
@ -4176,7 +4185,6 @@ function unitTest(cases, options) {
JS_DIR = fs.join(TOP_DIR, "js");
LOGS_DIR = fs.join(TOP_DIR, "logs");
PEM_FILE = fs.join(TOP_DIR, "UnitTests", "server.pem");
UNITTESTS_DIR = fs.join(TOP_DIR, fs.join(builddir, "tests"));
const jsonReply = options.jsonReply;
delete options.jsonReply;

View File

@ -22,6 +22,7 @@
#include "ApplicationFeatures/ClientFeature.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "ApplicationFeatures/ConsoleFeature.h"
#include "Logger/Logger.h"
#include "ProgramOptions2/ProgramOptions.h"
@ -31,6 +32,7 @@
#include "SimpleHttpClient/SimpleHttpClient.h"
using namespace arangodb;
using namespace arangodb::application_features;
using namespace arangodb::httpclient;
using namespace arangodb::options;
using namespace arangodb::rest;
@ -134,7 +136,15 @@ void ClientFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
if (_authentication &&
!options->processingResult().touched(_section + ".password")) {
usleep(10 * 1000);
_password = ConsoleFeature::readPassword("Please specify a password: ");
ConsoleFeature* console = dynamic_cast<ConsoleFeature*>(ApplicationServer::lookupFeature("ConsoleFeature"));
if (console != nullptr) {
_password = console->readPassword("Please specify a password: ");
} else {
std::cout << "Please specify a password: " << std::flush;
std::getline(std::cin, _password);
}
}
}

View File

@ -23,6 +23,7 @@
#include "ApplicationFeatures/ConsoleFeature.h"
#include "ApplicationFeatures/ClientFeature.h"
#include "Basics/StringUtils.h"
#include "Basics/messages.h"
#include "Basics/shell-colors.h"
#include "Basics/terminal-utils.h"
@ -31,6 +32,7 @@
#include "ProgramOptions2/Section.h"
using namespace arangodb;
using namespace arangodb::basics;
using namespace arangodb::options;
ConsoleFeature::ConsoleFeature(application_features::ApplicationServer* server)
@ -48,12 +50,20 @@ ConsoleFeature::ConsoleFeature(application_features::ApplicationServer* server)
_pagerCommand("less -X -R -F -L"),
_prompt("%E@%d> "),
_promptError(false),
_supportsColors(isatty(STDIN_FILENO)),
_supportsColors(isatty(STDIN_FILENO) != 0),
_toPager(stdout),
_toAuditFile(nullptr) {
setOptional(false);
requiresElevatedPrivileges(false);
startsAfter("LoggerFeature");
if (!_supportsColors) {
_colors = false;
}
#if _WIN32
_codePage = GetConsoleOutputCP();
#endif
}
void ConsoleFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
@ -107,6 +117,12 @@ void ConsoleFeature::start() {
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
openLog();
#if _WIN32
if (_codePage != -1) {
SetConsoleOutputCP(_codePage);
}
#endif
}
void ConsoleFeature::stop() {
@ -115,25 +131,13 @@ void ConsoleFeature::stop() {
closeLog();
}
// prints a string to stdout, without a newline (Non-Windows only) on
// Windows, we'll print the line and a newline. No, we cannot use
// std::cout as this doesn't support UTF-8 on Windows.
void ConsoleFeature::printContinuous(std::string const& s) {
#ifdef _WIN32
// On Windows, we just print the line followed by a newline
printLine(s, true);
#else
fprintf(stdout, "%s", s.c_str());
fflush(stdout);
#endif
}
#ifdef _WIN32
static bool _newLine() {
COORD pos;
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &bufferInfo);
auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(handle, &bufferInfo);
if (bufferInfo.dwCursorPosition.Y + 1 >= bufferInfo.dwSize.Y) {
// when we are at the last visible line of the console
// the first line of console is deleted (the content of the console
@ -143,51 +147,55 @@ static bool _newLine() {
srctScrollRect.Bottom = bufferInfo.dwCursorPosition.Y + 1;
srctScrollRect.Left = 0;
srctScrollRect.Right = bufferInfo.dwSize.X;
COORD coordDest;
coordDest.X = 0;
coordDest.Y = -1;
CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo;
CHAR_INFO chiFill;
chiFill.Char.AsciiChar = (char)' ';
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
&consoleScreenBufferInfo)) {
if (GetConsoleScreenBufferInfo(handle, &consoleScreenBufferInfo)) {
chiFill.Attributes = consoleScreenBufferInfo.wAttributes;
} else {
// Fill the bottom row with green blanks.
chiFill.Attributes = BACKGROUND_GREEN | FOREGROUND_RED;
}
ScrollConsoleScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE), &srctScrollRect,
ScrollConsoleScreenBuffer(handle, &srctScrollRect,
nullptr, coordDest, &chiFill);
pos.Y = bufferInfo.dwCursorPosition.Y;
pos.X = 0;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
SetConsoleCursorPosition(handle, pos);
return true;
} else {
pos.Y = bufferInfo.dwCursorPosition.Y + 1;
pos.X = 0;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
SetConsoleCursorPosition(handle, pos);
return false;
}
}
#endif
#ifdef _WIN32
static void _printLine(std::string const& s) {
LPWSTR wBuf = (LPWSTR)TRI_Allocate(TRI_CORE_MEM_ZONE,
(sizeof WCHAR) * (s.size() + 1), true);
static void _print2(std::string const& s, int attr) {
size_t sLen = s.size();
LPWSTR wBuf = new WCHAR[sLen + 1];
int wLen = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, wBuf,
(int)((sizeof WCHAR) * (s.size() + 1)));
(int)((sizeof WCHAR) * (sLen + 1)));
if (wLen) {
DWORD n;
COORD pos;
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &bufferInfo);
auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(handle, &bufferInfo);
// save old cursor position
pos = bufferInfo.dwCursorPosition;
size_t newX = static_cast<size_t>(pos.X) + s.size();
// size_t oldY = static_cast<size_t>(pos.Y);
size_t newX = static_cast<size_t>(pos.X) + wLen;
if (newX >= static_cast<size_t>(bufferInfo.dwSize.X)) {
for (size_t i = 0; i <= newX / bufferInfo.dwSize.X; ++i) {
// insert as many newlines as we need. this prevents running out of
@ -200,62 +208,179 @@ static void _printLine(std::string const& s) {
}
// save new cursor position
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &bufferInfo);
GetConsoleScreenBufferInfo(handle, &bufferInfo);
auto newPos = bufferInfo.dwCursorPosition;
// print the actual string. note: printing does not advance the cursor
// position
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
WriteConsoleOutputCharacterW(GetStdHandle(STD_OUTPUT_HANDLE), wBuf,
(DWORD)s.size(), pos, &n);
SetConsoleCursorPosition(handle, pos);
SetConsoleTextAttribute(handle, attr);
WriteConsoleOutputCharacterW(handle, wBuf, (DWORD)wLen, pos, &n);
// finally set the cursor position to where the printing should have
// stopped
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), newPos);
SetConsoleCursorPosition(handle, newPos);
} else {
fprintf(stdout, "window error: '%d' \r\n", GetLastError());
fprintf(stdout, "%s\r\n", s.c_str());
}
if (wBuf) {
TRI_Free(TRI_CORE_MEM_ZONE, wBuf);
delete[] wBuf;
}
}
static void _print(std::string const& s) {
auto pos = s.find_first_of("\x1b");
if (pos == std::string::npos) {
int color = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
_print2(s, color);
}
else {
std::vector<std::string> lines = StringUtils::split(s, '\x1b', '\0');
int i = 0;
int color = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
int attr = 0;
for (auto line : lines) {
size_t pos = 0;
if (i++ != 0 && !line.empty()) {
char c = line[0];
if (c == '[') {
int code = 0;
for (++pos; pos < line.size(); ++pos) {
c = line[pos];
if ('0' <= c && c <= '9') {
code = code * 10 + (c - '0');
}
else if (c == 'm' || c == ';') {
switch (code) {
case 0:
attr = 0;
color = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
break;
case 1: // BOLD
case 5: // BLINK
attr = FOREGROUND_INTENSITY;
break;
case 30:
color = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
break;
case 31:
color = FOREGROUND_RED;
break;
case 32:
color = FOREGROUND_GREEN;
break;
case 33:
color = FOREGROUND_RED | FOREGROUND_GREEN;
break;
case 34:
color = FOREGROUND_BLUE;
break;
case 35:
color = FOREGROUND_BLUE | FOREGROUND_RED;
break;
case 36:
color = FOREGROUND_BLUE | FOREGROUND_GREEN;
break;
case 37:
color = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
break;
case 39:
color = 0;
break;
}
code = 0;
}
if (c == 'm') {
++pos;
break;
}
}
}
}
_print2(line.substr(pos), attr | color);
}
}
}
#endif
void ConsoleFeature::printLine(std::string const& s, bool forceNewLine) {
// prints a string to stdout, without a newline
void ConsoleFeature::printContinuous(std::string const& s) {
#ifdef _WIN32
//#warning do we need forceNewLine
// no, we cannot use std::cout as this doesn't support UTF-8 on Windows
if (!cygwinShell) {
if (s.empty()) {
return;
}
if (/*!_cygwinShell*/ true) {
// no, we cannot use std::cout as this doesn't support UTF-8 on Windows
// fprintf(stdout, "%s\r\n", s.c_str());
TRI_vector_string_t subStrings = TRI_SplitString(s.c_str(), '\n');
bool hasNewLines = (s.find("\n") != std::string::npos) | forceNewLine;
if (hasNewLines) {
for (size_t i = 0; i < subStrings._length; i++) {
_printLine(subStrings._buffer[i]);
_newLine();
}
} else {
_printLine(s);
std::vector<std::string> lines = StringUtils::split(s, '\n', '\0');
auto last = lines.back();
lines.pop_back();
for (auto& line : lines) {
_print(line);
_newLine();
}
_print(last);
} else
#endif
{
fprintf(stdout, "%s", s.c_str());
fflush(stdout);
}
}
void ConsoleFeature::printLine(std::string const& s) {
#ifdef _WIN32
// no, we cannot use std::cout as this doesn't support UTF-8 on Windows
if (/*!_cygwinShell*/ true) {
std::vector<std::string> lines = StringUtils::split(s, '\n', '\0');
for (auto& line : lines) {
_print(line);
_newLine();
}
TRI_DestroyVectorString(&subStrings);
} else
#endif
{
fprintf(stdout, "%s\n", s.c_str());
fflush(stdout);
}
}
void ConsoleFeature::printErrorLine(std::string const& s) {
#ifdef _WIN32
// no, we can use std::cerr as this doesn't support UTF-8 on Windows
printLine(s);
#else
fprintf(stderr, "%s\n", s.c_str());
#endif
}
std::string ConsoleFeature::readPassword(std::string const& message) {

View File

@ -50,7 +50,7 @@ class ConsoleFeature final : public application_features::ApplicationFeature {
std::string const& prompt() const { return _prompt; }
private:
#ifdef WIN32
#ifdef _WIN32
int16_t _codePage;
bool _cygwinShell;
#endif
@ -63,17 +63,15 @@ class ConsoleFeature final : public application_features::ApplicationFeature {
std::string _pagerCommand;
std::string _prompt;
public:
static void printContinuous(std::string const&);
static void printLine(std::string const&, bool forceNewLine = false);
static void printErrorLine(std::string const&);
static std::string readPassword(std::string const& message);
public:
void setPromptError(bool value) { _promptError = value; }
void setSupportsColors(bool value) { _supportsColors = value; }
void printWelcomeInfo();
void printByeBye();
std::string readPassword(std::string const& message);
void printContinuous(std::string const&);
void printLine(std::string const&);
void printErrorLine(std::string const&);
void print(std::string const&);
void openLog();
void closeLog();

View File

@ -24,8 +24,6 @@
#ifndef LIB_BASICS_SHELL_COLORS_H
#define LIB_BASICS_SHELL_COLORS_H 1
#ifndef _WIN32
////////////////////////////////////////////////////////////////////////////////
/// @brief color red
////////////////////////////////////////////////////////////////////////////////
@ -140,31 +138,4 @@
#define TRI_SHELL_COLOR_RESET "\x1b[0m"
#else
// .............................................................................
// Quick hack for windows
// .............................................................................
#define TRI_SHELL_COLOR_RED ""
#define TRI_SHELL_COLOR_BOLD_RED ""
#define TRI_SHELL_COLOR_GREEN ""
#define TRI_SHELL_COLOR_BOLD_GREEN ""
#define TRI_SHELL_COLOR_BLUE ""
#define TRI_SHELL_COLOR_BOLD_BLUE ""
#define TRI_SHELL_COLOR_YELLOW ""
#define TRI_SHELL_COLOR_BOLD_YELLOW ""
#define TRI_SHELL_COLOR_WHITE ""
#define TRI_SHELL_COLOR_BOLD_WHITE ""
#define TRI_SHELL_COLOR_CYAN ""
#define TRI_SHELL_COLOR_BOLD_CYAN ""
#define TRI_SHELL_COLOR_MAGENTA ""
#define TRI_SHELL_COLOR_BOLD_MAGENTA ""
#define TRI_SHELL_COLOR_BLACK ""
#define TRI_SHELL_COLOR_BOLD_BLACK ""
#define TRI_SHELL_COLOR_BLINK ""
#define TRI_SHELL_COLOR_BRIGHT ""
#define TRI_SHELL_COLOR_RESET ""
#endif
#endif