Add window.gc back to Smoothness.WillNavigateToPageHook
[chromium-blink-merge.git] / tools / gn / standard_out.cc
blob6d3960e6f4863b418cc333c92fbeb527c9a5511d
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 bool is_markdown = false;
34 void EnsureInitialized() {
35 if (initialized)
36 return;
37 initialized = true;
39 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
40 if (cmdline->HasSwitch(switches::kMarkdown)) {
41 // Output help in Markdown's syntax, not color-highlighted.
42 is_markdown = true;
45 if (cmdline->HasSwitch(switches::kNoColor)) {
46 // Force color off.
47 is_console = false;
48 return;
51 #if defined(OS_WIN)
52 // On Windows, we can't force the color on. If the output handle isn't a
53 // console, there's nothing we can do about it.
54 hstdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
55 CONSOLE_SCREEN_BUFFER_INFO info;
56 is_console = !!::GetConsoleScreenBufferInfo(hstdout, &info);
57 default_attributes = info.wAttributes;
58 #else
59 if (cmdline->HasSwitch(switches::kColor))
60 is_console = true;
61 else
62 is_console = isatty(fileno(stdout));
63 #endif
66 #if !defined(OS_WIN)
67 void WriteToStdOut(const std::string& output) {
68 size_t written_bytes = fwrite(output.data(), 1, output.size(), stdout);
69 DCHECK_EQ(output.size(), written_bytes);
71 #endif // !defined(OS_WIN)
73 void OutputMarkdownDec(TextDecoration dec) {
74 // The markdown rendering turns "dim" text to italics and any
75 // other colored text to bold.
77 #if defined(OS_WIN)
78 DWORD written = 0;
79 if (dec == DECORATION_DIM)
80 ::WriteFile(hstdout, "*", 1, &written, nullptr);
81 else if (dec != DECORATION_NONE)
82 ::WriteFile(hstdout, "**", 2, &written, nullptr);
83 #else
84 if (dec == DECORATION_DIM)
85 WriteToStdOut("*");
86 else if (dec != DECORATION_NONE)
87 WriteToStdOut("**");
88 #endif
91 } // namespace
93 #if defined(OS_WIN)
95 void OutputString(const std::string& output, TextDecoration dec) {
96 EnsureInitialized();
97 DWORD written = 0;
99 if (is_markdown) {
100 OutputMarkdownDec(dec);
101 } else if (is_console) {
102 switch (dec) {
103 case DECORATION_NONE:
104 break;
105 case DECORATION_DIM:
106 ::SetConsoleTextAttribute(hstdout, FOREGROUND_INTENSITY);
107 break;
108 case DECORATION_RED:
109 ::SetConsoleTextAttribute(hstdout,
110 FOREGROUND_RED | FOREGROUND_INTENSITY);
111 break;
112 case DECORATION_GREEN:
113 // Keep green non-bold.
114 ::SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
115 break;
116 case DECORATION_BLUE:
117 ::SetConsoleTextAttribute(hstdout,
118 FOREGROUND_BLUE | FOREGROUND_INTENSITY);
119 break;
120 case DECORATION_YELLOW:
121 ::SetConsoleTextAttribute(hstdout,
122 FOREGROUND_RED | FOREGROUND_GREEN);
123 break;
127 ::WriteFile(hstdout, output.c_str(), static_cast<DWORD>(output.size()),
128 &written, nullptr);
130 if (is_markdown) {
131 OutputMarkdownDec(dec);
132 } else if (is_console) {
133 ::SetConsoleTextAttribute(hstdout, default_attributes);
137 #else
139 void OutputString(const std::string& output, TextDecoration dec) {
140 EnsureInitialized();
141 if (is_markdown) {
142 OutputMarkdownDec(dec);
143 } else if (is_console) {
144 switch (dec) {
145 case DECORATION_NONE:
146 break;
147 case DECORATION_DIM:
148 WriteToStdOut("\e[2m");
149 break;
150 case DECORATION_RED:
151 WriteToStdOut("\e[31m\e[1m");
152 break;
153 case DECORATION_GREEN:
154 WriteToStdOut("\e[32m");
155 break;
156 case DECORATION_BLUE:
157 WriteToStdOut("\e[34m\e[1m");
158 break;
159 case DECORATION_YELLOW:
160 WriteToStdOut("\e[33m\e[1m");
161 break;
165 WriteToStdOut(output.data());
167 if (is_markdown) {
168 OutputMarkdownDec(dec);
169 } else if (is_console && dec != DECORATION_NONE) {
170 WriteToStdOut("\e[0m");
174 #endif
176 void PrintShortHelp(const std::string& line) {
177 EnsureInitialized();
179 size_t colon_offset = line.find(':');
180 size_t first_normal = 0;
181 if (colon_offset != std::string::npos) {
182 OutputString(" " + line.substr(0, colon_offset), DECORATION_YELLOW);
183 first_normal = colon_offset;
186 // See if the colon is followed by a " [" and if so, dim the contents of [ ].
187 if (first_normal > 0 &&
188 line.size() > first_normal + 2 &&
189 line[first_normal + 1] == ' ' && line[first_normal + 2] == '[') {
190 size_t begin_bracket = first_normal + 2;
191 OutputString(": ");
192 first_normal = line.find(']', begin_bracket);
193 if (first_normal == std::string::npos)
194 first_normal = line.size();
195 else
196 first_normal++;
197 OutputString(line.substr(begin_bracket, first_normal - begin_bracket),
198 DECORATION_DIM);
201 OutputString(line.substr(first_normal) + "\n");
204 void PrintLongHelp(const std::string& text) {
205 EnsureInitialized();
207 bool first_header = true;
208 bool in_body = false;
209 for (const std::string& line : base::SplitString(
210 text, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) {
211 // Check for a heading line.
212 if (!line.empty() && line[0] != ' ') {
213 if (is_markdown) {
214 // GN's block-level formatting is converted to markdown as follows:
215 // * The first heading is treated as an H2.
216 // * Subsequent heading are treated as H3s.
217 // * Any other text is wrapped in a code block and displayed as-is.
219 // Span-level formatting (the decorations) is converted inside
220 // OutputString().
221 if (in_body) {
222 OutputString("```\n\n", DECORATION_NONE);
223 in_body = false;
226 if (first_header) {
227 OutputString("## ", DECORATION_NONE);
228 first_header = false;
229 } else {
230 OutputString("### ", DECORATION_NONE);
234 // Highlight up to the colon (if any).
235 size_t chars_to_highlight = line.find(':');
236 if (chars_to_highlight == std::string::npos)
237 chars_to_highlight = line.size();
239 OutputString(line.substr(0, chars_to_highlight), DECORATION_YELLOW);
240 OutputString(line.substr(chars_to_highlight) + "\n");
241 continue;
242 } else if (is_markdown && !line.empty() && !in_body) {
243 OutputString("```\n", DECORATION_NONE);
244 in_body = true;
247 // Check for a comment.
248 TextDecoration dec = DECORATION_NONE;
249 for (const auto& elem : line) {
250 if (elem == '#' && !is_markdown) {
251 // Got a comment, draw dimmed.
252 dec = DECORATION_DIM;
253 break;
254 } else if (elem != ' ') {
255 break;
259 OutputString(line + "\n", dec);
262 if (is_markdown && in_body)
263 OutputString("\n```\n");