Roll src/third_party/skia ff271c2:b679ca8
[chromium-blink-merge.git] / tools / gn / standard_out.cc
blob69d443be368a22f37b8f1ca4eee2c6fe642dbaeb
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"
13 #include "tools/gn/switches.h"
15 #if defined(OS_WIN)
16 #include <windows.h>
17 #else
18 #include <stdio.h>
19 #include <unistd.h>
20 #endif
22 namespace {
24 bool initialized = false;
26 #if defined(OS_WIN)
27 HANDLE hstdout;
28 WORD default_attributes;
29 #endif
30 bool is_console = false;
32 void EnsureInitialized() {
33 if (initialized)
34 return;
35 initialized = true;
37 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
38 if (cmdline->HasSwitch(switches::kNoColor)) {
39 // Force color off.
40 is_console = false;
41 return;
44 #if defined(OS_WIN)
45 // On Windows, we can't force the color on. If the output handle isn't a
46 // console, there's nothing we can do about it.
47 hstdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
48 CONSOLE_SCREEN_BUFFER_INFO info;
49 is_console = !!::GetConsoleScreenBufferInfo(hstdout, &info);
50 default_attributes = info.wAttributes;
51 #else
52 if (cmdline->HasSwitch(switches::kColor))
53 is_console = true;
54 else
55 is_console = isatty(fileno(stdout));
56 #endif
59 void WriteToStdOut(const std::string& output) {
60 size_t written_bytes = fwrite(output.data(), 1, output.size(), stdout);
61 DCHECK_EQ(output.size(), written_bytes);
64 } // namespace
66 #if defined(OS_WIN)
68 void OutputString(const std::string& output, TextDecoration dec) {
69 EnsureInitialized();
70 if (is_console) {
71 switch (dec) {
72 case DECORATION_NONE:
73 break;
74 case DECORATION_DIM:
75 ::SetConsoleTextAttribute(hstdout, FOREGROUND_INTENSITY);
76 break;
77 case DECORATION_RED:
78 ::SetConsoleTextAttribute(hstdout,
79 FOREGROUND_RED | FOREGROUND_INTENSITY);
80 break;
81 case DECORATION_GREEN:
82 // Keep green non-bold.
83 ::SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
84 break;
85 case DECORATION_BLUE:
86 ::SetConsoleTextAttribute(hstdout,
87 FOREGROUND_BLUE | FOREGROUND_INTENSITY);
88 break;
89 case DECORATION_YELLOW:
90 ::SetConsoleTextAttribute(hstdout,
91 FOREGROUND_RED | FOREGROUND_GREEN);
92 break;
96 DWORD written = 0;
97 ::WriteFile(hstdout, output.c_str(), static_cast<DWORD>(output.size()),
98 &written, nullptr);
100 if (is_console)
101 ::SetConsoleTextAttribute(hstdout, default_attributes);
104 #else
106 void OutputString(const std::string& output, TextDecoration dec) {
107 EnsureInitialized();
108 if (is_console) {
109 switch (dec) {
110 case DECORATION_NONE:
111 break;
112 case DECORATION_DIM:
113 WriteToStdOut("\e[2m");
114 break;
115 case DECORATION_RED:
116 WriteToStdOut("\e[31m\e[1m");
117 break;
118 case DECORATION_GREEN:
119 WriteToStdOut("\e[32m");
120 break;
121 case DECORATION_BLUE:
122 WriteToStdOut("\e[34m\e[1m");
123 break;
124 case DECORATION_YELLOW:
125 WriteToStdOut("\e[33m\e[1m");
126 break;
130 WriteToStdOut(output.data());
132 if (is_console && dec != DECORATION_NONE)
133 WriteToStdOut("\e[0m");
136 #endif
138 void PrintShortHelp(const std::string& line) {
139 size_t colon_offset = line.find(':');
140 size_t first_normal = 0;
141 if (colon_offset != std::string::npos) {
142 OutputString(" " + line.substr(0, colon_offset), DECORATION_YELLOW);
143 first_normal = colon_offset;
146 // See if the colon is followed by a " [" and if so, dim the contents of [ ].
147 if (first_normal > 0 &&
148 line.size() > first_normal + 2 &&
149 line[first_normal + 1] == ' ' && line[first_normal + 2] == '[') {
150 size_t begin_bracket = first_normal + 2;
151 OutputString(": ");
152 first_normal = line.find(']', begin_bracket);
153 if (first_normal == std::string::npos)
154 first_normal = line.size();
155 else
156 first_normal++;
157 OutputString(line.substr(begin_bracket, first_normal - begin_bracket),
158 DECORATION_DIM);
161 OutputString(line.substr(first_normal) + "\n");
164 void PrintLongHelp(const std::string& text) {
165 std::vector<std::string> lines;
166 base::SplitStringDontTrim(text, '\n', &lines);
168 for (const auto& line : lines) {
169 // Check for a heading line.
170 if (!line.empty() && line[0] != ' ') {
171 // Highlight up to the colon (if any).
172 size_t chars_to_highlight = line.find(':');
173 if (chars_to_highlight == std::string::npos)
174 chars_to_highlight = line.size();
175 OutputString(line.substr(0, chars_to_highlight), DECORATION_YELLOW);
176 OutputString(line.substr(chars_to_highlight) + "\n");
177 continue;
180 // Check for a comment.
181 TextDecoration dec = DECORATION_NONE;
182 for (const auto& elem : line) {
183 if (elem == '#') {
184 // Got a comment, draw dimmed.
185 dec = DECORATION_DIM;
186 break;
187 } else if (elem != ' ') {
188 break;
192 OutputString(line + "\n", dec);