From b21e8818e774d7d16f799866b5e1e3768d769572 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Fri, 10 Nov 2023 22:51:03 -0500 Subject: [PATCH] Make a portable hook for getting program name. --- ProgramOptions.cc | 9 ++++----- System/programName.h | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 System/programName.h diff --git a/ProgramOptions.cc b/ProgramOptions.cc index ef247cb..461d14b 100644 --- a/ProgramOptions.cc +++ b/ProgramOptions.cc @@ -10,6 +10,8 @@ static_assert( __cplusplus > 2020'99 ); #include #include +#include + namespace Alepha::Hydrogen ::detail:: ProgramOptions_m { namespace @@ -205,9 +207,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m VariableMap substitutions= { - // This uses a GNU extension, but it's fine. We can always make this - // portable, later. - { "program-name"s, lambaste<=::program_invocation_short_name }, + { "program-name"s, lambaste<=System::programName() }, { "option-name"s, lambaste<=name }, { "default"s, [&defaultBuilder= defaultBuilder, &name= name] { @@ -283,8 +283,7 @@ namespace Alepha::Hydrogen ::detail:: ProgramOptions_m { VariableMap substitutions { - // Another use of the GNUism. - { "program-name"s, lambaste<=::program_invocation_short_name }, + { "program-name"s, lambaste<=System::programName() }, }; if( canonicalName.has_value() ) substitutions[ "canonical-name"s ]= lambaste<=canonicalName.value(); diff --git a/System/programName.h b/System/programName.h new file mode 100644 index 0000000..c7e5a2f --- /dev/null +++ b/System/programName.h @@ -0,0 +1,46 @@ +static_assert( __cplusplus > 2020'99 ); + +#pragma once + +#include + +#if defined( __FreeBSD__ ) +# include +# include +#elif defined( _GNU_SOURCE ) +#endif + +#include + +namespace Alepha::Hydrogen::System ::detail:: programName_m +{ + inline namespace exports + { + inline std::string + programName() + { + #if defined( __FreeBSD__ ) + int mib[] + { + CTL_KERN, + KERN_PROC, + KERN_PROC_PATHNAME, + -1, + }; + char buf[ 4096 ]; + std::size_t cb = sizeof( buf ); + ::sysctl( mib, 4, buf, &cb, nullptr, 0); + return buf; + #elif defined( _GNU_SOURCE ) + return ::program_invocation_short_name; + #else + #error "Not supported." + #endif + } + } +} + +namespace Alepha::Hydrogen::System::inline exports::inline programName_m +{ + using namespace detail::programName_m::exports; +}