summaryrefslogtreecommitdiffstats
path: root/src/pretty_printer.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/pretty_printer.cc105
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>());