19 #include <boost/filesystem.hpp>
20 #include <fmt/format.h>
24 namespace classic = boost::spirit::classic;
25 namespace bf = boost::filesystem;
28 namespace qi = boost::spirit::qi;
35 while ( !ifs.
eof() ) {
42 ifs.
seekg( 0, ifs.beg );
45 template <
typename Grammar>
48 int last_line, last_column;
50 GetLastLineAndColumn(
stream, last_line, last_column );
56 ForwardIterator fwd_begin = boost::spirit::make_default_multi_pass( in_begin );
61 Iterator position_begin( fwd_begin, fwd_end, stream_name );
67 root->value = stream_name;
68 bool result = qi::phrase_parse( position_begin, position_end,
gr, skipper, *
root );
71 if ( result && ( pos.line == last_line ) && ( pos.column == last_column ) ) {
return true; }
78 template <
typename Grammar>
79 bool ParseFile(
const gp::Position& from, std::string_view
filename, std::string_view search_path,
84 search_path_with_current_dir =
85 file_path.parent_path().
string() +
86 ( search_path_with_current_dir.
empty() ?
"" : (
"," + search_path_with_current_dir ) );
91 if ( absolute_path.
empty() ) {
93 search_path_with_current_dir +
"'" );
97 if ( !included->
GetPosition( absolute_path, &included_from ) ) {
98 included->
AddFile( absolute_path, from );
100 if ( !file.is_open() ) {
104 return ParseStream<Grammar>( file, absolute_path, messages,
root );
106 assert( included_from !=
nullptr );
108 from,
fmt::format(
"File {} already included from {}", absolute_path, included_from->
ToString() ) );
123 return ParseFile<Grammar>( from,
filename, search_path, included, messages,
root );
130 return ParseFile<Grammar>( from,
filename, search_path, included, messages,
root );