[PATCH v5 07/15] config: Look up log color configuration in configuration file

Barnabás Pőcze pobrn at protonmail.com
Wed Dec 4 18:45:02 CET 2024


Hi


2024. október 1., kedd 12:27 keltezéssel, Milan Zamazal <mzamazal at redhat.com> írta:

> The configuration snippet:
> 
>   configuration:
>     log:
>       color: BOOL
> 
> In order to use the global configuration access helper for a boolean
> value, we must make a template from it.  To make the template visible,
> we must implement it in the header file, otherwise undefined reference
> error would be reported when linking.
> 
> We don't implement envOption helper for boolean here, because we would
> have to deal with a specific value interpretation in this particular
> case.
> 
> Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
> ---
>  .../libcamera/internal/global_configuration.h | 27 ++++++++++++++++++-
>  src/libcamera/base/global_configuration.cpp   | 20 ++++----------
>  src/libcamera/base/log.cpp                    |  2 ++
>  3 files changed, 33 insertions(+), 16 deletions(-)
> 
> diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h
> index b1529f392..d34410744 100644
> --- a/include/libcamera/internal/global_configuration.h
> +++ b/include/libcamera/internal/global_configuration.h
> @@ -12,6 +12,8 @@
>  #include <string>
>  #include <vector>
> 
> +#include <libcamera/base/utils.h>
> +
>  #include "libcamera/internal/yaml_parser.h"
> 
>  namespace libcamera {
> @@ -27,7 +29,30 @@ public:
> 
>  	static unsigned int version();
>  	static Configuration configuration();
> -	static std::optional<std::string> option(const std::string &confPath);
> +
> +	template<typename T,
> +		 std::enable_if_t<
> +			 std::is_same_v<bool, T> ||
> +			 std::is_same_v<double, T> ||
> +			 std::is_same_v<int8_t, T> ||
> +			 std::is_same_v<uint8_t, T> ||
> +			 std::is_same_v<int16_t, T> ||
> +			 std::is_same_v<uint16_t, T> ||
> +			 std::is_same_v<int32_t, T> ||
> +			 std::is_same_v<uint32_t, T> ||
> +			 std::is_same_v<std::string, T> ||
> +			 std::is_same_v<Size, T>> * = nullptr>
> +	static std::optional<T> option(const std::string &confPath)
> +	{
> +		YamlObject *c = &const_cast<YamlObject &>(configuration());

Why are the `const_cast`s needed?


> +		for (auto part : utils::details::StringSplitter(confPath, "."))

utils::split(...)


> +			if (c->contains(part))

You can get rid of this check, e.g.

  for (...) {
    c = &(*c)[part];
    if (!*c)
      return {};
  }

It does not look particularly aestethic, though...


> +				c = &const_cast<YamlObject &>((*c)[part]);
> +			else
> +				return std::optional<T>();
> +		return c->get<T>();
> +	}
> +
>  	static std::optional<std::string> envOption(const char *const envVariable,
>  						    const std::string &confPath);
> 
> diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp
> index 1243a5f4e..82d1339c3 100644
> --- a/src/libcamera/base/global_configuration.cpp
> +++ b/src/libcamera/base/global_configuration.cpp
> @@ -14,7 +14,6 @@
> 
>  #include <libcamera/base/file.h>
>  #include <libcamera/base/log.h>
> -#include <libcamera/base/utils.h>
> 
>  #include "libcamera/internal/yaml_parser.h"
> 
> @@ -150,23 +149,14 @@ GlobalConfiguration::Configuration GlobalConfiguration::get()
>  }
> 
>  /**
> + * \fn static std::optional<T> GlobalConfiguration::option(const char *const confPath)
>   * \brief Return value of the configuration option identified by \a confPath
> + * \tparam T The type of the retrieved configuration value
>   * \param[in] confPath Sequence of the YAML section names (excluding
>   * `configuration') leading to the requested option separated by dots
> - * \return A value if an item corresponding to \a confPath exists in the
> - * configuration file, no value otherwise
> + * \return A value of type \a T if an item corresponding to \a confPath exists
> + * in the configuration file and matches type \a T, no value otherwise
>   */
> -std::optional<std::string> GlobalConfiguration::option(
> -	const std::string &confPath)
> -{
> -	YamlObject *c = &const_cast<YamlObject &>(configuration());
> -	for (auto part : utils::details::StringSplitter(confPath, "."))
> -		if (c->contains(part))
> -			c = &const_cast<YamlObject &>((*c)[part]);
> -		else
> -			return std::optional<std::string>();
> -	return c->get<std::string>();
> -}
> 
>  /**
>   * \brief Return value of the configuration option from a file or environment
> @@ -192,7 +182,7 @@ std::optional<std::string> GlobalConfiguration::envOption(
>  	const char *envValue = utils::secure_getenv(envVariable);
>  	if (envValue)
>  		return std::optional{ std::string{ envValue } };
> -	return option(confPath);
> +	return option<std::string>(confPath);
>  }
> 
>  /**
> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> index 07352f6c1..d522e895e 100644
> --- a/src/libcamera/base/log.cpp
> +++ b/src/libcamera/base/log.cpp
> @@ -590,6 +590,8 @@ void Logger::logSetLevel(const char *category, const char *level)
>  Logger::Logger()
>  {
>  	bool color = !utils::secure_getenv("LIBCAMERA_LOG_NO_COLOR");
> +	if (color)
> +		color = GlobalConfiguration::option<bool>("log.color").value_or(true);
>  	logSetStream(&std::cerr, color);
> 
>  	parseLogFile();
> --
> 2.44.1
> 
> 


Regards,
Barnabás Pőcze


More information about the libcamera-devel mailing list