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"
9 #include "base/logging.h"
10 #include "base/strings/string_split.h"
11 #include "build/build_config.h"
22 bool initialized
= false;
26 WORD default_attributes
;
28 bool is_console
= false;
30 void EnsureInitialized() {
36 hstdout
= ::GetStdHandle(STD_OUTPUT_HANDLE
);
37 CONSOLE_SCREEN_BUFFER_INFO info
;
38 is_console
= !!::GetConsoleScreenBufferInfo(hstdout
, &info
);
39 default_attributes
= info
.wAttributes
;
41 is_console
= isatty(fileno(stdout
));
45 void WriteToStdOut(const std::string
& output
) {
46 size_t written_bytes
= fwrite(output
.data(), 1, output
.size(), stdout
);
47 DCHECK_EQ(output
.size(), written_bytes
);
54 void OutputString(const std::string
& output
, TextDecoration dec
) {
61 ::SetConsoleTextAttribute(hstdout
, FOREGROUND_INTENSITY
);
64 ::SetConsoleTextAttribute(hstdout
,
65 FOREGROUND_RED
| FOREGROUND_INTENSITY
);
67 case DECORATION_GREEN
:
68 // Keep green non-bold.
69 ::SetConsoleTextAttribute(hstdout
, FOREGROUND_GREEN
);
72 ::SetConsoleTextAttribute(hstdout
,
73 FOREGROUND_BLUE
| FOREGROUND_INTENSITY
);
75 case DECORATION_YELLOW
:
76 ::SetConsoleTextAttribute(hstdout
,
77 FOREGROUND_RED
| FOREGROUND_GREEN
);
83 ::WriteFile(hstdout
, output
.c_str(), static_cast<DWORD
>(output
.size()),
87 ::SetConsoleTextAttribute(hstdout
, default_attributes
);
92 void OutputString(const std::string
& output
, TextDecoration dec
) {
99 WriteToStdOut("\e[2m");
102 WriteToStdOut("\e[31m\e[1m");
104 case DECORATION_GREEN
:
105 WriteToStdOut("\e[32m");
107 case DECORATION_BLUE
:
108 WriteToStdOut("\e[34m\e[1m");
110 case DECORATION_YELLOW
:
111 WriteToStdOut("\e[33m\e[1m");
116 WriteToStdOut(output
.data());
118 if (dec
!= DECORATION_NONE
)
119 WriteToStdOut("\e[0m");
124 void PrintShortHelp(const std::string
& line
) {
125 size_t colon_offset
= line
.find(':');
126 size_t first_normal
= 0;
127 if (colon_offset
!= std::string::npos
) {
128 OutputString(" " + line
.substr(0, colon_offset
), DECORATION_YELLOW
);
129 first_normal
= colon_offset
;
132 // See if the colon is followed by a " [" and if so, dim the contents of [ ].
133 if (first_normal
> 0 &&
134 line
.size() > first_normal
+ 2 &&
135 line
[first_normal
+ 1] == ' ' && line
[first_normal
+ 2] == '[') {
136 size_t begin_bracket
= first_normal
+ 2;
138 first_normal
= line
.find(']', begin_bracket
);
139 if (first_normal
== std::string::npos
)
140 first_normal
= line
.size();
143 OutputString(line
.substr(begin_bracket
, first_normal
- begin_bracket
),
147 OutputString(line
.substr(first_normal
) + "\n");
150 void PrintLongHelp(const std::string
& text
) {
151 std::vector
<std::string
> lines
;
152 base::SplitStringDontTrim(text
, '\n', &lines
);
154 for (size_t i
= 0; i
< lines
.size(); i
++) {
155 const std::string
& line
= lines
[i
];
157 // Check for a heading line.
158 if (!line
.empty() && line
[0] != ' ') {
159 // Highlight up to the colon (if any).
160 size_t chars_to_highlight
= line
.find(':');
161 if (chars_to_highlight
== std::string::npos
)
162 chars_to_highlight
= line
.size();
163 OutputString(line
.substr(0, chars_to_highlight
), DECORATION_YELLOW
);
164 OutputString(line
.substr(chars_to_highlight
) + "\n");
168 // Check for a comment.
169 TextDecoration dec
= DECORATION_NONE
;
170 for (size_t char_i
= 0; char_i
< line
.size(); char_i
++) {
171 if (line
[char_i
] == '#') {
172 // Got a comment, draw dimmed.
173 dec
= DECORATION_DIM
;
175 } else if (line
[char_i
] != ' ') {
180 OutputString(line
+ "\n", dec
);