Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / tools / gn / standard_out.cc
blob98e0680893705851ef06c209df1a926f8f9c890e
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "tools/gn/standard_out.h"
7 #include <vector>
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/strings/string_split.h"
12 #include "build/build_config.h"
14 #if defined(OS_WIN)
15 #include <windows.h>
16 #else
17 #include <stdio.h>
18 #include <unistd.h>
19 #endif
21 namespace {
23 bool initialized = false;
25 static const char kSwitchColor[] = "color";
26 static const char kSwitchNoColor[] = "nocolor";
28 #if defined(OS_WIN)
29 HANDLE hstdout;
30 WORD default_attributes;
31 #endif
32 bool is_console = false;
34 void EnsureInitialized() {
35 if (initialized)
36 return;
37 initialized = true;
39 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
40 if (cmdline->HasSwitch(kSwitchNoColor)) {
41 // Force color off.
42 is_console = false;
43 return;
46 #if defined(OS_WIN)
47 // On Windows, we can't force the color on. If the output handle isn't a
48 // console, there's nothing we can do about it.
49 hstdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
50 CONSOLE_SCREEN_BUFFER_INFO info;
51 is_console = !!::GetConsoleScreenBufferInfo(hstdout, &info);
52 default_attributes = info.wAttributes;
53 #else
54 if (cmdline->HasSwitch(kSwitchColor))
55 is_console = true;
56 else
57 is_console = isatty(fileno(stdout));
58 #endif
61 void WriteToStdOut(const std::string& output) {
62 size_t written_bytes = fwrite(output.data(), 1, output.size(), stdout);
63 DCHECK_EQ(output.size(), written_bytes);
66 } // namespace
68 #if defined(OS_WIN)
70 void OutputString(const std::string& output, TextDecoration dec) {
71 EnsureInitialized();
72 if (is_console) {
73 switch (dec) {
74 case DECORATION_NONE:
75 break;
76 case DECORATION_DIM:
77 ::SetConsoleTextAttribute(hstdout, FOREGROUND_INTENSITY);
78 break;
79 case DECORATION_RED:
80 ::SetConsoleTextAttribute(hstdout,
81 FOREGROUND_RED | FOREGROUND_INTENSITY);
82 break;
83 case DECORATION_GREEN:
84 // Keep green non-bold.
85 ::SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
86 break;
87 case DECORATION_BLUE:
88 ::SetConsoleTextAttribute(hstdout,
89 FOREGROUND_BLUE | FOREGROUND_INTENSITY);
90 break;
91 case DECORATION_YELLOW:
92 ::SetConsoleTextAttribute(hstdout,
93 FOREGROUND_RED | FOREGROUND_GREEN);
94 break;
98 DWORD written = 0;
99 ::WriteFile(hstdout, output.c_str(), static_cast<DWORD>(output.size()),
100 &written, NULL);
102 if (is_console)
103 ::SetConsoleTextAttribute(hstdout, default_attributes);
106 #else
108 void OutputString(const std::string& output, TextDecoration dec) {
109 EnsureInitialized();
110 if (is_console) {
111 switch (dec) {
112 case DECORATION_NONE:
113 break;
114 case DECORATION_DIM:
115 WriteToStdOut("\e[2m");
116 break;
117 case DECORATION_RED:
118 WriteToStdOut("\e[31m\e[1m");
119 break;
120 case DECORATION_GREEN:
121 WriteToStdOut("\e[32m");
122 break;
123 case DECORATION_BLUE:
124 WriteToStdOut("\e[34m\e[1m");
125 break;
126 case DECORATION_YELLOW:
127 WriteToStdOut("\e[33m\e[1m");
128 break;
132 WriteToStdOut(output.data());
134 if (is_console && dec != DECORATION_NONE)
135 WriteToStdOut("\e[0m");
138 #endif
140 void PrintShortHelp(const std::string& line) {
141 size_t colon_offset = line.find(':');
142 size_t first_normal = 0;
143 if (colon_offset != std::string::npos) {
144 OutputString(" " + line.substr(0, colon_offset), DECORATION_YELLOW);
145 first_normal = colon_offset;
148 // See if the colon is followed by a " [" and if so, dim the contents of [ ].
149 if (first_normal > 0 &&
150 line.size() > first_normal + 2 &&
151 line[first_normal + 1] == ' ' && line[first_normal + 2] == '[') {
152 size_t begin_bracket = first_normal + 2;
153 OutputString(": ");
154 first_normal = line.find(']', begin_bracket);
155 if (first_normal == std::string::npos)
156 first_normal = line.size();
157 else
158 first_normal++;
159 OutputString(line.substr(begin_bracket, first_normal - begin_bracket),
160 DECORATION_DIM);
163 OutputString(line.substr(first_normal) + "\n");
166 void PrintLongHelp(const std::string& text) {
167 std::vector<std::string> lines;
168 base::SplitStringDontTrim(text, '\n', &lines);
170 for (const auto& line : lines) {
171 // Check for a heading line.
172 if (!line.empty() && line[0] != ' ') {
173 // Highlight up to the colon (if any).
174 size_t chars_to_highlight = line.find(':');
175 if (chars_to_highlight == std::string::npos)
176 chars_to_highlight = line.size();
177 OutputString(line.substr(0, chars_to_highlight), DECORATION_YELLOW);
178 OutputString(line.substr(chars_to_highlight) + "\n");
179 continue;
182 // Check for a comment.
183 TextDecoration dec = DECORATION_NONE;
184 for (size_t char_i = 0; char_i < line.size(); char_i++) {
185 if (line[char_i] == '#') {
186 // Got a comment, draw dimmed.
187 dec = DECORATION_DIM;
188 break;
189 } else if (line[char_i] != ' ') {
190 break;
194 OutputString(line + "\n", dec);