19 #include <boost/filesystem.hpp>
20 #include <fmt/format.h>
25 namespace classic = boost::spirit::classic;
26 namespace bf = boost::filesystem;
29 namespace qi = boost::spirit::qi;
36 for (
size_t p =
s.find( delim ); p !=
s.npos; p =
s.find( delim ) ) {
37 s.remove_prefix( p + 1 );
40 return {
line,
s.size() + 1 };
43 template <
typename Grammar>
48 auto [last_line, last_column] = GetLastLineAndColumn( input );
52 ForwardIterator fwd_begin = boost::spirit::make_default_multi_pass( in_begin );
56 Iterator position_begin( fwd_begin, fwd_end, stream_name );
62 root->value = stream_name;
63 bool result = qi::phrase_parse( position_begin, position_end,
gr, skipper, *
root );
66 if ( result && ( pos.line == last_line ) && ( pos.column == last_column ) ) {
return true; }
73 template <
typename Grammar>
74 bool ParseFile(
const gp::Position& from, std::string_view
filename, std::string_view search_path,
79 search_path_with_current_dir =
80 file_path.parent_path().
string() +
81 ( search_path_with_current_dir.
empty() ?
"" : (
"," + search_path_with_current_dir ) );
86 if ( absolute_path.
empty() ) {
88 search_path_with_current_dir +
"'" );
92 if ( !included->
GetPosition( absolute_path, &included_from ) ) {
93 included->
AddFile( absolute_path, from );
95 if ( !file.is_open() ) {
99 return ParseStream<Grammar>( file, absolute_path, messages,
root );
101 assert( included_from !=
nullptr );
103 from,
fmt::format(
"File {} already included from {}", absolute_path, included_from->
ToString() ) );
118 return ParseFile<Grammar>( from,
filename, search_path, included, messages,
root );
125 return ParseFile<Grammar>( from,
filename, search_path, included, messages,
root );