diff options
-rw-r--r-- | bdep/new-parsers.cxx | 25 | ||||
-rw-r--r-- | bdep/new-parsers.hxx | 3 | ||||
-rw-r--r-- | bdep/new-types.hxx | 47 | ||||
-rw-r--r-- | bdep/new-types.ixx | 64 | ||||
-rw-r--r-- | tests/new.testscript | 151 |
5 files changed, 181 insertions, 109 deletions
diff --git a/bdep/new-parsers.cxx b/bdep/new-parsers.cxx index f8a8c75..7a12132 100644 --- a/bdep/new-parsers.cxx +++ b/bdep/new-parsers.cxx @@ -15,11 +15,11 @@ namespace bdep using vcs = cmd_new_vcs; // Parse comma-separated list of of options starting from the first comma - // at pos. + // at pos, merging them with options parsed previously. // template <typename O> - static O - parse_options (const char* o, const string v, size_t pos) + static void + parse_options (const char* o, const string v, size_t pos, O& r) { // Use vector_scanner to parse the comma-separated list of // parameter-specific options. Make sure that option values are only @@ -73,10 +73,7 @@ namespace bdep } vector_scanner s (os); - - O r; r.parse (s); - return r; } void parser<type>:: @@ -94,22 +91,22 @@ namespace bdep if (l == "exe") { r.type = type::exe; - r.exe_opt = parse_options<cmd_new_exe_options> (o, v, i); + parse_options<cmd_new_exe_options> (o, v, i, r.exe_opt); } else if (l == "lib") { r.type = type::lib; - r.lib_opt = parse_options<cmd_new_lib_options> (o, v, i); + parse_options<cmd_new_lib_options> (o, v, i, r.lib_opt); } else if (l == "bare") { r.type = type::bare; - r.bare_opt = parse_options<cmd_new_bare_options> (o, v, i); + parse_options<cmd_new_bare_options> (o, v, i, r.bare_opt); } else if (l == "empty") { r.type = type::empty; - r.empty_opt = parse_options<cmd_new_empty_options> (o, v, i); + parse_options<cmd_new_empty_options> (o, v, i, r.empty_opt); } else throw invalid_value (o, l); @@ -132,12 +129,12 @@ namespace bdep if (l == "c") { r.lang = lang::c; - r.c_opt = parse_options<cmd_new_c_options> (o, v, i); + parse_options<cmd_new_c_options> (o, v, i, r.c_opt); } else if (l == "c++") { r.lang = lang::cxx; - r.cxx_opt = parse_options<cmd_new_cxx_options> (o, v, i); + parse_options<cmd_new_cxx_options> (o, v, i, r.cxx_opt); } else throw invalid_value (o, l); @@ -160,12 +157,12 @@ namespace bdep if (l == "git") { r.vcs = vcs::git; - r.git_opt = parse_options<cmd_new_git_options> (o, v, i); + parse_options<cmd_new_git_options> (o, v, i, r.git_opt); } else if (l == "none") { r.vcs = vcs::none; - r.none_opt = parse_options<cmd_new_none_options> (o, v, i); + parse_options<cmd_new_none_options> (o, v, i, r.none_opt); } else throw invalid_value (o, l); diff --git a/bdep/new-parsers.hxx b/bdep/new-parsers.hxx index e771369..0bc6d56 100644 --- a/bdep/new-parsers.hxx +++ b/bdep/new-parsers.hxx @@ -16,6 +16,9 @@ namespace bdep { class scanner; + // Note that these parsers merge parameter-specific options rather + // than overwriting them (see new-types.hxx for details). + // template <typename T> struct parser; diff --git a/bdep/new-types.hxx b/bdep/new-types.hxx index 0f36e42..9d19c48 100644 --- a/bdep/new-types.hxx +++ b/bdep/new-types.hxx @@ -12,6 +12,13 @@ namespace bdep // We could have defined cmd_new_*_options in a separate .cli file, include // that here, and so on. Or we can abuse templates and keep everything // together. + // + // Note that these types are designed to accumulate sub-options from the + // options specified on the command line (or in option files) multiple + // times, with the last one serving as a "selector". This, in particular, + // will be useful for specifying custom project creation defaults in the + // configuration files. + // // --type // @@ -30,17 +37,14 @@ namespace bdep operator type_type () const {return type;} - union - { - EXE exe_opt; - LIB lib_opt; - BARE bare_opt; - EMPTY empty_opt; - }; + EXE exe_opt; + LIB lib_opt; + BARE bare_opt; + EMPTY empty_opt; // Default is exe with no options. // - cmd_new_type_template (): type (exe) {exe_opt = EXE ();} + cmd_new_type_template (): type (exe) {} friend ostream& operator<< (ostream& os, const cmd_new_type_template& t) @@ -74,22 +78,12 @@ namespace bdep operator lang_type () const {return lang;} - union - { - C c_opt; - CXX cxx_opt; - }; + C c_opt; + CXX cxx_opt; // Default is C++ with no options. // - cmd_new_lang_template (): lang (cxx), cxx_opt (CXX ()) {} - - cmd_new_lang_template (cmd_new_lang_template&&); - cmd_new_lang_template (const cmd_new_lang_template&); - cmd_new_lang_template& operator= (cmd_new_lang_template&&); - cmd_new_lang_template& operator= (const cmd_new_lang_template&); - - ~cmd_new_lang_template (); + cmd_new_lang_template (): lang (cxx) {} }; using cmd_new_lang = cmd_new_lang_template<>; @@ -107,20 +101,15 @@ namespace bdep operator vcs_type () const {return vcs;} - union - { - GIT git_opt; - NONE none_opt; - }; + GIT git_opt; + NONE none_opt; // Default is git with no options. // - cmd_new_vcs_template (): vcs (git) {git_opt = GIT ();} + cmd_new_vcs_template (): vcs (git) {} }; using cmd_new_vcs = cmd_new_vcs_template<>; } -#include <bdep/new-types.ixx> - #endif // BDEP_NEW_TYPES_HXX diff --git a/bdep/new-types.ixx b/bdep/new-types.ixx deleted file mode 100644 index a8eafc5..0000000 --- a/bdep/new-types.ixx +++ /dev/null @@ -1,64 +0,0 @@ -// file : bdep/new-types.ixx -*- C++ -*- -// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <bdep/utility.hxx> // move() - -namespace bdep -{ - template <typename C, typename CXX> - inline cmd_new_lang_template<C, CXX>:: - ~cmd_new_lang_template () - { - if (lang == c) - c_opt.~C (); - else - cxx_opt.~CXX (); - } - - template <typename C, typename CXX> - inline cmd_new_lang_template<C, CXX>:: - cmd_new_lang_template (cmd_new_lang_template&& l): lang (l.lang) - { - if (lang == c) - new (&c_opt) C (move (l.c_opt)); - else - new (&cxx_opt) CXX (move (l.cxx_opt)); - } - - template <typename C, typename CXX> - inline cmd_new_lang_template<C, CXX>:: - cmd_new_lang_template (const cmd_new_lang_template& l): lang (l.lang) - { - if (lang == c) - new (&c_opt) C (l.c_opt); - else - new (&cxx_opt) CXX (l.cxx_opt); - } - - template <typename C, typename CXX> - inline cmd_new_lang_template<C, CXX>& cmd_new_lang_template<C, CXX>:: - operator= (cmd_new_lang_template&& l) - { - if (this != &l) - { - this->~cmd_new_lang_template<C, CXX> (); - - // Assume noexcept move-construction. - // - new (this) cmd_new_lang_template<C, CXX> (move (l)); - } - - return *this; - } - - template <typename C, typename CXX> - inline cmd_new_lang_template<C, CXX>& cmd_new_lang_template<C, CXX>:: - operator= (const cmd_new_lang_template& l) - { - if (this != &l) - *this = cmd_new_lang_template<C, CXX> (l); // Reduce to move-assignment. - - return *this; - } -} diff --git a/tests/new.testscript b/tests/new.testscript index 6662eee..a1eaecf 100644 --- a/tests/new.testscript +++ b/tests/new.testscript @@ -395,13 +395,18 @@ status += -d prj created new library project libprj in $~/libprj/ EOE - sed -n -e 's/(.*\bixx\b.*)/\1/p' libprj/build/root.build >>EOO; + cat libprj/build/root.build >>~%EOO%; + %.+ ixx{*}: extension = ixx + %.+ EOO - sed -n -e 's/(.*\bixx\b.*)/\1/p' libprj/libprj/buildfile >>~%EOO%; + cat libprj/libprj/buildfile >>~%EOO%; + %.+ %.*\{hxx ixx cxx\}.*% + %.+ {hxx ixx}{*}: + %.+ EOO $build libprj/ $cxx 2>>~%EOE% @@ -424,6 +429,20 @@ status += -d prj EOE } + : merge + { + $* -t lib -l c++,cxx=cpp -l c -l c++,hxx=hpp libprj 2>>/"EOE" &libprj/***; + created new library project libprj in $~/libprj/ + EOE + + test -f libprj/libprj/prj.cpp; + test -f libprj/libprj/prj.hpp; + + $build libprj/ $cxx 2>>~%EOE% + %(version\.in|c\+\+|ar|ld) .+%{7} + EOE + } + : errors : { @@ -464,6 +483,134 @@ status += -d prj EOE } } + + : options-file + : + { + +cat <<EOI >=options + --type exe,no-tests,unit-tests + --type lib,no-version + --type bare,alt-naming + --lang c++,cpp + --lang c + --vcs none + EOI + + test.arguments += --options-file $~/options + + : type + : + { + : exe + : + { + $* -t exe prj 2>>/"EOE" &prj/***; + created new executable project prj in $~/prj/ + EOE + + test -f prj/buildfile; + test -f prj/prj/testscript == 1; + + cat prj/prj/buildfile >>~%EOO%; + %.+ + %for t: c\{\*\*.test...\}%d + %.+ + EOO + + $build prj/ $cxx 2>>~%EOE% + %(c|ar|ld) .+%{5} + EOE + } + + : lib + : + { + $* -t lib libprj 2>>/"EOE" &libprj/***; + created new library project libprj in $~/libprj/ + EOE + + test -f libprj/buildfile; + test -f libprj/libprj/version.h.in == 1; + + $build libprj/ $cxx 2>>~%EOE% + %(c|ar|ld) .+%{6} + EOE + } + + : bare + : + { + $* -t bare libprj 2>>/"EOE" &libprj/***; + created new bare project libprj in $~/libprj/ + EOE + + test -f libprj/build2file; + test -d libprj/libprj == 1; + + $build libprj/ $cxx 2>>~%EOE% + %info: .+ is up to date% + EOE + } + + : empty + : + { + $* -t empty libprj 2>>/"EOE" &libprj/*** + created new empty project libprj in $~/libprj/ + EOE + } + } + + : lang + : + { + test.arguments += -t lib + + : c++ + : + { + $* -l c++,hxx= libprj 2>>/"EOE" &libprj/***; + created new library project libprj in $~/libprj/ + EOE + + test -f libprj/libprj/prj; + test -f libprj/libprj/prj.cpp; + + $build libprj/ $cxx 2>>~%EOE% + %(c\+\+|ar|ld) .+%{6} + EOE + } + + : c + : + { + $* -l c libprj 2>>/"EOE" &libprj/***; + created new library project libprj in $~/libprj/ + EOE + + test -f libprj/libprj/prj.h; + test -f libprj/libprj/prj.c; + + $build libprj/ $cxx 2>>~%EOE% + %(c|ar|ld) .+%{6} + EOE + } + } + + : vcs + : + { + : git + : + { + $* -s git prj 2>>/"EOE" &prj/***; + created new bare project prj in $~/prj/ + EOE + + test -d prj/.git + } + } + } } : cfg |