blob: 28fcb38354b96688b45eaf7300e210f6d53899e1 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/cmd/command.h"
namespace cmd {
Command::Command() = default;
Command::~Command() = default;
const char Command::kWhitespace[] = " \t\r\n";
bool Command::Parse(const std::string& line) {
args_.clear();
size_t pos = 0;
while (pos != std::string::npos) {
size_t start = line.find_first_not_of(kWhitespace, pos);
if (start == std::string::npos) {
return true;
}
if (line[start] == '#') {
return true;
}
if (line[start] == '"') {
std::string token;
if (!ParseQuotedToken(line, start + 1, &token, &pos)) {
args_.clear();
return false;
}
args_.push_back(std::move(token));
} else {
size_t end = line.find_first_of(kWhitespace, start);
std::string token = line.substr(start, end - start);
if (token.find('"') != std::string::npos) {
args_.clear();
parse_error_ = "Unexpected quotation in token.";
return false;
}
args_.push_back(std::move(token));
pos = end;
}
}
return true;
}
bool Command::ParseQuotedToken(const std::string& line, size_t pos, std::string* token,
size_t* end) {
std::vector<char> buffer;
while (pos < line.size()) {
char ch = line[pos++];
switch (ch) {
case '\\':
if (pos == line.size()) {
parse_error_ = "Unterminated escape sequence.";
return false;
}
ch = line[pos++];
switch (ch) {
case 't':
buffer.push_back('\t');
break;
case 'n':
buffer.push_back('\n');
break;
case 'r':
buffer.push_back('\r');
break;
case '"':
buffer.push_back('\"');
break;
case '\\':
buffer.push_back('\\');
break;
default:
parse_error_ = "Unknown escape character: ";
parse_error_ += ch;
return false;
}
break;
case '"':
if (pos < line.size()) {
ch = line[pos];
if (strchr(kWhitespace, ch) == nullptr) {
parse_error_ = "Ending quotation mark did not terminate token.";
return false;
}
}
*token = std::string(buffer.data(), buffer.size());
*end = pos;
return true;
default:
buffer.push_back(ch);
break;
}
}
parse_error_ = "Unterminated quotation.";
return false;
}
} // namespace cmd