- add sources.
[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/logging.h"
10 #include "base/strings/string_split.h"
11 #include "build/build_config.h"
12
13 #if defined(OS_WIN)
14 #include <windows.h>
15 #else
16 #include <stdio.h>
17 #include <unistd.h>
18 #endif
19
20 namespace {
21
22 bool initialized = false;
23
24 #if defined(OS_WIN)
25 HANDLE hstdout;
26 WORD default_attributes;
27 #endif
28 bool is_console = false;
29
30 void EnsureInitialized() {
31   if (initialized)
32     return;
33   initialized = true;
34
35 #if defined(OS_WIN)
36   hstdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
37   CONSOLE_SCREEN_BUFFER_INFO info;
38   is_console = !!::GetConsoleScreenBufferInfo(hstdout, &info);
39   default_attributes = info.wAttributes;
40 #else
41   is_console = isatty(fileno(stdout));
42 #endif
43 }
44
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);
48 }
49
50 }  // namespace
51
52 #if defined(OS_WIN)
53
54 void OutputString(const std::string& output, TextDecoration dec) {
55   EnsureInitialized();
56   if (is_console) {
57     switch (dec) {
58       case DECORATION_NONE:
59         break;
60       case DECORATION_DIM:
61         ::SetConsoleTextAttribute(hstdout, FOREGROUND_INTENSITY);
62         break;
63       case DECORATION_RED:
64         ::SetConsoleTextAttribute(hstdout,
65                                   FOREGROUND_RED | FOREGROUND_INTENSITY);
66         break;
67       case DECORATION_GREEN:
68         // Keep green non-bold.
69         ::SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
70         break;
71       case DECORATION_BLUE:
72         ::SetConsoleTextAttribute(hstdout,
73                                   FOREGROUND_BLUE | FOREGROUND_INTENSITY);
74         break;
75       case DECORATION_YELLOW:
76         ::SetConsoleTextAttribute(hstdout,
77                                   FOREGROUND_RED | FOREGROUND_GREEN);
78         break;
79     }
80   }
81
82   DWORD written = 0;
83   ::WriteFile(hstdout, output.c_str(), static_cast<DWORD>(output.size()),
84               &written, NULL);
85
86   if (is_console)
87     ::SetConsoleTextAttribute(hstdout, default_attributes);
88 }
89
90 #else
91
92 void OutputString(const std::string& output, TextDecoration dec) {
93   EnsureInitialized();
94   if (is_console) {
95     switch (dec) {
96       case DECORATION_NONE:
97         break;
98       case DECORATION_DIM:
99         WriteToStdOut("\e[2m");
100         break;
101       case DECORATION_RED:
102         WriteToStdOut("\e[31m\e[1m");
103         break;
104       case DECORATION_GREEN:
105         WriteToStdOut("\e[32m");
106         break;
107       case DECORATION_BLUE:
108         WriteToStdOut("\e[34m\e[1m");
109         break;
110       case DECORATION_YELLOW:
111         WriteToStdOut("\e[33m\e[1m");
112         break;
113     }
114   }
115
116   WriteToStdOut(output.data());
117
118   if (dec != DECORATION_NONE)
119     WriteToStdOut("\e[0m");
120 }
121
122 #endif
123
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;
130   }
131
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;
137     OutputString(": ");
138     first_normal = line.find(']', begin_bracket);
139     if (first_normal == std::string::npos)
140       first_normal = line.size();
141     else
142       first_normal++;
143     OutputString(line.substr(begin_bracket, first_normal - begin_bracket),
144                  DECORATION_DIM);
145   }
146
147   OutputString(line.substr(first_normal) + "\n");
148 }
149
150 void PrintLongHelp(const std::string& text) {
151   std::vector<std::string> lines;
152   base::SplitStringDontTrim(text, '\n', &lines);
153
154   for (size_t i = 0; i < lines.size(); i++) {
155     const std::string& line = lines[i];
156
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");
165       continue;
166     }
167
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;
174         break;
175       } else if (line[char_i] != ' ') {
176         break;
177       }
178     }
179
180     OutputString(line + "\n", dec);
181   }
182 }
183