- add sources.
[platform/framework/web/crosswalk.git] / src / tools / gn / escape.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/escape.h"
6
7 #include "base/containers/stack_container.h"
8
9 namespace {
10
11 template<typename DestString>
12 void EscapeStringToString(const base::StringPiece& str,
13                           const EscapeOptions& options,
14                           DestString* dest,
15                           bool* needed_quoting) {
16   bool used_quotes = false;
17
18   for (size_t i = 0; i < str.size(); i++) {
19     if (str[i] == '$' && (options.mode & ESCAPE_NINJA)) {
20       // Escape dollars signs since ninja treats these specially.
21       dest->push_back('$');
22       dest->push_back('$');
23     } else if (str[i] == '"' && (options.mode & ESCAPE_SHELL)) {
24       // Escape quotes with backslashes for the command-line (Ninja doesn't
25       // care).
26       dest->push_back('\\');
27       dest->push_back('"');
28     } else if (str[i] == ' ') {
29       if (options.mode & ESCAPE_NINJA) {
30         // For Ninja just escape spaces with $.
31         dest->push_back('$');
32       }
33       if (options.mode & ESCAPE_SHELL) {
34         // For the shell, quote the whole string.
35         if (needed_quoting)
36           *needed_quoting = true;
37         if (!options.inhibit_quoting) {
38           if (!used_quotes) {
39             used_quotes = true;
40             dest->insert(dest->begin(), '"');
41           }
42         }
43       }
44       dest->push_back(' ');
45     } else if (str[i] == '\'' && (options.mode & ESCAPE_JSON)) {
46       dest->push_back('\\');
47       dest->push_back('\'');
48 #if defined(OS_WIN)
49     } else if (str[i] == '/' && options.convert_slashes) {
50       // Convert slashes on Windows if requested.
51       dest->push_back('\\');
52 #else
53     } else if (str[i] == '\\' && (options.mode & ESCAPE_SHELL)) {
54       // For non-Windows shell, escape backslashes.
55       dest->push_back('\\');
56       dest->push_back('\\');
57 #endif
58     } else if (str[i] == '\\' && (options.mode & ESCAPE_JSON)) {
59       dest->push_back('\\');
60       dest->push_back('\\');
61     } else {
62       dest->push_back(str[i]);
63     }
64   }
65
66   if (used_quotes)
67     dest->push_back('"');
68 }
69
70 }  // namespace
71
72 std::string EscapeString(const base::StringPiece& str,
73                          const EscapeOptions& options,
74                          bool* needed_quoting) {
75   std::string result;
76   result.reserve(str.size() + 4);  // Guess we'll add a couple of extra chars.
77   EscapeStringToString(str, options, &result, needed_quoting);
78   return result;
79 }
80
81 void EscapeStringToStream(std::ostream& out,
82                           const base::StringPiece& str,
83                           const EscapeOptions& options) {
84   // Escape to a stack buffer and then write out to the stream.
85   base::StackVector<char, 256> result;
86   result->reserve(str.size() + 4);  // Guess we'll add a couple of extra chars.
87   EscapeStringToString(str, options, &result.container(), NULL);
88   if (!result->empty())
89     out.write(result->data(), result->size());
90 }