1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-24 00:48:53 +03:00
Files
libgpiod/bindings/cxx/line-config.cpp
Bartosz Golaszewski 76ecc337c5 licensing: relicense C++ bindings under LGPL-2.1-or-later
Commit ea84f882d5 ("licensing: relicense C++ library code under
LGPL-3.0-or-later") changed the license of C++ bindings in order to
solve potential issues with code generated from templates[1], default
implementations, etc. However this change makes the bindings less
attractive to projects that have strict licensing restrictions and avoid
GPL-3.0 code[2].

After talking to Grant Likely I decided that the best approach is to
make the bindings available under LGPL-v2.1-or-later and simply let the
end user decide which version's text to apply.

While at it: tweak the README to also mention that examples are provided
under GPL-2.0-or-later.

Link: [1] https://www.spinics.net/lists/linux-gpio/msg46605.html
Link: [2] https://github.com/brgl/libgpiod/issues/72
Suggested-by: Walter Lozano <walter.lozano@collabora.com>
Suggested-by: Grant Likely <grant.likely@linaro.org>
Acked-by: Kent Gibson <warthog618@gmail.com>
Acked-by: Kevin Hilman <khilman@baylibre.com>
Acked-by: Grant Likely <grant.likely@linaro.org>
Link: https://lore.kernel.org/r/20240416212141.6683-2-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
2024-04-22 14:04:19 +02:00

168 lines
3.8 KiB
C++

// SPDX-License-Identifier: LGPL-2.1-or-later
// SPDX-FileCopyrightText: 2021-2022 Bartosz Golaszewski <brgl@bgdev.pl>
#include <cstdlib>
#include <iterator>
#include <ostream>
#include <sstream>
#include <utility>
#include <vector>
#include "internal.hpp"
namespace gpiod {
namespace {
line_config_ptr make_line_config()
{
line_config_ptr config(::gpiod_line_config_new());
if (!config)
throw_from_errno("Unable to allocate the line config object");
return config;
}
} /* namespace */
line_config::impl::impl()
: config(make_line_config())
{
}
GPIOD_CXX_API line_config::line_config()
: _m_priv(new impl)
{
}
GPIOD_CXX_API line_config::line_config(line_config&& other) noexcept
: _m_priv(::std::move(other._m_priv))
{
}
GPIOD_CXX_API line_config::~line_config()
{
}
line_config& line_config::operator=(const line_config& other)
{
this->_m_priv = other._m_priv;
return *this;
}
GPIOD_CXX_API line_config& line_config::operator=(line_config&& other) noexcept
{
this->_m_priv = ::std::move(other._m_priv);
return *this;
}
GPIOD_CXX_API line_config& line_config::reset() noexcept
{
::gpiod_line_config_reset(this->_m_priv->config.get());
return *this;
}
GPIOD_CXX_API line_config& line_config::add_line_settings(line::offset offset,
const line_settings& settings)
{
return this->add_line_settings(line::offsets({offset}), settings);
}
GPIOD_CXX_API line_config& line_config::add_line_settings(const line::offsets& offsets,
const line_settings& settings)
{
::std::vector<unsigned int> raw_offsets(offsets.size());
for (unsigned int i = 0; i < offsets.size(); i++)
raw_offsets[i] = offsets[i];
auto ret = ::gpiod_line_config_add_line_settings(this->_m_priv->config.get(),
raw_offsets.data(), raw_offsets.size(),
settings._m_priv->settings.get());
if (ret)
throw_from_errno("unable to add line settings");
return *this;
}
GPIOD_CXX_API line_config& line_config::set_output_values(const line::values& values)
{
::std::vector<::gpiod_line_value> mapped_values(values.size());
for (unsigned int i = 0; i < values.size(); i++)
mapped_values[i] = map_output_value(values[i]);
auto ret = ::gpiod_line_config_set_output_values(this->_m_priv->config.get(),
mapped_values.data(), mapped_values.size());
if (ret)
throw_from_errno("unable to set output values");
return *this;
}
GPIOD_CXX_API ::std::map<line::offset, line_settings> line_config::get_line_settings() const
{
::std::size_t num_offsets = ::gpiod_line_config_get_num_configured_offsets(
this->_m_priv->config.get());
::std::map<line::offset, line_settings> settings_map;
::std::vector<unsigned int> offsets(num_offsets);
if (num_offsets == 0)
return settings_map;
::gpiod_line_config_get_configured_offsets(this->_m_priv->config.get(),
offsets.data(), num_offsets);
for (size_t i = 0; i < num_offsets; i++) {
line_settings settings;
settings._m_priv->settings.reset(::gpiod_line_config_get_line_settings(
this->_m_priv->config.get(),
offsets[i]));
if (!settings._m_priv->settings)
throw_from_errno("unable to retrieve line settings");
settings_map[offsets[i]] = ::std::move(settings);
}
return settings_map;
}
GPIOD_CXX_API ::std::ostream&
operator<<(::std::ostream& out, const line_config& config)
{
auto settings_map = config.get_line_settings();
::std::vector<::std::string> vec;
out << "gpiod::line_config(num_settings=" << settings_map.size();
if (settings_map.size() == 0) {
out << ")";
return out;
}
for (const auto& [offset, settings]: settings_map) {
::std::stringstream str;
str << offset << ": " << settings;
vec.push_back(str.str());
}
out << ", settings=[";
::std::copy(vec.begin(), ::std::prev(vec.end()),
::std::ostream_iterator<::std::string>(out, ", "));
out << vec.back();
out << "])";
return out;
}
} /* namespace gpiod */