From db6f5f55f1f0130bba814c494001cbadb138f53f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 11 Sep 2015 13:30:25 +0200 Subject: Handle file io failures in parser --- build/b.cxx | 12 ++--- build/config/operation.cxx | 8 ++-- build/file.cxx | 57 ++++++++++++------------ build/parser.cxx | 106 +++++++++++++++++++++++++-------------------- 4 files changed, 99 insertions(+), 84 deletions(-) diff --git a/build/b.cxx b/build/b.cxx index 665fac8..8ea9094 100644 --- a/build/b.cxx +++ b/build/b.cxx @@ -186,17 +186,17 @@ main (int argc, char* argv[]) s += ' '; } - istringstream is (s); - is.exceptions (istringstream::failbit | istringstream::badbit); - parser p; - try { + istringstream is (s); + is.exceptions (istringstream::failbit | istringstream::badbit); + + parser p; bspec = p.parse_buildspec (is, ""); } - catch (const std::ios_base::failure&) + catch (const istringstream::failure&) { - fail << "failed to parse buildspec string"; + fail << "unable to parse buildspec '" << s << "'"; } } diff --git a/build/config/operation.cxx b/build/config/operation.cxx index 9d7c9b3..cab6520 100644 --- a/build/config/operation.cxx +++ b/build/config/operation.cxx @@ -57,9 +57,9 @@ namespace build << "#" << endl << "src_root = " << src_root << endl; } - catch (const ios_base::failure&) + catch (const ofstream::failure&) { - fail << "failed to write to " << f; + fail << "unable to write " << f; } } @@ -125,9 +125,9 @@ namespace build } } } - catch (const ios_base::failure&) + catch (const ofstream::failure&) { - fail << "failed to write to " << f; + fail << "unable to write " << f; } } diff --git a/build/file.cxx b/build/file.cxx index 8f51660..3a8a5d0 100644 --- a/build/file.cxx +++ b/build/file.cxx @@ -79,22 +79,22 @@ namespace build { tracer trace ("source"); - ifstream ifs (bf.string ()); - if (!ifs.is_open ()) - fail << "unable to open " << bf; + try + { + ifstream ifs (bf.string ()); + if (!ifs.is_open ()) + fail << "unable to open " << bf; - level5 ([&]{trace << "sourcing " << bf;}); + ifs.exceptions (ifstream::failbit | ifstream::badbit); - ifs.exceptions (ifstream::failbit | ifstream::badbit); - parser p; + level5 ([&]{trace << "sourcing " << bf;}); - try - { + parser p; p.parse_buildfile (ifs, bf, root, base); } - catch (const std::ios_base::failure&) + catch (const ifstream::failure&) { - fail << "failed to read from " << bf; + fail << "unable to read buildfile " << bf; } } @@ -260,14 +260,14 @@ namespace build static value extract_variable (const path& bf, const char* var) { - ifstream ifs (bf.string ()); - if (!ifs.is_open ()) - fail << "unable to open " << bf; - - ifs.exceptions (ifstream::failbit | ifstream::badbit); - try { + ifstream ifs (bf.string ()); + if (!ifs.is_open ()) + fail << "unable to open " << bf; + + ifs.exceptions (ifstream::failbit | ifstream::badbit); + path rbf (diag_relative (bf)); lexer lex (ifs, rbf.string ()); @@ -291,9 +291,9 @@ namespace build value& v (*l); return move (v); // Steal the value, the scope is going away. } - catch (const std::ios_base::failure&) + catch (const ifstream::failure&) { - fail << "failed to read from " << bf; + fail << "unable to read buildfile " << bf; } return value (); // Never reaches. @@ -882,26 +882,27 @@ namespace build // point. // path es (root.src_path () / path ("build/export.build")); - ifstream ifs (es.string ()); - if (!ifs.is_open ()) - fail (loc) << "unable to open " << es; - - level5 ([&]{trace << "importing " << es;}); - - ifs.exceptions (ifstream::failbit | ifstream::badbit); - parser p; try { + ifstream ifs (es.string ()); + if (!ifs.is_open ()) + fail (loc) << "unable to open " << es; + + ifs.exceptions (ifstream::failbit | ifstream::badbit); + + level5 ([&]{trace << "importing " << es;}); + // @@ Should we verify these are all unqualified names? Or maybe // there is a use-case for the export stub to return a qualified // name? // + parser p; return p.parse_export_stub (ifs, es, iroot, ts); } - catch (const std::ios_base::failure&) + catch (const ifstream::failure&) { - fail (loc) << "failed to read from " << es; + fail (loc) << "unable to read buildfile " << es; } return names (); // Never reached. diff --git a/build/parser.cxx b/build/parser.cxx index 227e5b3..8a79ae9 100644 --- a/build/parser.cxx +++ b/build/parser.cxx @@ -446,37 +446,44 @@ namespace build p.normalize (); - ifstream ifs (p.string ()); + try + { + ifstream ifs (p.string ()); - if (!ifs.is_open ()) - fail (l) << "unable to open " << p; + if (!ifs.is_open ()) + fail (l) << "unable to open " << p; - ifs.exceptions (ifstream::failbit | ifstream::badbit); + ifs.exceptions (ifstream::failbit | ifstream::badbit); - level5 ([&]{trace (t) << "entering " << p;}); + level5 ([&]{trace (t) << "entering " << p;}); - enter_buildfile (p); + enter_buildfile (p); - string rw (diag_relative (p)); // Relative to work. - const string* op (path_); - path_ = &rw; + string rw (diag_relative (p)); // Relative to work. + const string* op (path_); + path_ = &rw; - lexer l (ifs, rw); - lexer* ol (lexer_); - lexer_ = &l; + lexer l (ifs, rw); + lexer* ol (lexer_); + lexer_ = &l; - token t (type::eos, false, 0, 0); - type tt; - next (t, tt); - clause (t, tt); + token t (type::eos, false, 0, 0); + type tt; + next (t, tt); + clause (t, tt); - if (tt != type::eos) - fail (t) << "unexpected " << t; + if (tt != type::eos) + fail (t) << "unexpected " << t; - level5 ([&]{trace (t) << "leaving " << p;}); + level5 ([&]{trace (t) << "leaving " << p;}); - lexer_ = ol; - path_ = op; + lexer_ = ol; + path_ = op; + } + catch (const ifstream::failure&) + { + fail (l) << "unable to read buildfile " << p; + } } if (tt == type::newline) @@ -575,43 +582,50 @@ namespace build continue; } - ifstream ifs (p.string ()); + try + { + ifstream ifs (p.string ()); - if (!ifs.is_open ()) - fail (l) << "unable to open " << p; + if (!ifs.is_open ()) + fail (l) << "unable to open " << p; - ifs.exceptions (ifstream::failbit | ifstream::badbit); + ifs.exceptions (ifstream::failbit | ifstream::badbit); - level5 ([&]{trace (t) << "entering " << p;}); + level5 ([&]{trace (t) << "entering " << p;}); - enter_buildfile (p); + enter_buildfile (p); - string rw (diag_relative (p)); // Relative to work. - const string* op (path_); - path_ = &rw; + string rw (diag_relative (p)); // Relative to work. + const string* op (path_); + path_ = &rw; - lexer l (ifs, rw); - lexer* ol (lexer_); - lexer_ = &l; + lexer l (ifs, rw); + lexer* ol (lexer_); + lexer_ = &l; - target* odt (default_target_); - default_target_ = nullptr; + target* odt (default_target_); + default_target_ = nullptr; - token t (type::eos, false, 0, 0); - type tt; - next (t, tt); - clause (t, tt); + token t (type::eos, false, 0, 0); + type tt; + next (t, tt); + clause (t, tt); - if (tt != type::eos) - fail (t) << "unexpected " << t; + if (tt != type::eos) + fail (t) << "unexpected " << t; - process_default_target (t); + process_default_target (t); - level5 ([&]{trace (t) << "leaving " << p;}); + level5 ([&]{trace (t) << "leaving " << p;}); - default_target_ = odt; - lexer_ = ol; - path_ = op; + default_target_ = odt; + lexer_ = ol; + path_ = op; + } + catch (const ifstream::failure&) + { + fail (l) << "unable to read buildfile " << p; + } scope_ = ocs; root_ = ors; -- cgit v1.1