aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-11 13:30:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-11 13:30:25 +0200
commitdb6f5f55f1f0130bba814c494001cbadb138f53f (patch)
treef2206b2f46dcd56a692ce003671c6e33c3eda7a5
parenta7362cf29a76ef679c9a1ce74715a5d087851b91 (diff)
Handle file io failures in parser
-rw-r--r--build/b.cxx12
-rw-r--r--build/config/operation.cxx8
-rw-r--r--build/file.cxx57
-rw-r--r--build/parser.cxx106
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, "<buildspec>");
}
- 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;