From d3e624ef7c0fb274e62b81c4c7bd59640770520a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 5 Jan 2015 15:03:39 +0200 Subject: Rename 'bd' to 'b' What the heck, let's be bold, right? --- build/.gitignore | 5 +- build/b.cxx | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ build/bd.cxx | 299 ------------------------------------------------------- build/buildfile | 4 +- 4 files changed, 305 insertions(+), 302 deletions(-) create mode 100644 build/b.cxx delete mode 100644 build/bd.cxx diff --git a/build/.gitignore b/build/.gitignore index 1683c0f..6dc02d1 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1 +1,4 @@ -bd +b +b1 + + diff --git a/build/b.cxx b/build/b.cxx new file mode 100644 index 0000000..a5123f1 --- /dev/null +++ b/build/b.cxx @@ -0,0 +1,299 @@ +// file : build/b.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include // tzset() +#include // strerror() + +#include // getenv() +#include // getuid() +#include // uid_t +#include // struct passwd, getpwuid() + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; + +namespace build +{ + bool + match_recursive (target& t) + { + // Because we match the target first and then prerequisites, + // any additional dependency information injected by the rule + // will be covered as well. + // + if (!t.recipe ()) + { + if (!match (t)) + { + cerr << "error: no rule to update target " << t << endl; + return false; + } + } + + for (prerequisite& p: t.prerequisites) + { + // Resolve prerequisite to target (prerequisite search). We + // do this after matching since the rule can alter search + // paths. + // + if (p.target == nullptr) + search (p); + + if (!match_recursive (*p.target)) + { + cerr << "info: required by " << t << endl; + return false; + } + } + + return true; + } + + target_state + update (target& t) + { + assert (t.state () == target_state::unknown); + + target_state ts; + + for (prerequisite& p: t.prerequisites) + { + target& pt (*p.target); + + if (pt.state () == target_state::unknown) + { + pt.state ((ts = update (pt))); + + if (ts == target_state::failed) + return ts; + } + } + + const recipe& r (t.recipe ()); + + { + auto g ( + make_exception_guard ( + [] (target& t) + { + cerr << "info: while building target " << t << endl; + }, + t)); + + ts = r (t); + } + + assert (ts != target_state::unknown); + t.state (ts); + return ts; + } + + void + dump () + { + for (const auto& pt: targets) + { + target& t (*pt); + + cout << t << ':'; + + for (const auto& p: t.prerequisites) + { + cout << ' ' << p; + } + + cout << endl; + } + } + +} + +#include + +#include +#include + + +using namespace build; + +int +main (int argc, char* argv[]) +{ + // Initialize time conversion data that is used by localtime_r(). + // + tzset (); + + // Register target types. + // + target_types.insert (file::static_type); + + target_types.insert (exe::static_type); + target_types.insert (obj::static_type); + + target_types.insert (cxx::cxx::static_type); + target_types.insert (cxx::hxx::static_type); + target_types.insert (cxx::ixx::static_type); + target_types.insert (cxx::txx::static_type); + + // Figure out directories: work, home, and {src,out}_{root,base}. + // + work = path::current (); + + if (const char* h = getenv ("HOME")) + home = path (h); + else + { + struct passwd* pw (getpwuid (getuid ())); + + if (pw == nullptr) + { + const char* msg (strerror (errno)); + cerr << "error: unable to determine home directory: " << msg << endl; + return 1; + } + + home = path (pw->pw_dir); + } + + //@@ Must be normalized. + // + out_base = work; + src_base = out_base; + + // The project's root directory is the one that contains the build/ + // sub-directory which contains the pre.build file. + // + for (path d (src_base); !d.root () && d != home; d = d.directory ()) + { + path f (d / path ("build/pre.build")); + if (path_mtime (f) != timestamp_nonexistent) + { + src_root = d; + break; + } + } + + if (src_root.empty ()) + { + src_root = src_base; + out_root = out_base; + } + else + out_root = out_base.directory (src_base.leaf (src_root)); + + cerr << "work dir: " << work << endl; + cerr << "home dir: " << home << endl; + cerr << "out_base: " << out_base << endl; + cerr << "src_base: " << src_base << endl; + cerr << "out_root: " << out_root << endl; + cerr << "src_root: " << src_root << endl; + + // Parse buildfile. + // + path bf ("buildfile"); + + ifstream ifs (bf.string ().c_str ()); + if (!ifs.is_open ()) + { + cerr << "error: unable to open " << bf << " in read mode" << endl; + return 1; + } + + ifs.exceptions (ifstream::failbit | ifstream::badbit); + parser p (cerr); + + try + { + p.parse (ifs, bf, scopes[path::current ()]); + } + catch (const lexer_error&) + { + return 1; // Diagnostics has already been issued. + } + catch (const parser_error&) + { + return 1; // Diagnostics has already been issued. + } + catch (const std::ios_base::failure&) + { + cerr << "error: failed to read from " << bf << endl; + return 1; + } + + dump (); + + // Register rules. + // + cxx::link cxx_link; + rules.emplace (typeid (exe), cxx_link); + + cxx::compile cxx_compile; + rules.emplace (typeid (obj), cxx_compile); + + default_path_rule path_exists; + rules.emplace (typeid (path_target), path_exists); + + // Build. + // + if (default_target == nullptr) + { + cerr << "error: no default target" << endl; + return 1; + } + + try + { + target& d (*default_target); + + if (!match_recursive (d)) + return 1; // Diagnostics has already been issued. + + //dump (); + + switch (update (d)) + { + case target_state::uptodate: + { + cerr << "info: target " << d << " is up to date" << endl; + break; + } + case target_state::updated: + break; + case target_state::failed: + { + cerr << "error: failed to update target " << d << endl; + return 1; + } + case target_state::unknown: + assert (false); + } + } + catch (const error&) + { + return 1; // Diagnostics has already been issued. + } + catch (const std::exception& e) + { + cerr << "error: " << e.what () << endl; + return 1; + } +} diff --git a/build/bd.cxx b/build/bd.cxx deleted file mode 100644 index 394665a..0000000 --- a/build/bd.cxx +++ /dev/null @@ -1,299 +0,0 @@ -// file : build/bd.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC -// license : MIT; see accompanying LICENSE file - -#include // tzset() -#include // strerror() - -#include // getenv() -#include // getuid() -#include // uid_t -#include // struct passwd, getpwuid() - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace std; - -namespace build -{ - bool - match_recursive (target& t) - { - // Because we match the target first and then prerequisites, - // any additional dependency information injected by the rule - // will be covered as well. - // - if (!t.recipe ()) - { - if (!match (t)) - { - cerr << "error: no rule to update target " << t << endl; - return false; - } - } - - for (prerequisite& p: t.prerequisites) - { - // Resolve prerequisite to target (prerequisite search). We - // do this after matching since the rule can alter search - // paths. - // - if (p.target == nullptr) - search (p); - - if (!match_recursive (*p.target)) - { - cerr << "info: required by " << t << endl; - return false; - } - } - - return true; - } - - target_state - update (target& t) - { - assert (t.state () == target_state::unknown); - - target_state ts; - - for (prerequisite& p: t.prerequisites) - { - target& pt (*p.target); - - if (pt.state () == target_state::unknown) - { - pt.state ((ts = update (pt))); - - if (ts == target_state::failed) - return ts; - } - } - - const recipe& r (t.recipe ()); - - { - auto g ( - make_exception_guard ( - [] (target& t) - { - cerr << "info: while building target " << t << endl; - }, - t)); - - ts = r (t); - } - - assert (ts != target_state::unknown); - t.state (ts); - return ts; - } - - void - dump () - { - for (const auto& pt: targets) - { - target& t (*pt); - - cout << t << ':'; - - for (const auto& p: t.prerequisites) - { - cout << ' ' << p; - } - - cout << endl; - } - } - -} - -#include - -#include -#include - - -using namespace build; - -int -main (int argc, char* argv[]) -{ - // Initialize time conversion data that is used by localtime_r(). - // - tzset (); - - // Register target types. - // - target_types.insert (file::static_type); - - target_types.insert (exe::static_type); - target_types.insert (obj::static_type); - - target_types.insert (cxx::cxx::static_type); - target_types.insert (cxx::hxx::static_type); - target_types.insert (cxx::ixx::static_type); - target_types.insert (cxx::txx::static_type); - - // Figure out directories: work, home, and {src,out}_{root,base}. - // - work = path::current (); - - if (const char* h = getenv ("HOME")) - home = path (h); - else - { - struct passwd* pw (getpwuid (getuid ())); - - if (pw == nullptr) - { - const char* msg (strerror (errno)); - cerr << "error: unable to determine home directory: " << msg << endl; - return 1; - } - - home = path (pw->pw_dir); - } - - //@@ Must be normalized. - // - out_base = work; - src_base = out_base; - - // The project's root directory is the one that contains the build/ - // sub-directory which contains the pre.build file. - // - for (path d (src_base); !d.root () && d != home; d = d.directory ()) - { - path f (d / path ("build/pre.build")); - if (path_mtime (f) != timestamp_nonexistent) - { - src_root = d; - break; - } - } - - if (src_root.empty ()) - { - src_root = src_base; - out_root = out_base; - } - else - out_root = out_base.directory (src_base.leaf (src_root)); - - cerr << "work dir: " << work << endl; - cerr << "home dir: " << home << endl; - cerr << "out_base: " << out_base << endl; - cerr << "src_base: " << src_base << endl; - cerr << "out_root: " << out_root << endl; - cerr << "src_root: " << src_root << endl; - - // Parse buildfile. - // - path bf ("buildfile"); - - ifstream ifs (bf.string ().c_str ()); - if (!ifs.is_open ()) - { - cerr << "error: unable to open " << bf << " in read mode" << endl; - return 1; - } - - ifs.exceptions (ifstream::failbit | ifstream::badbit); - parser p (cerr); - - try - { - p.parse (ifs, bf, scopes[path::current ()]); - } - catch (const lexer_error&) - { - return 1; // Diagnostics has already been issued. - } - catch (const parser_error&) - { - return 1; // Diagnostics has already been issued. - } - catch (const std::ios_base::failure&) - { - cerr << "error: failed to read from " << bf << endl; - return 1; - } - - dump (); - - // Register rules. - // - cxx::link cxx_link; - rules.emplace (typeid (exe), cxx_link); - - cxx::compile cxx_compile; - rules.emplace (typeid (obj), cxx_compile); - - default_path_rule path_exists; - rules.emplace (typeid (path_target), path_exists); - - // Build. - // - if (default_target == nullptr) - { - cerr << "error: no default target" << endl; - return 1; - } - - try - { - target& d (*default_target); - - if (!match_recursive (d)) - return 1; // Diagnostics has already been issued. - - //dump (); - - switch (update (d)) - { - case target_state::uptodate: - { - cerr << "info: target " << d << " is up to date" << endl; - break; - } - case target_state::updated: - break; - case target_state::failed: - { - cerr << "error: failed to update target " << d << endl; - return 1; - } - case target_state::unknown: - assert (false); - } - } - catch (const error&) - { - return 1; // Diagnostics has already been issued. - } - catch (const std::exception& e) - { - cerr << "error: " << e.what () << endl; - return 1; - } -} diff --git a/build/buildfile b/build/buildfile index 8bd80b7..88ea4d6 100644 --- a/build/buildfile +++ b/build/buildfile @@ -1,7 +1,7 @@ -exe{bd1}: obj{bd algorithm scope parser lexer target prerequisite rule \ +exe{b1}: obj{b algorithm scope parser lexer target prerequisite rule \ native context cxx/target cxx/rule process timestamp path} -obj{bd}: cxx{bd} +obj{b}: cxx{b} obj{algorithm}: cxx{algorithm} obj{scope}: cxx{scope} obj{parser}: cxx{parser} -- cgit v1.1