From 723a15c5390d0c5eb42f2082fcedb7262e7bc856 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 22 Mar 2023 13:18:24 +0300 Subject: Add package_manifest::effective_type_sub_options() --- libbpkg/manifest.cxx | 28 ++++++++++++++++++---------- libbpkg/manifest.hxx | 18 +++++++++++++----- libbpkg/manifest.ixx | 12 +++++++++++- tests/manifest/driver.cxx | 18 +++++++++++++++++- tests/manifest/testscript | 20 +++++++++++++++++++- 5 files changed, 78 insertions(+), 18 deletions(-) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 8db4026..3f4b6af 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -3643,16 +3643,7 @@ namespace bpkg if (m.type) bad_name ("package type redefinition"); - // Strip the type extra information, if present. - // - size_t p (v.find (',')); - if (p != string::npos) - { - v.resize (p); - trim_right (v); - } - - if (v.empty ()) + if (v.empty () || v.find (',') == 0) bad_value ("empty package type"); m.type = move (v); @@ -4489,6 +4480,23 @@ namespace bpkg p, move (nv), function (), iu, cv, fl, *this); } + strings package_manifest:: + effective_type_sub_options (const optional& t) + { + strings r; + + if (t) + { + for (size_t b (0), e (0); next_word (*t, b, e, ','); ) + { + if (b != 0) + r.push_back (trim (string (*t, b, e - b))); + } + } + + return r; + } + optional package_manifest:: effective_description_type (bool iu) const { diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index 1d45edf..c922cc4 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -1168,12 +1168,12 @@ namespace bpkg butl::optional sha256sum; butl::optional fragment; - // Translate optional type to either `exe`, `lib`, or `other`. + // Extract the name from optional type, returning either `exe`, `lib`, or + // `other`. // - // Specifically, if type is present but is not one of the recognized - // names, then return `other`. If type is absent and the package name - // starts with the `lib` prefix, then return `lib`. Otherwise, return - // `exe`. + // Specifically, if type is present but the name is not recognized, then + // return `other`. If type is absent and the package name starts with the + // `lib` prefix, then return `lib`. Otherwise, return `exe`. // std::string effective_type () const; @@ -1181,6 +1181,14 @@ namespace bpkg static std::string effective_type (const butl::optional&, const package_name&); + // Extract sub-options from optional type. + // + strings + effective_type_sub_options () const; + + static strings + effective_type_sub_options (const butl::optional&); + // Translate the potentially empty list of languages to a non-empty one. // // Specifically, if the list of languages is not empty, then return it as diff --git a/libbpkg/manifest.ixx b/libbpkg/manifest.ixx index d6eb4a6..589d00f 100644 --- a/libbpkg/manifest.ixx +++ b/libbpkg/manifest.ixx @@ -242,7 +242,11 @@ namespace bpkg effective_type (const butl::optional& t, const package_name& n) { if (t) - return *t == "exe" || *t == "lib" ? *t : "other"; + { + std::string tp (*t, 0, t->find (',')); + butl::trim (tp); + return tp == "exe" || tp == "lib" ? tp : "other"; + } const std::string& s (n.string ()); return s.size () > 3 && s.compare (0, 3, "lib") == 0 ? "lib" : "exe"; @@ -254,6 +258,12 @@ namespace bpkg return effective_type (type, name); } + inline strings package_manifest:: + effective_type_sub_options () const + { + return effective_type_sub_options (type); + } + inline butl::small_vector package_manifest:: effective_languages (const butl::small_vector& ls, const package_name& n) diff --git a/tests/manifest/driver.cxx b/tests/manifest/driver.cxx index fb40f7e..bf97c42 100644 --- a/tests/manifest/driver.cxx +++ b/tests/manifest/driver.cxx @@ -23,6 +23,7 @@ using namespace bpkg; // argv[0] (-pp|-dp|-gp|-pr|-dr|-gr|-s) [-l] // argv[0] -p [-c] [-i] [-l] // argv[0] -ec +// argv[0] -et // argv[0] -v // // In the first form read and parse manifest list from stdin and serialize it @@ -52,7 +53,10 @@ using namespace bpkg; // roundtrip them to stdout together with their effective constraints, // calculated using version passed as an argument. // -// In the forth form print the libbpkg version to stdout and exit. +// In the forth form print the effective type and the type sub-options to +// stdout (one per line) and exit. +// +// In the fifth form print the libbpkg version to stdout and exit. // int main (int argc, char* argv[]) @@ -135,6 +139,18 @@ main (int argc, char* argv[]) cout << c << " " << ec << endl; } } + else if (mode == "-et") + { + assert (argc == 4); + + optional t (*argv[2] != '\0' ? argv[2] : optional ()); + package_name n (argv[3]); + + cout << package_manifest::effective_type (t, n) << endl; + + for (const string& so: package_manifest::effective_type_sub_options (t)) + cout << so << endl; + } else { bool long_lines (false); diff --git a/tests/manifest/testscript b/tests/manifest/testscript index 6f714ad..222d262 100644 --- a/tests/manifest/testscript +++ b/tests/manifest/testscript @@ -129,7 +129,7 @@ : 1 name: foo version: 2.0.0 - type: bash + type: bash, something extra summary: Modern C++ parser license: LGPLv2 EOO @@ -4757,3 +4757,21 @@ } } } + +: effective-type +: +{ + test.options += -et + + $* '' libfoo >'lib' : lib-prefix + $* '' foo >'exe' : no-lib-prefix + $* 'mixed' foo >'other' : other + + : lib-binless + : + $* 'lib,binless,extras' libfoo >>EOO + lib + binless + extras + EOO +} -- cgit v1.1