From ca084abe9002794bd9585b7144cddb99343449a3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 00:44:27 +0900 Subject: [PATCH] feat: consider the first comments as a file comment --- toml/parser.hpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index 6cc028b..b8a34cc 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1703,6 +1703,44 @@ result parse_toml_file(location& loc) return ok(value_type(table_type{})); } + // put the first line as a region of a file + const region file(loc, loc.iter(), + std::find(loc.iter(), loc.end(), '\n')); + + // The first successive comments that are separated from the first value + // by an empty line are for a file itself. + // ```toml + // # this is a comment for a file. + // + // key = "the first value" + // ``` + // ```toml + // # this is a comment for "the first value". + // key = "the first value" + // ``` + std::vector comments; + using lex_first_comments = sequence< + repeat, lex_comment, lex_newline>, at_least<1>>, + sequence, lex_newline> + >; + if(const auto token = lex_first_comments::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + while(inner_loc.iter() != inner_loc.end()) + { + maybe::invoke(inner_loc); // remove ws if exists + if(lex_newline::invoke(inner_loc)) + { + assert(inner_loc.iter() == inner_loc.end()); + break; // empty line found. + } + auto com = lex_comment::invoke(inner_loc).unwrap().str(); + com.erase(com.begin()); // remove # sign + comments.push_back(std::move(com)); + lex_newline::invoke(inner_loc); + } + } + table_type data; // root object is also a table, but without [tablename] if(auto tab = parse_ml_table(loc)) @@ -1752,7 +1790,11 @@ result parse_toml_file(location& loc) return err(format_underline("[error]: toml::parse_toml_file: " "unknown line appeared", {{std::addressof(loc), "unknown format"}})); } - return ok(data); + + Value v(std::move(data), file); + v.comments() = comments; + + return ok(std::move(v)); } } // detail