/Users/deen/code/yugabyte-db/src/yb/util/split.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/util/split.h" |
15 | | |
16 | | #include "yb/util/status.h" |
17 | | |
18 | | using std::string; |
19 | | |
20 | | namespace yb { |
21 | | namespace util { |
22 | | |
23 | | using yb::Status; |
24 | | using yb::Slice; |
25 | | |
26 | | template<class Out> |
27 | 8 | Status SplitArgsImpl(const Slice& line, Out* out_vector) { |
28 | 8 | out_vector->clear(); |
29 | | |
30 | | // Points to the current position we are looking at. |
31 | 8 | const char* current_position = line.cdata(); |
32 | | // Points to the end. |
33 | 8 | const char* ptr_end = line.cend(); |
34 | | |
35 | 21 | while (current_position != ptr_end) { |
36 | | // Skip blanks. |
37 | 35 | while (current_position != ptr_end && isspace(*current_position)) { |
38 | 18 | current_position++; |
39 | 18 | } |
40 | | |
41 | 17 | if (current_position != ptr_end) { |
42 | 16 | const char* current_token = current_position; |
43 | 16 | int current_token_length = 0; |
44 | | // Get a token. |
45 | 16 | if (*current_position == '"' || *current_position == '\'') { |
46 | 5 | const char quotation = *current_position; |
47 | 5 | current_token++; // Skip the begining quote. |
48 | 5 | current_position++; |
49 | 42 | while (true) { |
50 | 42 | if (current_position == ptr_end) { |
51 | | // Unterminated quotes. |
52 | 2 | out_vector->clear(); |
53 | 2 | return STATUS(Corruption, "Unterminated quotes."); |
54 | 2 | } |
55 | | |
56 | 40 | if (quotation == *current_position) { |
57 | | // Reached the end of the quoted token. |
58 | | // |
59 | | // Closing quote must be followed by a space or nothing at all. |
60 | 3 | current_position++; |
61 | 3 | if (current_position != ptr_end && !isspace(*current_position)) { |
62 | 1 | out_vector->clear(); |
63 | 1 | return STATUS(Corruption, "A closing quote must be followed by a white space " |
64 | 1 | "or end of input"); |
65 | 1 | } |
66 | 2 | break; |
67 | 2 | } |
68 | 37 | current_token_length++; |
69 | 37 | current_position++; |
70 | 37 | } |
71 | 11 | } else { |
72 | | // Token is not begining with quotes. Process until the next space character. |
73 | 48 | while (current_position != ptr_end && !isspace(*current_position)) { |
74 | 38 | if (*current_position == '"' || *current_position == '\'') { |
75 | 1 | out_vector->clear(); |
76 | 1 | return STATUS(Corruption, "A closing quote must be followed by a white space " |
77 | 1 | "or end of input"); |
78 | 1 | } |
79 | 37 | current_token_length++; |
80 | 37 | current_position++; |
81 | 37 | } |
82 | 11 | } |
83 | | // Save the token. Get ready for the next one. |
84 | 12 | out_vector->emplace_back(current_token, current_token_length); |
85 | 12 | } |
86 | 17 | } |
87 | 4 | return Status::OK(); |
88 | 8 | } _ZN2yb4util13SplitArgsImplINSt3__16vectorINS_5SliceENS2_9allocatorIS4_EEEEEENS_6StatusERKS4_PT_ Line | Count | Source | 27 | 8 | Status SplitArgsImpl(const Slice& line, Out* out_vector) { | 28 | 8 | out_vector->clear(); | 29 | | | 30 | | // Points to the current position we are looking at. | 31 | 8 | const char* current_position = line.cdata(); | 32 | | // Points to the end. | 33 | 8 | const char* ptr_end = line.cend(); | 34 | | | 35 | 21 | while (current_position != ptr_end) { | 36 | | // Skip blanks. | 37 | 35 | while (current_position != ptr_end && isspace(*current_position)) { | 38 | 18 | current_position++; | 39 | 18 | } | 40 | | | 41 | 17 | if (current_position != ptr_end) { | 42 | 16 | const char* current_token = current_position; | 43 | 16 | int current_token_length = 0; | 44 | | // Get a token. | 45 | 16 | if (*current_position == '"' || *current_position == '\'') { | 46 | 5 | const char quotation = *current_position; | 47 | 5 | current_token++; // Skip the begining quote. | 48 | 5 | current_position++; | 49 | 42 | while (true) { | 50 | 42 | if (current_position == ptr_end) { | 51 | | // Unterminated quotes. | 52 | 2 | out_vector->clear(); | 53 | 2 | return STATUS(Corruption, "Unterminated quotes."); | 54 | 2 | } | 55 | | | 56 | 40 | if (quotation == *current_position) { | 57 | | // Reached the end of the quoted token. | 58 | | // | 59 | | // Closing quote must be followed by a space or nothing at all. | 60 | 3 | current_position++; | 61 | 3 | if (current_position != ptr_end && !isspace(*current_position)) { | 62 | 1 | out_vector->clear(); | 63 | 1 | return STATUS(Corruption, "A closing quote must be followed by a white space " | 64 | 1 | "or end of input"); | 65 | 1 | } | 66 | 2 | break; | 67 | 2 | } | 68 | 37 | current_token_length++; | 69 | 37 | current_position++; | 70 | 37 | } | 71 | 11 | } else { | 72 | | // Token is not begining with quotes. Process until the next space character. | 73 | 48 | while (current_position != ptr_end && !isspace(*current_position)) { | 74 | 38 | if (*current_position == '"' || *current_position == '\'') { | 75 | 1 | out_vector->clear(); | 76 | 1 | return STATUS(Corruption, "A closing quote must be followed by a white space " | 77 | 1 | "or end of input"); | 78 | 1 | } | 79 | 37 | current_token_length++; | 80 | 37 | current_position++; | 81 | 37 | } | 82 | 11 | } | 83 | | // Save the token. Get ready for the next one. | 84 | 12 | out_vector->emplace_back(current_token, current_token_length); | 85 | 12 | } | 86 | 17 | } | 87 | 4 | return Status::OK(); | 88 | 8 | } |
Unexecuted instantiation: _ZN2yb4util13SplitArgsImplIN5boost9container17small_vector_baseINS_5SliceEvvEEEENS_6StatusERKS5_PT_ |
89 | | |
90 | 8 | Status SplitArgs(const Slice& line, std::vector<Slice>* out_vector) { |
91 | 8 | return SplitArgsImpl(line, out_vector); |
92 | 8 | } |
93 | | |
94 | 0 | Status SplitArgs(const Slice& line, boost::container::small_vector_base<Slice>* out_vector) { |
95 | 0 | return SplitArgsImpl(line, out_vector); |
96 | 0 | } |
97 | | |
98 | | } // namespace util |
99 | | } // namespace yb |