Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / gn / standard_out.cc
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.
4
5 #include "tools/gn/standard_out.h"
6
7 #include <vector>
8
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
14 #if defined(OS_WIN)
15 #include <windows.h>
16 #else
17 #include <stdio.h>
18 #include <unistd.h>
19 #endif
20
21 namespace {
22
23 bool initialized = false;
24
25 static const char kSwitchColor[] = "color";
26 static const char kSwitchNoColor[] = "nocolor";
27
28 #if defined(OS_WIN)
29 HANDLE hstdout;
30 WORD default_attributes;
31 #endif
32 bool is_console = false;
33
34 void EnsureInitialized() {
35   if (initialized)
36     return;
37   initialized = true;
38
39   const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
40   if (cmdline->HasSwitch(kSwitchNoColor)) {
41     // Force color off.
42     is_console = false;
43     return;
44   }
45
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
59 }
60
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);
64 }
65
66 }  // namespace
67
68 #if defined(OS_WIN)
69
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;
95     }
96   }
97
98   DWORD written = 0;
99   ::WriteFile(hstdout, output.c_str(), static_cast<DWORD>(output.size()),
100               &written, NULL);
101
102   if (is_console)
103     ::SetConsoleTextAttribute(hstdout, default_attributes);
104 }
105
106 #else
107
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;
129     }
130   }
131
132   WriteToStdOut(output.data());
133
134   if (is_console && dec != DECORATION_NONE)
135     WriteToStdOut("\e[0m");
136 }
137
138 #endif
139
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;
146   }
147
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);
161   }
162
163   OutputString(line.substr(first_normal) + "\n");
164 }
165
166 void PrintLongHelp(const std::string& text) {
167   std::vector<std::string> lines;
168   base::SplitStringDontTrim(text, '\n', &lines);
169
170   for (size_t i = 0; i < lines.size(); i++) {
171     const std::string& line = lines[i];
172
173     // Check for a heading line.
174     if (!line.empty() && line[0] != ' ') {
175       // Highlight up to the colon (if any).
176       size_t chars_to_highlight = line.find(':');
177       if (chars_to_highlight == std::string::npos)
178         chars_to_highlight = line.size();
179       OutputString(line.substr(0, chars_to_highlight), DECORATION_YELLOW);
180       OutputString(line.substr(chars_to_highlight) + "\n");
181       continue;
182     }
183
184     // Check for a comment.
185     TextDecoration dec = DECORATION_NONE;
186     for (size_t char_i = 0; char_i < line.size(); char_i++) {
187       if (line[char_i] == '#') {
188         // Got a comment, draw dimmed.
189         dec = DECORATION_DIM;
190         break;
191       } else if (line[char_i] != ' ') {
192         break;
193       }
194     }
195
196     OutputString(line + "\n", dec);
197   }
198 }
199