From d5c6314f1af3d780a4e8e40f9e134e7b8dfdccf3 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 23 Jun 2022 10:24:06 -0700 Subject: [PATCH] ircd: Split info::versions into header/unit. --- include/ircd/info.h | 82 +---------------------------------- include/ircd/ircd.h | 1 + include/ircd/versions.h | 95 +++++++++++++++++++++++++++++++++++++++++ ircd/Makefile.am | 1 + ircd/info.cc | 84 ------------------------------------ ircd/versions.cc | 93 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 192 insertions(+), 164 deletions(-) create mode 100644 include/ircd/versions.h create mode 100644 ircd/versions.cc diff --git a/include/ircd/info.h b/include/ircd/info.h index 48d52e504..53d78379f 100644 --- a/include/ircd/info.h +++ b/include/ircd/info.h @@ -19,8 +19,7 @@ extern "C" const char *const ircd_version; /// Information & metadata about the library. namespace ircd::info { - struct line; - struct versions; + using ircd::versions; // Util void dump(); @@ -125,7 +124,7 @@ namespace ircd::info::hardware::x86 extern const bool sse, sse2, sse3, ssse3, sse4a, sse4_1, sse4_2; extern const bool avx, avx2, avx512f; extern const bool tsc, tsc_constant; -}; +} namespace ircd::info::hardware::arm { @@ -137,81 +136,4 @@ namespace ircd::info::hardware::arm extern const uint64_t ctr; extern const string_view vendor; -}; - -/// Instances of `versions` create a dynamic version registry identifying -/// third-party dependencies throughout the project and its loaded modules. -/// -/// Create a static instance of this class in a definition file or module -/// which has access to the version information of the dependency. Often there -/// can be two version identifiers for a dependency, one for headers and the -/// other for dynamically loaded shared object. In that case, create two -/// instances of this class with the same name. -/// -struct ircd::info::versions -:instance_list -{ - /// Our own name for the dependency. - string_view name; - - /// Set the type to either API or ABI to indicate where this version - /// information has been sourced. Defaults to API. - enum type {API, ABI} type {API}; - - /// If the version number is a single (likely monotonic) integer. - long monotonic {0}; - - /// Alternative semantic version number. - std::array semantic {0}; - - /// Version string buffer. Copy any provided version string here. - char string[128] {0}; - - /// Convenience access to read the semantic version numbers. - auto &operator[](const int &idx) const; - - /// Convenience access to read the monotonic integer; note that if zero - /// the semantic major number is read instead. - explicit operator const long &() const; - - /// Convenience access to read the string - explicit operator string_view() const; - - versions(const string_view &name, - const enum type &type = type::API, - const long &monotonic = 0, - const std::array &semantic = {0L}, - const string_view &string = {}); - - versions(const string_view &name, - const enum type &type, - const long &monotonic, - const std::array &semantic, - const std::function &generator); - - versions() = default; - versions(versions &&) = delete; - versions(const versions &) = delete; - ~versions() noexcept; -}; - -inline ircd::info::versions::operator -const long &() -const -{ - return monotonic?: semantic[0]; -} - -inline ircd::info::versions::operator -ircd::string_view() -const -{ - return string; -} - -inline auto & -ircd::info::versions::operator[](const int &idx) -const -{ - return semantic.at(idx); } diff --git a/include/ircd/ircd.h b/include/ircd/ircd.h index fee9da501..6aa92c345 100644 --- a/include/ircd/ircd.h +++ b/include/ircd/ircd.h @@ -57,6 +57,7 @@ #include "run.h" #include "demangle.h" #include "backtrace.h" +#include "versions.h" #include "info.h" #include "logger.h" #include "stringops.h" diff --git a/include/ircd/versions.h b/include/ircd/versions.h new file mode 100644 index 000000000..4ed8c4d57 --- /dev/null +++ b/include/ircd/versions.h @@ -0,0 +1,95 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2022 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + + +#pragma once +#define HAVE_IRCD_VERSIONS_H + +namespace ircd +{ + struct versions; +} + +/// Instances of `versions` create a dynamic version registry identifying +/// third-party dependencies throughout the project and its loaded modules. +/// +/// Create a static instance of this class in a definition file or module +/// which has access to the version information of the dependency. Often there +/// can be two version identifiers for a dependency, one for headers and the +/// other for dynamically loaded shared object. In that case, create two +/// instances of this class with the same name. +/// +struct ircd::versions +:instance_list +{ + /// Our own name for the dependency. + string_view name; + + /// Set the type to either API or ABI to indicate where this version + /// information has been sourced. Defaults to API. + enum type {API, ABI} type {API}; + + /// If the version number is a single (likely monotonic) integer. + long monotonic {0}; + + /// Alternative semantic version number. + std::array semantic {0}; + + /// Version string buffer. Copy any provided version string here. + char string[128] {0}; + + /// Convenience access to read the semantic version numbers. + auto &operator[](const int &idx) const; + + /// Convenience access to read the monotonic integer; note that if zero + /// the semantic major number is read instead. + explicit operator const long &() const; + + /// Convenience access to read the string + explicit operator string_view() const; + + versions(const string_view &name, + const enum type &type = type::API, + const long &monotonic = 0, + const std::array &semantic = {0L}, + const string_view &string = {}); + + versions(const string_view &name, + const enum type &type, + const long &monotonic, + const std::array &semantic, + const std::function &generator); + + versions() = default; + versions(versions &&) = delete; + versions(const versions &) = delete; + ~versions() noexcept; +}; + +inline ircd::versions::operator +const long &() +const +{ + return monotonic?: semantic[0]; +} + +inline ircd::versions::operator +ircd::string_view() +const +{ + return string; +} + +inline auto & +ircd::versions::operator[](const int &idx) +const +{ + return semantic.at(idx); +} diff --git a/ircd/Makefile.am b/ircd/Makefile.am index 71a43130a..987048e00 100644 --- a/ircd/Makefile.am +++ b/ircd/Makefile.am @@ -160,6 +160,7 @@ libircd_la_SOURCES += simd.cc libircd_la_SOURCES += fpe.cc libircd_la_SOURCES += parse.cc libircd_la_SOURCES += lex_cast.cc +libircd_la_SOURCES += versions.cc libircd_la_SOURCES += info.cc libircd_la_SOURCES += allocator.cc libircd_la_SOURCES += allocator_gnu.cc diff --git a/ircd/info.cc b/ircd/info.cc index 27b080451..338190e9c 100644 --- a/ircd/info.cc +++ b/ircd/info.cc @@ -52,90 +52,6 @@ ircd::info::dump() fpe::debug_info(); } -// -// Version registry -// - -template<> -decltype(ircd::util::instance_list::allocator) -ircd::util::instance_list::allocator -{}; - -template<> -decltype(ircd::util::instance_list::list) -ircd::util::instance_list::list -{ - allocator -}; - -/// Straightforward construction of versions members; string is copied -/// into member buffer with null termination. -ircd::info::versions::versions(const string_view &name, - const enum type &type, - const long &monotonic, - const std::array &semantic, - const string_view &string) -:versions -{ - name, type, monotonic, semantic, [&string] - (auto &that, const mutable_buffer &buf) - { - strlcpy(buf, string); - } -} -{ -} - -/// Construction of versions members with closure for custom string generation. -/// The version string must be stored into buffer with null termination. -ircd::info::versions::versions(const string_view &name, - const enum type &type, - const long &monotonic, - const std::array &semantic, - const std::function &closure) -:name{name} -,type{type} -,monotonic{monotonic} -,semantic{semantic} -,string{'\0'} -{ - if(closure) try - { - closure(*this, this->string); - } - catch(const std::exception &e) - { - log::error - { - "Querying %s version of '%s' :%s", - type == type::ABI? "ABI"_sv : "API"_sv, - name, - e.what(), - }; - } - - // User provided a string already; nothing else to do - if(strnlen(this->string, sizeof(this->string)) != 0) - return; - - // Generate a string from the semantic version number or if all zeroes - // from the monotonic version number instead. - if(!this->semantic[0] && !this->semantic[1] && !this->semantic[2]) - ::snprintf(this->string, sizeof(this->string), "%ld", - this->monotonic); - else - ::snprintf(this->string, sizeof(this->string), "%ld.%ld.%ld", - this->semantic[0], - this->semantic[1], - this->semantic[2]); -} - -// Required for instance_list template instantiation. -ircd::info::versions::~versions() -noexcept -{ -} - /////////////////////////////////////////////////////////////////////////////// // // Hardware / Platform diff --git a/ircd/versions.cc b/ircd/versions.cc new file mode 100644 index 000000000..72aa571a2 --- /dev/null +++ b/ircd/versions.cc @@ -0,0 +1,93 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2022 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +// +// Version registry +// + +template<> +decltype(ircd::util::instance_list::allocator) +ircd::util::instance_list::allocator +{}; + +template<> +decltype(ircd::util::instance_list::list) +ircd::util::instance_list::list +{ + allocator +}; + +/// Straightforward construction of versions members; string is copied +/// into member buffer with null termination. +ircd::versions::versions(const string_view &name, + const enum type &type, + const long &monotonic, + const std::array &semantic, + const string_view &string) +:versions +{ + name, type, monotonic, semantic, [&string] + (auto &that, const mutable_buffer &buf) + { + strlcpy(buf, string); + } +} +{ +} + +/// Construction of versions members with closure for custom string generation. +/// The version string must be stored into buffer with null termination. +ircd::versions::versions(const string_view &name, + const enum type &type, + const long &monotonic, + const std::array &semantic, + const std::function &closure) +:name{name} +,type{type} +,monotonic{monotonic} +,semantic{semantic} +,string{'\0'} +{ + if(closure) try + { + closure(*this, this->string); + } + catch(const std::exception &e) + { + log::error + { + "Querying %s version of '%s' :%s", + type == type::ABI? "ABI"_sv : "API"_sv, + name, + e.what(), + }; + } + + // User provided a string already; nothing else to do + if(strnlen(this->string, sizeof(this->string)) != 0) + return; + + // Generate a string from the semantic version number or if all zeroes + // from the monotonic version number instead. + if(!this->semantic[0] && !this->semantic[1] && !this->semantic[2]) + ::snprintf(this->string, sizeof(this->string), "%ld", + this->monotonic); + else + ::snprintf(this->string, sizeof(this->string), "%ld.%ld.%ld", + this->semantic[0], + this->semantic[1], + this->semantic[2]); +} + +// Required for instance_list template instantiation. +ircd::versions::~versions() +noexcept +{ +}