diff options
Diffstat (limited to '')
-rw-r--r-- | src/pretty_printer.cc | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/src/pretty_printer.cc b/src/pretty_printer.cc index 2ff3e11..0e9ec0e 100644 --- a/src/pretty_printer.cc +++ b/src/pretty_printer.cc @@ -29,6 +29,10 @@ #include "pretty_printer.hh" +#include <sys/types.h> + +#include "base/auto_mem.hh" +#include "base/intern_string.hh" #include "base/string_util.hh" #include "config.h" @@ -73,14 +77,14 @@ pretty_printer::append_to(attr_line_t& al) = this->pp_stream.tellp(); this->pp_interval_state.back().is_name = tok_res->to_string(); - this->descend(); + this->descend(DT_XML_CLOSE_TAG); } else { this->pp_values.emplace_back(el); } continue; case DT_XML_CLOSE_TAG: this->flush_values(); - this->ascend(); + this->ascend(el.e_token); this->append_child_node(); this->write_element(el); this->start_new_line(); @@ -90,7 +94,7 @@ pretty_printer::append_to(attr_line_t& al) case DT_LPAREN: this->flush_values(true); this->pp_values.emplace_back(el); - this->descend(); + this->descend(to_closer(el.e_token)); this->pp_interval_state.back().is_start = this->pp_stream.tellp(); continue; @@ -101,7 +105,7 @@ pretty_printer::append_to(attr_line_t& al) if (this->pp_body_lines.top()) { this->start_new_line(); } - this->ascend(); + this->ascend(el.e_token); this->write_element(el); continue; case DT_COMMA: @@ -131,13 +135,17 @@ pretty_printer::append_to(attr_line_t& al) this->pp_values.emplace_back(el); } while (this->pp_depth > 0) { - this->ascend(); + this->ascend(this->pp_container_tokens.back()); } this->flush_values(); attr_line_t combined; combined.get_string() = this->pp_stream.str(); - combined.get_attrs() = this->pp_attrs; + auto& attrs = combined.get_attrs(); + attrs = this->pp_attrs; + attrs.insert( + attrs.end(), this->pp_post_attrs.begin(), this->pp_post_attrs.end()); + this->pp_post_attrs.clear(); if (!al.empty()) { al.append("\n"); @@ -163,11 +171,16 @@ pretty_printer::append_to(attr_line_t& al) void pretty_printer::write_element(const pretty_printer::element& el) { + ssize_t start_size = this->pp_stream.tellp(); if (this->pp_leading_indent == 0 && this->pp_line_length == 0 && el.e_token == DT_WHITE) { if (this->pp_depth == 0) { this->pp_soft_indent += el.e_capture.length(); + } else { + auto shift_cover = line_range{(int) start_size, (int) start_size}; + shift_string_attrs( + this->pp_attrs, shift_cover, -el.e_capture.length()); } return; } @@ -183,12 +196,12 @@ pretty_printer::write_element(const pretty_printer::element& el) } return; } + int indent_size = 0; if (this->pp_line_length == 0) { - this->append_indent(); + indent_size = this->append_indent(); } - ssize_t start_size = this->pp_stream.tellp(); if (el.e_token == DT_QUOTED_STRING) { - auto_mem<char> unquoted_str((char*) malloc(el.e_capture.length() + 1)); + auto unquoted_str = auto_mem<char>::malloc(el.e_capture.length() + 1); const char* start = this->pp_scanner->to_string_fragment(el.e_capture).data(); auto unq_len = unquote(unquoted_str.in(), start, el.e_capture.length()); @@ -222,11 +235,9 @@ pretty_printer::write_element(const pretty_printer::element& el) } } else { this->pp_stream << this->pp_scanner->to_string_fragment(el.e_capture); - int shift_amount - = start_size - el.e_capture.c_begin - this->pp_shift_accum; - shift_string_attrs(this->pp_attrs, el.e_capture.c_begin, shift_amount); - this->pp_shift_accum = start_size - el.e_capture.c_begin; } + auto shift_cover = line_range{(int) start_size, (int) start_size}; + shift_string_attrs(this->pp_attrs, shift_cover, indent_size); this->pp_line_length += el.e_capture.length(); if (el.e_token == DT_LINE) { this->pp_line_length = 0; @@ -234,18 +245,23 @@ pretty_printer::write_element(const pretty_printer::element& el) } } -void +int pretty_printer::append_indent() { + auto start_size = this->pp_stream.tellp(); this->pp_stream << std::string( this->pp_leading_indent + this->pp_soft_indent, ' '); this->pp_soft_indent = 0; - if (this->pp_stream.tellp() == this->pp_leading_indent) { - return; - } - for (int lpc = 0; lpc < this->pp_depth; lpc++) { - this->pp_stream << " "; + if (this->pp_stream.tellp() != this->pp_leading_indent) { + for (int lpc = 0; lpc < this->pp_depth; lpc++) { + this->pp_stream << " "; + } + if (this->pp_depth > 0) { + this->pp_indents.insert(this->pp_leading_indent + + 4 * this->pp_depth); + } } + return (this->pp_stream.tellp() - start_size); } bool @@ -286,7 +302,11 @@ pretty_printer::flush_values(bool start_on_depth) && (el.e_token == DT_LSQUARE || el.e_token == DT_LCURLY)) { if (this->pp_line_length > 0) { + ssize_t start_size = this->pp_stream.tellp(); this->pp_stream << std::endl; + auto shift_cover + = line_range{(int) start_size, (int) start_size}; + shift_string_attrs(this->pp_attrs, shift_cover, 1); } this->pp_line_length = 0; } @@ -302,43 +322,66 @@ pretty_printer::start_new_line() { bool has_output; + ssize_t start_size = this->pp_stream.tellp(); if (this->pp_line_length > 0) { this->pp_stream << std::endl; + auto shift_cover = line_range{(int) start_size, (int) start_size}; + shift_string_attrs(this->pp_attrs, shift_cover, 1); this->pp_line_length = 0; } has_output = this->flush_values(); if (has_output && this->pp_line_length > 0) { + start_size = this->pp_stream.tellp(); this->pp_stream << std::endl; + auto shift_cover = line_range{(int) start_size, (int) start_size}; + shift_string_attrs(this->pp_attrs, shift_cover, 1); } this->pp_line_length = 0; this->pp_body_lines.top() += 1; } void -pretty_printer::ascend() +pretty_printer::ascend(data_token_t dt) { if (this->pp_depth > 0) { - int lines = this->pp_body_lines.top(); - this->pp_depth -= 1; - this->pp_body_lines.pop(); - this->pp_body_lines.top() += lines; - - if (!this->pp_is_xml) { - this->append_child_node(); + if (this->pp_container_tokens.back() != dt + && std::find(this->pp_container_tokens.begin(), + this->pp_container_tokens.end(), + dt) + == this->pp_container_tokens.end()) + { + return; } - this->pp_interval_state.pop_back(); - this->pp_hier_stage = std::move(this->pp_hier_nodes.back()); - this->pp_hier_nodes.pop_back(); + + auto found = false; + do { + if (this->pp_container_tokens.back() == dt) { + found = true; + } + int lines = this->pp_body_lines.top(); + this->pp_depth -= 1; + this->pp_body_lines.pop(); + this->pp_body_lines.top() += lines; + + if (!this->pp_is_xml) { + this->append_child_node(); + } + this->pp_interval_state.pop_back(); + this->pp_hier_stage = std::move(this->pp_hier_nodes.back()); + this->pp_hier_nodes.pop_back(); + this->pp_container_tokens.pop_back(); + } while (!found); } else { this->pp_body_lines.top() = 0; } } void -pretty_printer::descend() +pretty_printer::descend(data_token_t dt) { this->pp_depth += 1; this->pp_body_lines.push(0); + this->pp_container_tokens.push_back(dt); this->pp_interval_state.resize(this->pp_depth + 1); this->pp_hier_nodes.push_back( std::make_unique<lnav::document::hier_node>()); |