summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-15 00:42:57 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-15 00:42:57 +0000
commit12774990ee4f8f9c6bb2d9ccd032f9000a97b04a (patch)
tree9b2018b3cf08e8374a7f59fbe2e3be5d9c8b05de
parent18de157f6c4c5eee14ad84e037def47a7f52a3a8 (diff)
downloadchromium_src-12774990ee4f8f9c6bb2d9ccd032f9000a97b04a.zip
chromium_src-12774990ee4f8f9c6bb2d9ccd032f9000a97b04a.tar.gz
chromium_src-12774990ee4f8f9c6bb2d9ccd032f9000a97b04a.tar.bz2
Posix: implement diagnostics mode console output.
BUG=42894,42345 TEST=chrome --diagnostics Review URL: http://codereview.chromium.org/2115001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47348 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/diagnostics/diagnostics_main.cc181
1 files changed, 144 insertions, 37 deletions
diff --git a/chrome/browser/diagnostics/diagnostics_main.cc b/chrome/browser/diagnostics/diagnostics_main.cc
index f6a03c0..d72e8a5 100644
--- a/chrome/browser/diagnostics/diagnostics_main.cc
+++ b/chrome/browser/diagnostics/diagnostics_main.cc
@@ -4,51 +4,87 @@
#include "chrome/browser/diagnostics/diagnostics_main.h"
+#if defined(OS_POSIX)
+#include <stdio.h>
+#include <unistd.h>
+#endif
+
#include "app/app_paths.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
#include "base/time.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/diagnostics/diagnostics_model.h"
#include "chrome/common/chrome_paths.h"
#if defined(OS_WIN)
#include "base/win_util.h"
+#endif
namespace {
-// This is a minimalistic class to wrap the windows console operating
-// in high-level IO mode. This will be eventually replaced by a view
-// that can be subclassed for each platform and that the approved look
-// and feel.
+// This is a minimalistic interface to wrap the platform console. This will be
+// eventually replaced by a view that can be subclassed for each platform and
+// that the approved look and feel.
class SimpleConsole {
public:
+ enum Color {
+ DEFAULT,
+ RED,
+ GREEN,
+ };
+
+ virtual ~SimpleConsole() { }
+
+ // Init must be called before using any other method. If it returns
+ // false there would be no console output.
+ virtual bool Init() = 0;
+
+ // Writes a string to the console with the current color.
+ virtual bool Write(const std::wstring& text) = 0;
+
+ // Reads a string from the console. Internally it may be limited to 256
+ // characters.
+ virtual bool Read(std::wstring* txt) = 0;
+
+ // Sets the foreground and background color.
+ virtual bool SetColor(Color color) = 0;
+
+ // Create an appropriate SimpleConsole instance. May return NULL if there is
+ // no implementation for the current platform.
+ static SimpleConsole* Create();
+};
+
+#if defined(OS_WIN)
+// Wrapper for the windows console operating in high-level IO mode.
+class WinConsole : public SimpleConsole {
+ public:
// The ctor allocates a console always. This avoids having to ask
// the user to start chrome from a command prompt.
- SimpleConsole()
+ WinConsole()
: std_out_(INVALID_HANDLE_VALUE),
std_in_(INVALID_HANDLE_VALUE) {
}
- ~SimpleConsole() {
+ virtual ~WinConsole() {
::FreeConsole();
}
- // Init must be called before using any other method. If it returns
- // false there would be no console output.
- bool Init() {
+
+ virtual bool Init() {
::AllocConsole();
return SetIOHandles();
}
- // Writes a string to the console with the current color.
- bool Write(const std::wstring& txt) {
+ virtual bool Write(const std::wstring& txt) {
DWORD sz = txt.size();
return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
}
// Reads a string from the console. Internally it is limited to 256
// characters.
- bool Read(std::wstring* txt) {
+ virtual bool Read(std::wstring* txt) {
wchar_t buf[256];
DWORD read = sizeof(buf) - sizeof(buf[0]);
if (!::ReadConsoleW(std_in_, buf, read, &read, NULL))
@@ -58,9 +94,22 @@ class SimpleConsole {
return true;
}
- // Sets the foreground and backgroudn color. See |kRedFG| or |kGreenFG|
- // below for examples how to combine colors.
- bool SetColor(uint16 color_combo) {
+ // Sets the foreground and background color.
+ virtual bool SetColor(Color color) {
+ uint16 color_combo =
+ FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
+ switch (color) {
+ case RED:
+ color_combo = FOREGROUND_RED|FOREGROUND_INTENSITY;
+ break;
+ case GREEN:
+ color_combo = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
+ break;
+ case DEFAULT:
+ break;
+ default:
+ NOTREACHED();
+ }
return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
}
@@ -77,9 +126,74 @@ class SimpleConsole {
HANDLE std_out_;
HANDLE std_in_;
- DISALLOW_COPY_AND_ASSIGN(SimpleConsole);
+ DISALLOW_COPY_AND_ASSIGN(WinConsole);
+};
+
+SimpleConsole* SimpleConsole::Create() {
+ return new WinConsole();
+}
+
+#elif defined(OS_POSIX)
+
+class PosixConsole : public SimpleConsole {
+ public:
+ PosixConsole() { }
+
+ virtual bool Init() {
+ // Technically, we should also check the terminal capabilities before using
+ // color, but in practice this is unlikely to be an issue.
+ use_color_ = isatty(STDOUT_FILENO);
+ return true;
+ }
+
+ virtual bool Write(const std::wstring& text) {
+ printf("%s", base::SysWideToNativeMB(text).c_str());
+ return true;
+ }
+
+ virtual bool Read(std::wstring* txt) {
+ // TODO(mattm): implement this.
+ return false;
+ }
+
+ virtual bool SetColor(Color color) {
+ if (!use_color_)
+ return false;
+
+ const char* code = "\033[m";
+ switch (color) {
+ case RED:
+ code = "\033[1;31m";
+ break;
+ case GREEN:
+ code = "\033[1;32m";
+ break;
+ case DEFAULT:
+ break;
+ default:
+ NOTREACHED();
+ }
+ printf("%s", code);
+ return true;
+ }
+
+ private:
+ bool use_color_;
+
+ DISALLOW_COPY_AND_ASSIGN(PosixConsole);
};
+SimpleConsole* SimpleConsole::Create() {
+ return new PosixConsole();
+}
+
+#else // !defined(OS_WIN) && !defined(OS_POSIX)
+
+SimpleConsole* SimpleConsole::Create() {
+ return NULL;
+}
+#endif
+
// This class wraps a SimpleConsole for the specific use case of
// writing the results of the diagnostic tests.
// TODO(cpu) figure out the localization strategy.
@@ -92,7 +206,7 @@ class TestWriter {
// Write an informational line of text in white over black.
bool WriteInfoText(const std::wstring& txt) {
- console_->SetColor(kWhiteFG);
+ console_->SetColor(SimpleConsole::DEFAULT);
return console_->Write(txt);
}
@@ -102,10 +216,10 @@ class TestWriter {
bool WriteResult(bool success, const std::wstring& name,
const std::wstring& extra) {
if (success) {
- console_->SetColor(kGreenFG);
+ console_->SetColor(SimpleConsole::GREEN);
console_->Write(L"[PASS] ");
} else {
- console_->SetColor(kRedFG);
+ console_->SetColor(SimpleConsole::RED);
console_->Write(L"[FAIL] ");
}
WriteInfoText(name + L"\n");
@@ -115,10 +229,6 @@ class TestWriter {
}
private:
- // constants for the colors we use.
- static const uint16 kRedFG = FOREGROUND_RED|FOREGROUND_INTENSITY;
- static const uint16 kGreenFG = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
- static const uint16 kWhiteFG = kRedFG | kGreenFG | FOREGROUND_BLUE;
SimpleConsole* console_;
@@ -181,8 +291,8 @@ class TestController : public DiagnosticsModel::Observer {
private:
void ShowResult(DiagnosticsModel::TestInfo& test_info) {
bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
- writer_->WriteResult(success, test_info.GetTitle(),
- test_info.GetAdditionalInfo());
+ writer_->WriteResult(success, UTF16ToWide(test_info.GetTitle()),
+ UTF16ToWide(test_info.GetAdditionalInfo()));
}
DiagnosticsModel* model_;
@@ -207,8 +317,8 @@ class TestController : public DiagnosticsModel::Observer {
int DiagnosticsMain(const CommandLine& command_line) {
// If we can't initialize the console exit right away.
- SimpleConsole console;
- if (!console.Init())
+ SimpleConsole* console = SimpleConsole::Create();
+ if (!console || !console->Init())
return 1;
// We need to have the path providers registered. They both
@@ -216,7 +326,7 @@ int DiagnosticsMain(const CommandLine& command_line) {
app::RegisterPathProvider();
chrome::RegisterPathProvider();
- TestWriter writer(&console);
+ TestWriter writer(console);
DiagnosticsModel* model = MakeDiagnosticsModel(command_line);
TestController controller(&writer);
@@ -224,17 +334,14 @@ int DiagnosticsMain(const CommandLine& command_line) {
controller.Run(model);
delete model;
+ // The "press enter to continue" prompt isn't very unixy, so only do that on
+ // Windows.
+#if defined(OS_WIN)
// Block here so the user can see the results.
writer.WriteInfoText(L"Press [enter] to continue\n");
std::wstring txt;
- console.Read(&txt);
- return 0;
-}
-
-#else // defined(OS_WIN)
-
-int DiagnosticsMain(const CommandLine& command_line) {
+ console->Read(&txt);
+#endif
+ delete console;
return 0;
}
-
-#endif