clang-format: update c/cc coding style
Update all cc code using .clang-format; please do so as well for future PRs etc.; emacs has a handy 'clang-format' mode to make this automatic. For comparing old changes with git blame, we can disregard this one using --ignore-rev (see https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame )
This commit is contained in:
@ -18,7 +18,6 @@
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "mu-sexp.hh"
|
||||
#include "mu-utils.hh"
|
||||
|
||||
@ -30,231 +29,221 @@ using namespace Mu;
|
||||
__attribute__((format(printf, 2, 0))) static Mu::Error
|
||||
parsing_error(size_t pos, const char* frm, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, frm);
|
||||
auto msg = vformat(frm, args);
|
||||
va_end(args);
|
||||
va_list args;
|
||||
va_start(args, frm);
|
||||
auto msg = vformat(frm, args);
|
||||
va_end(args);
|
||||
|
||||
if (pos == 0)
|
||||
return Mu::Error(Error::Code::Parsing, "%s", msg.c_str());
|
||||
else
|
||||
return Mu::Error(Error::Code::Parsing, "%zu: %s", pos, msg.c_str());
|
||||
if (pos == 0)
|
||||
return Mu::Error(Error::Code::Parsing, "%s", msg.c_str());
|
||||
else
|
||||
return Mu::Error(Error::Code::Parsing, "%zu: %s", pos, msg.c_str());
|
||||
}
|
||||
static size_t
|
||||
skip_whitespace (const std::string& s, size_t pos)
|
||||
skip_whitespace(const std::string& s, size_t pos)
|
||||
{
|
||||
while (pos != s.size()) {
|
||||
if (s[pos] == ' ' || s[pos] == '\t' || s[pos] == '\n')
|
||||
++pos;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (pos != s.size()) {
|
||||
if (s[pos] == ' ' || s[pos] == '\t' || s[pos] == '\n')
|
||||
++pos;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
static Sexp parse (const std::string& expr, size_t& pos);
|
||||
static Sexp parse(const std::string& expr, size_t& pos);
|
||||
|
||||
static Sexp
|
||||
parse_list (const std::string& expr, size_t& pos)
|
||||
parse_list(const std::string& expr, size_t& pos)
|
||||
{
|
||||
if (expr[pos] != '(') // sanity check.
|
||||
throw parsing_error(pos, "expected: '(' but got '%c", expr[pos]);
|
||||
if (expr[pos] != '(') // sanity check.
|
||||
throw parsing_error(pos, "expected: '(' but got '%c", expr[pos]);
|
||||
|
||||
Sexp::List list;
|
||||
Sexp::List list;
|
||||
|
||||
++pos;
|
||||
while (expr[pos] != ')' && pos != expr.size())
|
||||
list.add(parse(expr, pos));
|
||||
++pos;
|
||||
while (expr[pos] != ')' && pos != expr.size())
|
||||
list.add(parse(expr, pos));
|
||||
|
||||
if (expr[pos] != ')')
|
||||
throw parsing_error(pos, "expected: ')' but got '%c'", expr[pos]);
|
||||
++pos;
|
||||
return Sexp::make_list(std::move(list));
|
||||
if (expr[pos] != ')')
|
||||
throw parsing_error(pos, "expected: ')' but got '%c'", expr[pos]);
|
||||
++pos;
|
||||
return Sexp::make_list(std::move(list));
|
||||
}
|
||||
|
||||
// parse string
|
||||
static Sexp
|
||||
parse_string (const std::string& expr, size_t& pos)
|
||||
parse_string(const std::string& expr, size_t& pos)
|
||||
{
|
||||
if (expr[pos] != '"') // sanity check.
|
||||
throw parsing_error(pos, "expected: '\"'' but got '%c", expr[pos]);
|
||||
if (expr[pos] != '"') // sanity check.
|
||||
throw parsing_error(pos, "expected: '\"'' but got '%c", expr[pos]);
|
||||
|
||||
bool escape{};
|
||||
std::string str;
|
||||
for (++pos; pos != expr.size(); ++pos) {
|
||||
bool escape{};
|
||||
std::string str;
|
||||
for (++pos; pos != expr.size(); ++pos) {
|
||||
auto kar = expr[pos];
|
||||
if (escape && (kar == '"' || kar == '\\')) {
|
||||
str += kar;
|
||||
escape = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto kar = expr[pos];
|
||||
if (escape && (kar == '"' || kar == '\\')) {
|
||||
str += kar;
|
||||
escape = false;
|
||||
continue;
|
||||
}
|
||||
if (kar == '"')
|
||||
break;
|
||||
else if (kar == '\\')
|
||||
escape = true;
|
||||
else
|
||||
str += kar;
|
||||
}
|
||||
|
||||
if (kar == '"')
|
||||
break;
|
||||
else if (kar == '\\')
|
||||
escape = true;
|
||||
else
|
||||
str += kar;
|
||||
}
|
||||
if (escape || expr[pos] != '"')
|
||||
throw parsing_error(pos, "unterminated string '%s'", str.c_str());
|
||||
|
||||
if (escape || expr[pos] != '"')
|
||||
throw parsing_error(pos, "unterminated string '%s'", str.c_str());
|
||||
|
||||
++pos;
|
||||
return Sexp::make_string(std::move(str));
|
||||
++pos;
|
||||
return Sexp::make_string(std::move(str));
|
||||
}
|
||||
|
||||
static Sexp
|
||||
parse_integer (const std::string& expr, size_t& pos)
|
||||
parse_integer(const std::string& expr, size_t& pos)
|
||||
{
|
||||
if (!isdigit(expr[pos]) && expr[pos] != '-') // sanity check.
|
||||
throw parsing_error(pos, "expected: <digit> but got '%c", expr[pos]);
|
||||
if (!isdigit(expr[pos]) && expr[pos] != '-') // sanity check.
|
||||
throw parsing_error(pos, "expected: <digit> but got '%c", expr[pos]);
|
||||
|
||||
std::string num; // negative number?
|
||||
if (expr[pos] == '-') {
|
||||
num = "-";
|
||||
++pos;
|
||||
}
|
||||
std::string num; // negative number?
|
||||
if (expr[pos] == '-') {
|
||||
num = "-";
|
||||
++pos;
|
||||
}
|
||||
|
||||
for (; isdigit(expr[pos]); ++pos)
|
||||
num += expr[pos];
|
||||
for (; isdigit(expr[pos]); ++pos)
|
||||
num += expr[pos];
|
||||
|
||||
return Sexp::make_number(::atoi(num.c_str()));
|
||||
return Sexp::make_number(::atoi(num.c_str()));
|
||||
}
|
||||
|
||||
static Sexp
|
||||
parse_symbol (const std::string& expr, size_t& pos)
|
||||
parse_symbol(const std::string& expr, size_t& pos)
|
||||
{
|
||||
if (!isalpha(expr[pos]) && expr[pos] != ':') // sanity check.
|
||||
throw parsing_error(pos, "expected: <alpha>|: but got '%c", expr[pos]);
|
||||
if (!isalpha(expr[pos]) && expr[pos] != ':') // sanity check.
|
||||
throw parsing_error(pos, "expected: <alpha>|: but got '%c", expr[pos]);
|
||||
|
||||
std::string symbol(1, expr[pos]);
|
||||
for (++pos; isalnum(expr[pos]) || expr[pos] == '-'; ++pos)
|
||||
symbol += expr[pos];
|
||||
std::string symbol(1, expr[pos]);
|
||||
for (++pos; isalnum(expr[pos]) || expr[pos] == '-'; ++pos)
|
||||
symbol += expr[pos];
|
||||
|
||||
return Sexp::make_symbol(std::move(symbol));
|
||||
return Sexp::make_symbol(std::move(symbol));
|
||||
}
|
||||
|
||||
|
||||
static Sexp
|
||||
parse (const std::string& expr, size_t& pos)
|
||||
parse(const std::string& expr, size_t& pos)
|
||||
{
|
||||
pos = skip_whitespace(expr, pos);
|
||||
pos = skip_whitespace(expr, pos);
|
||||
|
||||
if (pos == expr.size())
|
||||
throw parsing_error(pos, "expected: character '%c", expr[pos]);
|
||||
if (pos == expr.size())
|
||||
throw parsing_error(pos, "expected: character '%c", expr[pos]);
|
||||
|
||||
const auto kar = expr[pos];
|
||||
const auto node =[&]() -> Sexp {
|
||||
if (kar == '(')
|
||||
return parse_list (expr, pos);
|
||||
else if (kar == '"')
|
||||
return parse_string(expr, pos);
|
||||
else if (isdigit(kar) || kar == '-')
|
||||
return parse_integer(expr, pos);
|
||||
else if (isalpha(kar) || kar == ':')
|
||||
return parse_symbol(expr, pos);
|
||||
else
|
||||
throw parsing_error(pos, "unexpected character '%c", kar);
|
||||
}();
|
||||
const auto kar = expr[pos];
|
||||
const auto node = [&]() -> Sexp {
|
||||
if (kar == '(')
|
||||
return parse_list(expr, pos);
|
||||
else if (kar == '"')
|
||||
return parse_string(expr, pos);
|
||||
else if (isdigit(kar) || kar == '-')
|
||||
return parse_integer(expr, pos);
|
||||
else if (isalpha(kar) || kar == ':')
|
||||
return parse_symbol(expr, pos);
|
||||
else
|
||||
throw parsing_error(pos, "unexpected character '%c", kar);
|
||||
}();
|
||||
|
||||
pos = skip_whitespace(expr, pos);
|
||||
pos = skip_whitespace(expr, pos);
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
Sexp
|
||||
Sexp::make_parse (const std::string& expr)
|
||||
Sexp::make_parse(const std::string& expr)
|
||||
{
|
||||
size_t pos{};
|
||||
auto node{::parse (expr, pos)};
|
||||
size_t pos{};
|
||||
auto node{::parse(expr, pos)};
|
||||
|
||||
if (pos != expr.size())
|
||||
throw parsing_error(pos, "trailing data starting with '%c'", expr[pos]);
|
||||
if (pos != expr.size())
|
||||
throw parsing_error(pos, "trailing data starting with '%c'", expr[pos]);
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Sexp::to_sexp_string () const
|
||||
Sexp::to_sexp_string() const
|
||||
{
|
||||
std::stringstream sstrm;
|
||||
std::stringstream sstrm;
|
||||
|
||||
switch (type()) {
|
||||
case Type::List: {
|
||||
sstrm << '(';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : " ") << child.to_sexp_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ')';
|
||||
break;
|
||||
}
|
||||
case Type::String:
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Number:
|
||||
case Type::Symbol:
|
||||
case Type::Empty:
|
||||
default:
|
||||
sstrm << value();
|
||||
}
|
||||
switch (type()) {
|
||||
case Type::List: {
|
||||
sstrm << '(';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : " ") << child.to_sexp_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ')';
|
||||
break;
|
||||
}
|
||||
case Type::String: sstrm << quote(value()); break;
|
||||
case Type::Number:
|
||||
case Type::Symbol:
|
||||
case Type::Empty:
|
||||
default: sstrm << value();
|
||||
}
|
||||
|
||||
return sstrm.str();
|
||||
return sstrm.str();
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Sexp::to_json_string () const
|
||||
Sexp::to_json_string() const
|
||||
{
|
||||
std::stringstream sstrm;
|
||||
std::stringstream sstrm;
|
||||
|
||||
switch (type()) {
|
||||
case Type::List: {
|
||||
// property-lists become JSON objects
|
||||
if (is_prop_list()) {
|
||||
sstrm << "{";
|
||||
auto it{list().begin()};
|
||||
bool first{true};
|
||||
while (it != list().end()) {
|
||||
sstrm << (first?"":",") << quote(it->value()) << ":";
|
||||
++it;
|
||||
sstrm << it->to_json_string();
|
||||
++it;
|
||||
first = false;
|
||||
}
|
||||
sstrm << "}";
|
||||
} else { // other lists become arrays.
|
||||
sstrm << '[';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : ", ") << child.to_json_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ']';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::String:
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Symbol:
|
||||
if (is_nil())
|
||||
sstrm << "false";
|
||||
else if (is_t())
|
||||
sstrm << "true";
|
||||
else
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Number:
|
||||
case Type::Empty:
|
||||
default:
|
||||
sstrm << value();
|
||||
}
|
||||
switch (type()) {
|
||||
case Type::List: {
|
||||
// property-lists become JSON objects
|
||||
if (is_prop_list()) {
|
||||
sstrm << "{";
|
||||
auto it{list().begin()};
|
||||
bool first{true};
|
||||
while (it != list().end()) {
|
||||
sstrm << (first ? "" : ",") << quote(it->value()) << ":";
|
||||
++it;
|
||||
sstrm << it->to_json_string();
|
||||
++it;
|
||||
first = false;
|
||||
}
|
||||
sstrm << "}";
|
||||
} else { // other lists become arrays.
|
||||
sstrm << '[';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : ", ") << child.to_json_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ']';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::String: sstrm << quote(value()); break;
|
||||
case Type::Symbol:
|
||||
if (is_nil())
|
||||
sstrm << "false";
|
||||
else if (is_t())
|
||||
sstrm << "true";
|
||||
else
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Number:
|
||||
case Type::Empty:
|
||||
default: sstrm << value();
|
||||
}
|
||||
|
||||
return sstrm.str();
|
||||
return sstrm.str();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user