OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/escape.h" | 5 #include "tools/gn/escape.h" |
6 | 6 |
7 #include "base/containers/stack_container.h" | 7 #include "base/containers/stack_container.h" |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
11 // A "1" in this lookup table means that char is valid in the shell. | |
12 const char kShellValid[0x80] = { | |
13 // 00-1f: all are invalid | |
14 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
16 // ' ' ! " # $ % & ' ( ) * + , - . / | |
17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, | |
18 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? | |
19 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, | |
20 // @ A B C D E F G H I J K L M N O | |
21 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
22 // P Q R S T U V W X Y Z [ \ ] ^ _ | |
23 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, | |
24 // ` a b c d e f g h i j k l m n o | |
25 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
26 // p q r s t u v w x y z { | } ~ | |
27 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 }; | |
28 | |
11 template<typename DestString> | 29 template<typename DestString> |
12 void EscapeStringToString(const base::StringPiece& str, | 30 void EscapeStringToString(const base::StringPiece& str, |
13 const EscapeOptions& options, | 31 const EscapeOptions& options, |
14 DestString* dest, | 32 DestString* dest, |
15 bool* needed_quoting) { | 33 bool* needed_quoting) { |
16 bool used_quotes = false; | 34 bool used_quotes = false; |
17 | 35 |
18 for (size_t i = 0; i < str.size(); i++) { | 36 for (size_t i = 0; i < str.size(); i++) { |
19 if (str[i] == '$' && (options.mode & ESCAPE_NINJA)) { | 37 if (str[i] == '$' && (options.mode & ESCAPE_NINJA)) { |
20 // Escape dollars signs since ninja treats these specially. | 38 // Escape dollars signs since ninja treats these specially. If we're also |
39 // escaping for the shell, we need to backslash-escape that again. | |
scottmg
2014/05/30 18:02:15
this should be if !WIN i think
| |
40 if (options.mode & ESCAPE_SHELL) | |
41 dest->push_back('\\'); | |
21 dest->push_back('$'); | 42 dest->push_back('$'); |
22 dest->push_back('$'); | 43 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] == ' ') { | 44 } else if (str[i] == ' ') { |
29 if (options.mode & ESCAPE_NINJA) { | 45 if (options.mode & ESCAPE_NINJA) { |
30 // For Ninja just escape spaces with $. | 46 // For Ninja just escape spaces with $. |
31 dest->push_back('$'); | 47 dest->push_back('$'); |
32 } | 48 } |
33 if (options.mode & ESCAPE_SHELL) { | 49 if (options.mode & ESCAPE_SHELL) { |
34 // For the shell, quote the whole string. | 50 // For the shell, quote the whole string. |
35 if (needed_quoting) | 51 if (needed_quoting) |
36 *needed_quoting = true; | 52 *needed_quoting = true; |
37 if (!options.inhibit_quoting) { | 53 if (!options.inhibit_quoting) { |
(...skipping 16 matching lines...) Expand all Loading... | |
54 // For non-Windows shell, escape backslashes. | 70 // For non-Windows shell, escape backslashes. |
55 dest->push_back('\\'); | 71 dest->push_back('\\'); |
56 dest->push_back('\\'); | 72 dest->push_back('\\'); |
57 #endif | 73 #endif |
58 } else if (str[i] == '\\' && (options.mode & ESCAPE_JSON)) { | 74 } else if (str[i] == '\\' && (options.mode & ESCAPE_JSON)) { |
59 dest->push_back('\\'); | 75 dest->push_back('\\'); |
60 dest->push_back('\\'); | 76 dest->push_back('\\'); |
61 } else if (str[i] == ':' && (options.mode & ESCAPE_NINJA)) { | 77 } else if (str[i] == ':' && (options.mode & ESCAPE_NINJA)) { |
62 dest->push_back('$'); | 78 dest->push_back('$'); |
63 dest->push_back(':'); | 79 dest->push_back(':'); |
80 } else if ((options.mode & ESCAPE_SHELL) && | |
scottmg
2014/05/30 18:02:15
and this too, or at least \ doesn't escape them on
| |
81 (static_cast<unsigned>(str[i]) >= 0x80 || | |
82 !kShellValid[static_cast<int>(str[i])])) { | |
83 // All other invalid shell chars get backslash-escaped. | |
84 dest->push_back('\\'); | |
85 dest->push_back(str[i]); | |
64 } else { | 86 } else { |
65 dest->push_back(str[i]); | 87 dest->push_back(str[i]); |
66 } | 88 } |
67 } | 89 } |
68 | 90 |
69 if (used_quotes) | 91 if (used_quotes) |
70 dest->push_back('"'); | 92 dest->push_back('"'); |
71 } | 93 } |
72 | 94 |
73 } // namespace | 95 } // namespace |
(...skipping 10 matching lines...) Expand all Loading... | |
84 void EscapeStringToStream(std::ostream& out, | 106 void EscapeStringToStream(std::ostream& out, |
85 const base::StringPiece& str, | 107 const base::StringPiece& str, |
86 const EscapeOptions& options) { | 108 const EscapeOptions& options) { |
87 // Escape to a stack buffer and then write out to the stream. | 109 // Escape to a stack buffer and then write out to the stream. |
88 base::StackVector<char, 256> result; | 110 base::StackVector<char, 256> result; |
89 result->reserve(str.size() + 4); // Guess we'll add a couple of extra chars. | 111 result->reserve(str.size() + 4); // Guess we'll add a couple of extra chars. |
90 EscapeStringToString(str, options, &result.container(), NULL); | 112 EscapeStringToString(str, options, &result.container(), NULL); |
91 if (!result->empty()) | 113 if (!result->empty()) |
92 out.write(&result[0], result->size()); | 114 out.write(&result[0], result->size()); |
93 } | 115 } |
OLD | NEW |