10 #include "boost/filesystem.hpp" 14 #include "cetlib_except/coded_exception.h" 21 namespace bfs = boost::filesystem;
26 std::regex
const reCarriageReturn{
"\r"};
29 enum error { cant_open, cant_read, malformed, recursive };
36 return "Can't locate or can't open specified file:";
38 return "Can't read from supplied input stream:";
40 return "Malformed #include directive:";
42 return "Recursive #include directive:";
44 return "Unknown code";
48 using inc_exception = cet::coded_exception<error, translate>;
61 std::vector<std::string>
62 getlines(std::istream& is)
64 std::vector<std::string>
result;
65 for (
std::string readline; std::getline(is, readline);) {
66 for (
auto const&
line :
68 result.emplace_back(
line);
78 bfs::path path{path_str};
81 path = bfs::canonical(path);
87 throw detail::inc_exception(detail::cant_open)
88 <<
"Exception while examining include specification \"" << path_str
89 <<
"\": " << e.what();
98 : frames_{
frame(0, begin_string(), 0,
text_.size())}
117 for (framenum = 1u; framenum !=
frames_.size(); ++framenum)
118 if (textpos <
frames_[framenum].starting_textpos)
123 uint delta_line_num{};
125 auto const this_frame_begin = this_frame.
nl_positions.cbegin();
126 auto const this_frame_end = this_frame.
nl_positions.cend();
128 std::upper_bound(this_frame_begin, this_frame_end, textpos);
134 uint const newlinepos =
135 textpos == 0u ? std::string::npos :
text_.find_last_of(
'\n', textpos - 1u);
136 uint const charpos = newlinepos == std::string::npos ?
138 textpos -
text_.find_last_of(
'\n', textpos - 1u);
139 return {textpos, linenum, charpos, framenum};
147 std::ostringstream
result;
148 result <<
"line " <<
pos.linenum <<
", character " <<
pos.charpos
149 <<
", of file \"" <<
frames_[
pos.framenum].filename <<
'\"';
159 std::ostringstream
result;
160 result <<
"line " <<
pos.linenum <<
", character " <<
pos.charpos
161 <<
", of file \"" <<
frames_[
pos.framenum].filename <<
'\"' 163 auto cp0 =
pos.charpos - 1;
165 result <<
text_.substr(
pos.textpos - cp0,
166 (eol == std::string::npos) ?
168 (eol - (
pos.textpos - cp0)))
180 std::ostringstream
result;
181 result <<
frames_[
pos.framenum].filename <<
':' <<
pos.linenum;
191 static uint const min_sz = inc_lit.size() + 3u;
194 bool const use_cin = (filename ==
"-");
197 use_cin ? canonicalizePath(filepath) :
filepath;
203 throw inc_exception(recursive)
213 ifs.open(filepath.c_str(), std::ifstream::in);
214 std::istream&
f = use_cin ? std::cin : ifs;
216 throw inc_exception(cant_open)
219 int const starting_linenum = 1;
220 frame new_frame(including_framenum, filepath, starting_linenum,
text_.size());
224 for (
auto&
line : getlines(f)) {
226 if (
line.find(inc_lit) != 0) {
228 new_frame.nl_positions.push_back(
text_.size());
236 new_frame.starting_linenum = linenum;
237 new_frame.starting_textpos =
text_.size();
242 if (
line.size() <= min_sz
244 ||
line[9] !=
'\"' ||
line.end()[-1] !=
'\"' 246 throw inc_exception(malformed)
247 <<
line <<
"\n at line " << linenum <<
" of file " <<
filepath;
254 new_frame.starting_linenum = linenum + 1;
255 new_frame.starting_textpos =
text_.size();
269 static uint const min_sz = inc_lit.size() + 3u;
276 throw inc_exception(cant_open)
279 int const starting_linenum = 1;
280 frame new_frame(0, filepath, starting_linenum,
text_.size());
284 for (
auto&
line : getlines(f)) {
286 if (
line.find(inc_lit) != 0) {
288 new_frame.nl_positions.push_back(
text_.size());
296 new_frame.starting_linenum = linenum;
297 new_frame.starting_textpos =
text_.size();
302 if (
line.size() <= min_sz
304 ||
line[9] !=
'\"' ||
line.end()[-1] !=
'\"' 306 throw inc_exception(malformed)
307 <<
line <<
"\n at line " << linenum <<
" of file " <<
filepath;
314 new_frame.starting_linenum = linenum + 1;
315 new_frame.starting_textpos =
text_.size();
325 std::ostringstream
result;
327 for (
uint k = from_frame;
k != 0u;
k =
frames_[
k].including_framenum) {
328 result <<
"\nincluded from line " <<
frames_[
k].starting_linenum
329 <<
" of file \"" <<
frames_[
k].filename <<
'\"';
337 std::ostringstream
result;
339 result <<
"\nframe[" << 0 <<
"] " <<
frames_[0].including_framenum <<
" " 340 <<
frames_[0].starting_linenum <<
" " <<
frames_[0].starting_textpos
341 <<
" " <<
frames_[0].filename <<
'\n';
344 uint starting_textpos =
frames_[
k - 1u].starting_textpos;
345 result <<
"\nframe[" <<
k <<
"] " <<
frames_[
k].including_framenum <<
" " 347 <<
" " <<
frames_[
k].filename <<
'\n' 348 <<
text_.substr(starting_textpos,
349 frames_[
k].starting_textpos - starting_textpos);
351 std::cerr << result.str();
std::string & trim_right(std::string &source, std::string const &t=" ")
void include(int including_framenum, std::string const &filename, cet::filepath_maker &abs_filename)
std::string::size_type uint
std::string backtrace(uint from_frame) const
std::string highlighted_whereis(const_iterator const &it) const
std::vector< std::string > split_by_regex(std::string const &str, std::regex const &reDelimSet)
bool exists(std::string path)
std::string translate(errors::ErrorCodes)
std::string src_whereis(const_iterator const &it) const
CodeOutputInterface * code
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
std::vector< std::string > recursionStack_
std::string whereis(const_iterator const &it) const
void line(double t, double *p, double &x, double &y, double &z)
posinfo get_posinfo(const_iterator const &it) const
std::string::const_iterator const_iterator
std::vector< frame > frames_
std::vector< size_t > nl_positions
cet::coded_exception< error, detail::translate > exception
includer(std::string const &filename, cet::filepath_maker &abs_filename)