Merge ~sergiodj/ubuntu/+source/nut:fix-ftbfs-gcc-11 into ubuntu/+source/nut:ubuntu/devel

Proposed by Sergio Durigan Junior
Status: Merged
Approved by: Sergio Durigan Junior
Approved revision: 9104363279602e6778b134572033b9179a197d21
Merged at revision: 9104363279602e6778b134572033b9179a197d21
Proposed branch: ~sergiodj/ubuntu/+source/nut:fix-ftbfs-gcc-11
Merge into: ubuntu/+source/nut:ubuntu/devel
Diff against target: 1012 lines (+990/-0)
3 files modified
debian/changelog (+8/-0)
debian/patches/Remove-dynamic-exception-specifications-from-clients.patch (+981/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Bryce Harrington (community) Approve
Utkarsh Gupta (community) Needs Information
Review via email: mp+407043@code.launchpad.net

Description of the change

This MP fixes the FTBFS that happens when compiling nut with GCC 11.

GCC 11 defaults to C++17, which doesn't allow dynamic exception specifications anymore. This is the reason for the build failure.

Upstream has already fixed the issue:

https://github.com/networkupstools/nut/commit/fab323320d5b955ed034b2eea390a9bbb549e8e5

The patch is big and required manual adjustments, but it makes the package compile again. Bear in mind that nut is in a sad state and there are a lot of warnings when building the package.

There's a PPA with the proposed change (built using GCC 11) here:

https://launchpad.net/~sergiodj/+archive/ubuntu/ftbfs-impish/+packages

To post a comment you must log in.
Revision history for this message
Utkarsh Gupta (utkarsh) wrote :
Download full text (28.8 KiB)

Hey,

On a quick look:
-> indeed, as you say, there are lots of warnings, et al. But well, it's okay.

-> build-time tests aren't being run, why? :(
```
============================================================================
Testsuite summary for nut 2.7.4
============================================================================
# TOTAL: 0
# PASS: 0
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================
```

-> there seem to be a symbols mismatch:
```
dpkg-gensymbols: warning: debian/libnutclient0/DEBIAN/symbols doesn't match completely debian/libnutclient0.symbols
--- debian/libnutclient0.symbols (libnutclient0_2.7.4-13ubuntu5_amd64)
+++ dpkg-gensymbolsXa6vj0 2021-08-12 20:05:50.329104861 +0000
@@ -50,16 +50,16 @@
  (c++)"nut::Device::setVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
  (c++)"nut::Device::setVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
  (c++)"nut::Device::~Device()@Base" 2.7.3
- (c++|optional=lto)"nut::IOException::~IOException()@Base" 2.7.3
- (c++|optional=lto)"nut::NotConnectedException::NotConnectedException()@Base" 2.7.3
- (c++|optional=lto)"nut::NotConnectedException::~NotConnectedException()@Base" 2.7.3
- (c++|optional=lto)"nut::NutException::NutException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
- (c++|optional=lto)"nut::NutException::str[abi:cxx11]() const@Base" 2.7.3
- (c++|optional=lto)"nut::NutException::what() const@Base" 2.7.3
- (c++|optional=lto)"nut::NutException::~NutException()@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::IOException::~IOException()@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NotConnectedException::NotConnectedException()@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NotConnectedException::~NotConnectedException()@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NutException::NutException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NutException::str[abi:cxx11]() const@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NutException::what() const@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NutException::~NutException()@Base" 2.7.3
  (c++)"nut::SystemException::SystemException()@Base" 2.7.3
  (c++)"nut::SystemException::err[abi:cxx11]()@Base" 2.7.3
- (c++|optional=lto)"nut::SystemException::~SystemException()@Base" 2.7.3
+#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::SystemException::~SystemException()@Base" 2.7.3
  (c++)"nut::TcpClient::TcpClient()@Base" 2.7.3
  (c++)"nut::TcpClient::TcpClient(std::__cxx11::basic_string<char, std::c...

review: Needs Information
Revision history for this message
Bryce Harrington (bryce) wrote :

* Changelog:
  - [√] old content and logical tag match as expected
  - [√] changelog entry correct version and targeted codename
  - [√] changelog entries correct
  - [√] update-maintainer has been run

* Actual changes:
  - [√] no upstream changes to consider
  - [√] no further upstream version to consider
  - [√] debian changes look safe

* Old Delta:
  - [-] dropped changes are ok to be dropped
  - [-] nothing else to drop
  - [-] changes forwarded upstream/debian (if appropriate)

* New Delta:
  - [-] no new patches added
  - [√] patches match what was proposed upstream
  - [√] patches correctly included in debian/patches/series
  - [√] patches have correct DEP3 metadata

* Build/Test:
  - [√] build is ok
  - [-] verified PPA package installs/uninstalls
  - [√] autopkgtest against the PPA package passes
  - [-] sanity checks test fine

I'm curious why the new patch is numbered 0012 since there already is a different patch 0012 (and 0013), so seems like this should should be 0014. Fwiw, when Debian numbers their patches, I sometimes deliberately don't number the ubuntu ones; figure it distinguishes them and is less likely to get confused in future merges as the Debian patches change. However, patch naming is entirely personal preference.

Everything else LGTM. The PPA package hasn't published but it's built successfully on all arches.

I ran the testsuite but get weird errors about test dependencies:
autopkgtest [03:52:23]: @@@@@@@@@@@@@@@@@@@@ summary
nut FAIL badpkg
blame: ./nut_2.7.4-13ubuntu5.dsc
badpkg: Test dependencies are unsatisfiable. A common reason is that your testbed is out of date with respect to the archive, and you need to use a current testbed or run apt-get update or use -U.

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :
Download full text (31.2 KiB)

On Friday, August 13 2021, Utkarsh Gupta wrote:

> Hey,

Thanks for the review.

Bear in mind that the issues you raised are orthogonal to the FTBFS fix,
although they are of course valid.

> -> build-time tests aren't being run, why? :(
> ```
> ============================================================================
> Testsuite summary for nut 2.7.4
> ============================================================================
> # TOTAL: 0
> # PASS: 0
> # SKIP: 0
> # XFAIL: 0
> # FAIL: 0
> # XPASS: 0
> # ERROR: 0
> ============================================================================
> ```

I don't know offhand. As you can see from the logs "make check" is
being properly invoked by the dh_auto_test target, and "make" is
traversing the tree and calling "check" on the subdirs as expected, but
for some reason all of them return with "Nothing to be done for
'check'."

Looking into the "tests/" directory, we can see that there's not much
there. I did find what looks like to be valid tests inside
scripts/augeas/tests/test_nut.aug, but I don't know how they're supposed
to be run.

I checked that the same problem obviously happens on Debian, and I
verified that the Fedora nut package doesn't run its tests during build
time either. The next step would be to build a pristine upstream
checkout and verify what happens there, I guess.

> -> there seem to be a symbols mismatch:
> ```
> dpkg-gensymbols: warning: debian/libnutclient0/DEBIAN/symbols doesn't match completely debian/libnutclient0.symbols
> --- debian/libnutclient0.symbols (libnutclient0_2.7.4-13ubuntu5_amd64)
> +++ dpkg-gensymbolsXa6vj0 2021-08-12 20:05:50.329104861 +0000
> @@ -50,16 +50,16 @@
> (c++)"nut::Device::setVariable(std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> > const&,
> std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> > const&)@Base" 2.7.3
> (c++)"nut::Device::setVariable(std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> > const&,
> std::vector<std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> >,
> std::allocator<std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
> (c++)"nut::Device::~Device()@Base" 2.7.3
> - (c++|optional=lto)"nut::IOException::~IOException()@Base" 2.7.3
> - (c++|optional=lto)"nut::NotConnectedException::NotConnectedException()@Base" 2.7.3
> - (c++|optional=lto)"nut::NotConnectedException::~NotConnectedException()@Base" 2.7.3
> - (c++|optional=lto)"nut::NutException::NutException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
> - (c++|optional=lto)"nut::NutException::str[abi:cxx11]() const@Base" 2.7.3
> - (c++|optional=lto)"nut::NutException::what() const@Base" 2.7.3
> - (c++|optional=lto)"nut::NutException::~NutException()@Base" 2.7.3
> +#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::IOException::~IOException()@Base" 2.7.3
> +#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NotConnectedException::NotConnectedException()@Base" 2.7.3
> +#MISSING: 2.7.4-13ubuntu5# (c++|optional=lto)"nut::NotConnectedExceptio...

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

On Friday, August 13 2021, Bryce Harrington wrote:

> Review: Approve

Thanks for the review.

> I'm curious why the new patch is numbered 0012 since there already is
> a different patch 0012 (and 0013), so seems like this should should be
> 0014. Fwiw, when Debian numbers their patches, I sometimes
> deliberately don't number the ubuntu ones; figure it distinguishes
> them and is less likely to get confused in future merges as the Debian
> patches change. However, patch naming is entirely personal
> preference.

Hm. I use "gbp pq" to manage patches (even with Ubuntu packages, which
don't use gbp), and I think that was a problem with how gbp calculated
this patch's number. That's a good point and I will manually rename it.

> I ran the testsuite but get weird errors about test dependencies:
> autopkgtest [03:52:23]: @@@@@@@@@@@@@@@@@@@@ summary
> nut FAIL badpkg
> blame: ./nut_2.7.4-13ubuntu5.dsc
> badpkg: Test dependencies are unsatisfiable. A common reason is that
> your testbed is out of date with respect to the archive, and you need
> to use a current testbed or run apt-get update or use -U.

Yeah, that was happening with me when I was running the tests using
schroot/lxd as the backend. When I switched to qemu (and enabled the
proposed pocket), the tests succeeded:

autopkgtest [16:12:52]: @@@@@@@@@@@@@@@@@@@@ summary
nut PASS

Anyway, thanks again. I will rename the patch, force-push the branch
and upload the package.

--
Sergio
GPG key ID: E92F D0B3 6B14 F1F4 D8E0 EB2F 106D A1C8 C3CB BF14

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

On Friday, August 13 2021, Sergio Durigan Junior wrote:

> On Friday, August 13 2021, Utkarsh Gupta wrote:
>
>> -> build-time tests aren't being run, why? :(
>> ```
>> ============================================================================
>> Testsuite summary for nut 2.7.4
>> ============================================================================
>> # TOTAL: 0
>> # PASS: 0
>> # SKIP: 0
>> # XFAIL: 0
>> # FAIL: 0
>> # XPASS: 0
>> # ERROR: 0
>> ============================================================================
>> ```
>
> I don't know offhand. As you can see from the logs "make check" is
> being properly invoked by the dh_auto_test target, and "make" is
> traversing the tree and calling "check" on the subdirs as expected, but
> for some reason all of them return with "Nothing to be done for
> 'check'."
>
> Looking into the "tests/" directory, we can see that there's not much
> there. I did find what looks like to be valid tests inside
> scripts/augeas/tests/test_nut.aug, but I don't know how they're supposed
> to be run.
>
> I checked that the same problem obviously happens on Debian, and I
> verified that the Fedora nut package doesn't run its tests during build
> time either. The next step would be to build a pristine upstream
> checkout and verify what happens there, I guess.

A few more interesting bits regarding this topic:

While looking at the dep8 tests from nut, I noticed that they were added
by the following commit (from Debian):

  commit f313323738fd5bf05cd49c0b80b1f21783e8602b
  Author: Laurent Bigonville <email address hidden>
  AuthorDate: Tue Jun 18 21:52:31 2013 +0200
  Commit: Laurent Bigonville <email address hidden>
  CommitDate: Tue Jun 18 21:52:31 2013 +0200

      Added dep-8-tests to improve QA (from Ubuntu, closes: #708130)

If we take a look at the actual tests inside d/t/, we can see that
there's a custom "d/t/test-nut.py", which came from Ubuntu. The file
looks a lot like what we have in the ~qa-regression-testing repository,
and I bet that's where it came from.

This all contributes to the theory that upstream doesn't have a very
comprehensive testsuite and for that reason we had to come up with our
own test script that were later incorporated into the official package.

Cheers,

--
Sergio
GPG key ID: E92F D0B3 6B14 F1F4 D8E0 EB2F 106D A1C8 C3CB BF14

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Uploaded:

$ git push pkg upload/2.7.4-13ubuntu5
Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Delta compression using up to 8 threads
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 6.70 KiB | 1.34 MiB/s, done.
Total 11 (delta 7), reused 0 (delta 0)
remote: Checking connectivity: 11, done.
To ssh://git.launchpad.net/ubuntu/+source/nut
 * [new tag] upload/2.7.4-13ubuntu5 -> upload/2.7.4-13ubuntu5

$ dput nut_2.7.4-13ubuntu5_source.changes
Trying to upload package to ubuntu
Checking signature on .changes
gpg: /home/sergio/work/nut/nut_2.7.4-13ubuntu5_source.changes: Valid signature from 106DA1C8C3CBBF14
Checking signature on .dsc
gpg: /home/sergio/work/nut/nut_2.7.4-13ubuntu5.dsc: Valid signature from 106DA1C8C3CBBF14
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading nut_2.7.4-13ubuntu5.dsc: done.
  Uploading nut_2.7.4-13ubuntu5.debian.tar.xz: done.
  Uploading nut_2.7.4-13ubuntu5_source.buildinfo: done.
  Uploading nut_2.7.4-13ubuntu5_source.changes: done.
Successfully uploaded packages.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index a79c717..ac54bcd 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,11 @@
6+nut (2.7.4-13ubuntu5) impish; urgency=medium
7+
8+ * d/p/Remove-dynamic-exception-specifications-from-clients.patch:
9+ Fix FTBFS with GCC 11 due to C++17 not allowing dynamic exception
10+ specifications anymore. (LP: #1939744)
11+
12+ -- Sergio Durigan Junior <sergio.durigan@canonical.com> Thu, 12 Aug 2021 15:51:12 -0400
13+
14 nut (2.7.4-13ubuntu4) hirsute; urgency=medium
15
16 * Mark symbols as optional not seen when building with lto.
17diff --git a/debian/patches/Remove-dynamic-exception-specifications-from-clients.patch b/debian/patches/Remove-dynamic-exception-specifications-from-clients.patch
18new file mode 100644
19index 0000000..d0ce293
20--- /dev/null
21+++ b/debian/patches/Remove-dynamic-exception-specifications-from-clients.patch
22@@ -0,0 +1,981 @@
23+From: Peter Klein <kleinpa00@gmail.com>
24+Date: Thu, 11 Jun 2020 02:32:13 +0000
25+Subject: Remove dynamic exception specifications from clients/nutclient.cpp
26+
27+These are invalid in c++17 and must be removed for compatibility with
28+modern compilers.
29+
30+Origin: backport, https://github.com/networkupstools/nut/commit/fab323320d5b955ed034b2eea390a9bbb549e8e5
31+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/nut/+bug/1939744
32+Reviewed-By: Sergio Durigan Junior <sergiodj@ubuntu.com>
33+---
34+ clients/nutclient.cpp | 128 ++++++++++++++++++-------------------
35+ clients/nutclient.h | 170 +++++++++++++++++++++++++-------------------------
36+ 2 files changed, 146 insertions(+), 152 deletions(-)
37+
38+diff --git a/clients/nutclient.cpp b/clients/nutclient.cpp
39+index 8304473..a6004ab 100644
40+--- a/clients/nutclient.cpp
41++++ b/clients/nutclient.cpp
42+@@ -96,18 +96,18 @@ class Socket
43+ public:
44+ Socket();
45+
46+- void connect(const std::string& host, int port)throw(nut::IOException);
47++ void connect(const std::string& host, int port);
48+ void disconnect();
49+ bool isConnected()const;
50+
51+ void setTimeout(long timeout);
52+ bool hasTimeout()const{return _tv.tv_sec>=0;}
53+
54+- size_t read(void* buf, size_t sz)throw(nut::IOException);
55+- size_t write(const void* buf, size_t sz)throw(nut::IOException);
56++ size_t read(void* buf, size_t sz);
57++ size_t write(const void* buf, size_t sz);
58+
59+- std::string read()throw(nut::IOException);
60+- void write(const std::string& str)throw(nut::IOException);
61++ std::string read();
62++ void write(const std::string& str);
63+
64+
65+ private:
66+@@ -129,7 +129,7 @@ void Socket::setTimeout(long timeout)
67+ _tv.tv_sec = timeout;
68+ }
69+
70+-void Socket::connect(const std::string& host, int port)throw(nut::IOException)
71++void Socket::connect(const std::string& host, int port)
72+ {
73+ int sock_fd;
74+ struct addrinfo hints, *res, *ai;
75+@@ -298,7 +298,7 @@ bool Socket::isConnected()const
76+ return _sock!=INVALID_SOCKET;
77+ }
78+
79+-size_t Socket::read(void* buf, size_t sz)throw(nut::IOException)
80++size_t Socket::read(void* buf, size_t sz)
81+ {
82+ if(!isConnected())
83+ {
84+@@ -325,7 +325,7 @@ size_t Socket::read(void* buf, size_t sz)throw(nut::IOException)
85+ return (size_t) res;
86+ }
87+
88+-size_t Socket::write(const void* buf, size_t sz)throw(nut::IOException)
89++size_t Socket::write(const void* buf, size_t sz)
90+ {
91+ if(!isConnected())
92+ {
93+@@ -352,7 +352,7 @@ size_t Socket::write(const void* buf, size_t sz)throw(nut::IOException)
94+ return (size_t) res;
95+ }
96+
97+-std::string Socket::read()throw(nut::IOException)
98++std::string Socket::read()
99+ {
100+ std::string res;
101+ char buff[256];
102+@@ -383,7 +383,7 @@ std::string Socket::read()throw(nut::IOException)
103+ }
104+ }
105+
106+-void Socket::write(const std::string& str)throw(nut::IOException)
107++void Socket::write(const std::string& str)
108+ {
109+ // write(str.c_str(), str.size());
110+ // write("\n", 1);
111+@@ -408,13 +408,13 @@ Client::~Client()
112+ {
113+ }
114+
115+-bool Client::hasDevice(const std::string& dev)throw(NutException)
116++bool Client::hasDevice(const std::string& dev)
117+ {
118+ std::set<std::string> devs = getDeviceNames();
119+ return devs.find(dev) != devs.end();
120+ }
121+
122+-Device Client::getDevice(const std::string& name)throw(NutException)
123++Device Client::getDevice(const std::string& name)
124+ {
125+ if(hasDevice(name))
126+ return Device(this, name);
127+@@ -422,7 +422,7 @@ Device Client::getDevice(const std::string& name)throw(NutException)
128+ return Device(NULL, "");
129+ }
130+
131+-std::set<Device> Client::getDevices()throw(NutException)
132++std::set<Device> Client::getDevices()
133+ {
134+ std::set<Device> res;
135+
136+@@ -435,13 +435,13 @@ std::set<Device> Client::getDevices()throw(NutException)
137+ return res;
138+ }
139+
140+-bool Client::hasDeviceVariable(const std::string& dev, const std::string& name)throw(NutException)
141++bool Client::hasDeviceVariable(const std::string& dev, const std::string& name)
142+ {
143+ std::set<std::string> names = getDeviceVariableNames(dev);
144+ return names.find(name) != names.end();
145+ }
146+
147+-std::map<std::string,std::vector<std::string> > Client::getDeviceVariableValues(const std::string& dev)throw(NutException)
148++std::map<std::string,std::vector<std::string> > Client::getDeviceVariableValues(const std::string& dev)
149+ {
150+ std::map<std::string,std::vector<std::string> > res;
151+
152+@@ -455,7 +455,7 @@ std::map<std::string,std::vector<std::string> > Client::getDeviceVariableValues(
153+ return res;
154+ }
155+
156+-bool Client::hasDeviceCommand(const std::string& dev, const std::string& name)throw(NutException)
157++bool Client::hasDeviceCommand(const std::string& dev, const std::string& name)
158+ {
159+ std::set<std::string> names = getDeviceCommandNames(dev);
160+ return names.find(name) != names.end();
161+@@ -477,7 +477,7 @@ _socket(new internal::Socket)
162+ // Do not connect now
163+ }
164+
165+-TcpClient::TcpClient(const std::string& host, int port)throw(IOException):
166++TcpClient::TcpClient(const std::string& host, int port):
167+ Client(),
168+ _socket(new internal::Socket)
169+ {
170+@@ -489,14 +489,14 @@ TcpClient::~TcpClient()
171+ delete _socket;
172+ }
173+
174+-void TcpClient::connect(const std::string& host, int port)throw(IOException)
175++void TcpClient::connect(const std::string& host, int port)
176+ {
177+ _host = host;
178+ _port = port;
179+ connect();
180+ }
181+
182+-void TcpClient::connect()throw(nut::IOException)
183++void TcpClient::connect()
184+ {
185+ _socket->connect(_host, _port);
186+ }
187+@@ -532,19 +532,18 @@ long TcpClient::getTimeout()const
188+ }
189+
190+ void TcpClient::authenticate(const std::string& user, const std::string& passwd)
191+- throw(NutException)
192+ {
193+ detectError(sendQuery("USERNAME " + user));
194+ detectError(sendQuery("PASSWORD " + passwd));
195+ }
196+
197+-void TcpClient::logout()throw(NutException)
198++void TcpClient::logout()
199+ {
200+ detectError(sendQuery("LOGOUT"));
201+ _socket->disconnect();
202+ }
203+
204+-Device TcpClient::getDevice(const std::string& name)throw(NutException)
205++Device TcpClient::getDevice(const std::string& name)
206+ {
207+ try
208+ {
209+@@ -560,7 +559,7 @@ Device TcpClient::getDevice(const std::string& name)throw(NutException)
210+ return Device(this, name);
211+ }
212+
213+-std::set<std::string> TcpClient::getDeviceNames()throw(NutException)
214++std::set<std::string> TcpClient::getDeviceNames()
215+ {
216+ std::set<std::string> res;
217+
218+@@ -576,12 +575,12 @@ std::set<std::string> TcpClient::getDeviceNames()throw(NutException)
219+ return res;
220+ }
221+
222+-std::string TcpClient::getDeviceDescription(const std::string& name)throw(NutException)
223++std::string TcpClient::getDeviceDescription(const std::string& name)
224+ {
225+ return get("UPSDESC", name)[0];
226+ }
227+
228+-std::set<std::string> TcpClient::getDeviceVariableNames(const std::string& dev)throw(NutException)
229++std::set<std::string> TcpClient::getDeviceVariableNames(const std::string& dev)
230+ {
231+ std::set<std::string> set;
232+
233+@@ -594,7 +593,7 @@ std::set<std::string> TcpClient::getDeviceVariableNames(const std::string& dev)t
234+ return set;
235+ }
236+
237+-std::set<std::string> TcpClient::getDeviceRWVariableNames(const std::string& dev)throw(NutException)
238++std::set<std::string> TcpClient::getDeviceRWVariableNames(const std::string& dev)
239+ {
240+ std::set<std::string> set;
241+
242+@@ -607,17 +606,17 @@ std::set<std::string> TcpClient::getDeviceRWVariableNames(const std::string& dev
243+ return set;
244+ }
245+
246+-std::string TcpClient::getDeviceVariableDescription(const std::string& dev, const std::string& name)throw(NutException)
247++std::string TcpClient::getDeviceVariableDescription(const std::string& dev, const std::string& name)
248+ {
249+ return get("DESC", dev + " " + name)[0];
250+ }
251+
252+-std::vector<std::string> TcpClient::getDeviceVariableValue(const std::string& dev, const std::string& name)throw(NutException)
253++std::vector<std::string> TcpClient::getDeviceVariableValue(const std::string& dev, const std::string& name)
254+ {
255+ return get("VAR", dev + " " + name);
256+ }
257+
258+-std::map<std::string,std::vector<std::string> > TcpClient::getDeviceVariableValues(const std::string& dev)throw(NutException)
259++std::map<std::string,std::vector<std::string> > TcpClient::getDeviceVariableValues(const std::string& dev)
260+ {
261+
262+ std::map<std::string,std::vector<std::string> > map;
263+@@ -634,13 +633,13 @@ std::map<std::string,std::vector<std::string> > TcpClient::getDeviceVariableValu
264+ return map;
265+ }
266+
267+-void TcpClient::setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)throw(NutException)
268++void TcpClient::setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)
269+ {
270+ std::string query = "SET VAR " + dev + " " + name + " " + escape(value);
271+ detectError(sendQuery(query));
272+ }
273+
274+-void TcpClient::setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)throw(NutException)
275++void TcpClient::setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)
276+ {
277+ std::string query = "SET VAR " + dev + " " + name;
278+ for(size_t n=0; n<values.size(); ++n)
279+@@ -650,7 +649,7 @@ void TcpClient::setDeviceVariable(const std::string& dev, const std::string& nam
280+ detectError(sendQuery(query));
281+ }
282+
283+-std::set<std::string> TcpClient::getDeviceCommandNames(const std::string& dev)throw(NutException)
284++std::set<std::string> TcpClient::getDeviceCommandNames(const std::string& dev)
285+ {
286+ std::set<std::string> cmds;
287+
288+@@ -663,32 +662,32 @@ std::set<std::string> TcpClient::getDeviceCommandNames(const std::string& dev)th
289+ return cmds;
290+ }
291+
292+-std::string TcpClient::getDeviceCommandDescription(const std::string& dev, const std::string& name)throw(NutException)
293++std::string TcpClient::getDeviceCommandDescription(const std::string& dev, const std::string& name)
294+ {
295+ return get("CMDDESC", dev + " " + name)[0];
296+ }
297+
298+-void TcpClient::executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException)
299++void TcpClient::executeDeviceCommand(const std::string& dev, const std::string& name)
300+ {
301+ detectError(sendQuery("INSTCMD " + dev + " " + name));
302+ }
303+
304+-void TcpClient::deviceLogin(const std::string& dev)throw(NutException)
305++void TcpClient::deviceLogin(const std::string& dev)
306+ {
307+ detectError(sendQuery("LOGIN " + dev));
308+ }
309+
310+-void TcpClient::deviceMaster(const std::string& dev)throw(NutException)
311++void TcpClient::deviceMaster(const std::string& dev)
312+ {
313+ detectError(sendQuery("MASTER " + dev));
314+ }
315+
316+-void TcpClient::deviceForcedShutdown(const std::string& dev)throw(NutException)
317++void TcpClient::deviceForcedShutdown(const std::string& dev)
318+ {
319+ detectError(sendQuery("FSD " + dev));
320+ }
321+
322+-int TcpClient::deviceGetNumLogins(const std::string& dev)throw(NutException)
323++int TcpClient::deviceGetNumLogins(const std::string& dev)
324+ {
325+ std::string num = get("NUMLOGINS", dev)[0];
326+ return atoi(num.c_str());
327+@@ -696,7 +695,7 @@ int TcpClient::deviceGetNumLogins(const std::string& dev)throw(NutException)
328+
329+
330+ std::vector<std::string> TcpClient::get
331+- (const std::string& subcmd, const std::string& params) throw(NutException)
332++ (const std::string& subcmd, const std::string& params)
333+ {
334+ std::string req = subcmd;
335+ if(!params.empty())
336+@@ -714,7 +713,7 @@ std::vector<std::string> TcpClient::get
337+ }
338+
339+ std::vector<std::vector<std::string> > TcpClient::list
340+- (const std::string& subcmd, const std::string& params) throw(NutException)
341++ (const std::string& subcmd, const std::string& params)
342+ {
343+ std::string req = subcmd;
344+ if(!params.empty())
345+@@ -748,13 +747,13 @@ std::vector<std::vector<std::string> > TcpClient::list
346+ }
347+ }
348+
349+-std::string TcpClient::sendQuery(const std::string& req)throw(IOException)
350++std::string TcpClient::sendQuery(const std::string& req)
351+ {
352+ _socket->write(req);
353+ return _socket->read();
354+ }
355+
356+-void TcpClient::detectError(const std::string& req)throw(NutException)
357++void TcpClient::detectError(const std::string& req)
358+ {
359+ if(req.substr(0,3)=="ERR")
360+ {
361+@@ -954,47 +953,44 @@ bool Device::operator<(const Device& dev)const
362+ return getName()<dev.getName();
363+ }
364+
365+-std::string Device::getDescription()throw(NutException)
366++std::string Device::getDescription()
367+ {
368+ return getClient()->getDeviceDescription(getName());
369+ }
370+
371+ std::vector<std::string> Device::getVariableValue(const std::string& name)
372+- throw(NutException)
373+ {
374+ return getClient()->getDeviceVariableValue(getName(), name);
375+ }
376+
377+ std::map<std::string,std::vector<std::string> > Device::getVariableValues()
378+- throw(NutException)
379+ {
380+ return getClient()->getDeviceVariableValues(getName());
381+ }
382+
383+-std::set<std::string> Device::getVariableNames()throw(NutException)
384++std::set<std::string> Device::getVariableNames()
385+ {
386+ return getClient()->getDeviceVariableNames(getName());
387+ }
388+
389+-std::set<std::string> Device::getRWVariableNames()throw(NutException)
390++std::set<std::string> Device::getRWVariableNames()
391+ {
392+ return getClient()->getDeviceRWVariableNames(getName());
393+ }
394+
395+-void Device::setVariable(const std::string& name, const std::string& value)throw(NutException)
396++void Device::setVariable(const std::string& name, const std::string& value)
397+ {
398+ getClient()->setDeviceVariable(getName(), name, value);
399+ }
400+
401+ void Device::setVariable(const std::string& name, const std::vector<std::string>& values)
402+- throw(NutException)
403+ {
404+ getClient()->setDeviceVariable(getName(), name, values);
405+ }
406+
407+
408+
409+-Variable Device::getVariable(const std::string& name)throw(NutException)
410++Variable Device::getVariable(const std::string& name)
411+ {
412+ if(getClient()->hasDeviceVariable(getName(), name))
413+ return Variable(this, name);
414+@@ -1002,7 +998,7 @@ Variable Device::getVariable(const std::string& name)throw(NutException)
415+ return Variable(NULL, "");
416+ }
417+
418+-std::set<Variable> Device::getVariables()throw(NutException)
419++std::set<Variable> Device::getVariables()
420+ {
421+ std::set<Variable> set;
422+
423+@@ -1015,7 +1011,7 @@ std::set<Variable> Device::getVariables()throw(NutException)
424+ return set;
425+ }
426+
427+-std::set<Variable> Device::getRWVariables()throw(NutException)
428++std::set<Variable> Device::getRWVariables()
429+ {
430+ std::set<Variable> set;
431+
432+@@ -1028,12 +1024,12 @@ std::set<Variable> Device::getRWVariables()throw(NutException)
433+ return set;
434+ }
435+
436+-std::set<std::string> Device::getCommandNames()throw(NutException)
437++std::set<std::string> Device::getCommandNames()
438+ {
439+ return getClient()->getDeviceCommandNames(getName());
440+ }
441+
442+-std::set<Command> Device::getCommands()throw(NutException)
443++std::set<Command> Device::getCommands()
444+ {
445+ std::set<Command> cmds;
446+
447+@@ -1046,7 +1042,7 @@ std::set<Command> Device::getCommands()throw(NutException)
448+ return cmds;
449+ }
450+
451+-Command Device::getCommand(const std::string& name)throw(NutException)
452++Command Device::getCommand(const std::string& name)
453+ {
454+ if(getClient()->hasDeviceCommand(getName(), name))
455+ return Command(this, name);
456+@@ -1054,26 +1050,26 @@ Command Device::getCommand(const std::string& name)throw(NutException)
457+ return Command(NULL, "");
458+ }
459+
460+-void Device::executeCommand(const std::string& name)throw(NutException)
461++void Device::executeCommand(const std::string& name)
462+ {
463+ getClient()->executeDeviceCommand(getName(), name);
464+ }
465+
466+-void Device::login()throw(NutException)
467++void Device::login()
468+ {
469+ getClient()->deviceLogin(getName());
470+ }
471+
472+-void Device::master()throw(NutException)
473++void Device::master()
474+ {
475+ getClient()->deviceMaster(getName());
476+ }
477+
478+-void Device::forcedShutdown()throw(NutException)
479++void Device::forcedShutdown()
480+ {
481+ }
482+
483+-int Device::getNumLogins()throw(NutException)
484++int Device::getNumLogins()
485+ {
486+ return getClient()->deviceGetNumLogins(getName());
487+ }
488+@@ -1141,22 +1137,22 @@ bool Variable::operator<(const Variable& var)const
489+ return getName()<var.getName();
490+ }
491+
492+-std::vector<std::string> Variable::getValue()throw(NutException)
493++std::vector<std::string> Variable::getValue()
494+ {
495+ return getDevice()->getClient()->getDeviceVariableValue(getDevice()->getName(), getName());
496+ }
497+
498+-std::string Variable::getDescription()throw(NutException)
499++std::string Variable::getDescription()
500+ {
501+ return getDevice()->getClient()->getDeviceVariableDescription(getDevice()->getName(), getName());
502+ }
503+
504+-void Variable::setValue(const std::string& value)throw(NutException)
505++void Variable::setValue(const std::string& value)
506+ {
507+ getDevice()->setVariable(getName(), value);
508+ }
509+
510+-void Variable::setValues(const std::vector<std::string>& values)throw(NutException)
511++void Variable::setValues(const std::vector<std::string>& values)
512+ {
513+ getDevice()->setVariable(getName(), values);
514+ }
515+@@ -1225,12 +1221,12 @@ bool Command::operator<(const Command& cmd)const
516+ return getName()<cmd.getName();
517+ }
518+
519+-std::string Command::getDescription()throw(NutException)
520++std::string Command::getDescription()
521+ {
522+ return getDevice()->getClient()->getDeviceCommandDescription(getDevice()->getName(), getName());
523+ }
524+
525+-void Command::execute()throw(NutException)
526++void Command::execute()
527+ {
528+ getDevice()->executeCommand(getName());
529+ }
530+diff --git a/clients/nutclient.h b/clients/nutclient.h
531+index ed2ea44..3d4cbcb 100644
532+--- a/clients/nutclient.h
533++++ b/clients/nutclient.h
534+@@ -51,9 +51,9 @@ class NutException : public std::exception
535+ {
536+ public:
537+ NutException(const std::string& msg):_msg(msg){}
538+- virtual ~NutException() throw() {}
539+- virtual const char * what() const throw() {return this->_msg.c_str();}
540+- virtual std::string str() const throw() {return this->_msg;}
541++ virtual ~NutException() {}
542++ virtual const char * what() const noexcept {return this->_msg.c_str();}
543++ virtual std::string str() const noexcept {return this->_msg;}
544+ private:
545+ std::string _msg;
546+ };
547+@@ -65,7 +65,7 @@ class SystemException : public NutException
548+ {
549+ public:
550+ SystemException();
551+- virtual ~SystemException() throw() {}
552++ virtual ~SystemException() {}
553+ private:
554+ static std::string err();
555+ };
556+@@ -78,7 +78,7 @@ class IOException : public NutException
557+ {
558+ public:
559+ IOException(const std::string& msg):NutException(msg){}
560+- virtual ~IOException() throw() {}
561++ virtual ~IOException() {}
562+ };
563+
564+ /**
565+@@ -88,7 +88,7 @@ class UnknownHostException : public IOException
566+ {
567+ public:
568+ UnknownHostException():IOException("Unknown host"){}
569+- virtual ~UnknownHostException() throw() {}
570++ virtual ~UnknownHostException() {}
571+ };
572+
573+ /**
574+@@ -98,7 +98,7 @@ class NotConnectedException : public IOException
575+ {
576+ public:
577+ NotConnectedException():IOException("Not connected"){}
578+- virtual ~NotConnectedException() throw() {}
579++ virtual ~NotConnectedException() {}
580+ };
581+
582+ /**
583+@@ -108,7 +108,7 @@ class TimeoutException : public IOException
584+ {
585+ public:
586+ TimeoutException():IOException("Timeout"){}
587+- virtual ~TimeoutException() throw() {}
588++ virtual ~TimeoutException() {}
589+ };
590+
591+ /**
592+@@ -132,13 +132,13 @@ public:
593+ * \todo Is his method is global to all connection protocol or is it specific to TCP ?
594+ * \note Actually, authentication fails only if already set, not if bad values are sent.
595+ */
596+- virtual void authenticate(const std::string& user, const std::string& passwd)throw(NutException)=0;
597++ virtual void authenticate(const std::string& user, const std::string& passwd)=0;
598+
599+ /**
600+ * Disconnect from the NUTD server.
601+ * \todo Is his method is global to all connection protocol or is it specific to TCP ?
602+ */
603+- virtual void logout()throw(NutException)=0;
604++ virtual void logout()=0;
605+
606+ /**
607+ * Device manipulations.
608+@@ -151,29 +151,29 @@ public:
609+ * \param name Name of the device.
610+ * \return The device.
611+ */
612+- virtual Device getDevice(const std::string& name)throw(NutException);
613++ virtual Device getDevice(const std::string& name);
614+ /**
615+ * Retrieve the list of all devices supported by UPSD server.
616+ * \return The set of supported devices.
617+ */
618+- virtual std::set<Device> getDevices()throw(NutException);
619++ virtual std::set<Device> getDevices();
620+ /**
621+ * Test if a device is supported by the NUTD server.
622+ * \param dev Device name.
623+ * \return true if supported, false otherwise.
624+ */
625+- virtual bool hasDevice(const std::string& dev)throw(NutException);
626++ virtual bool hasDevice(const std::string& dev);
627+ /**
628+ * Retrieve names of devices supported by NUTD server.
629+ * \return The set of names of supported devices.
630+ */
631+- virtual std::set<std::string> getDeviceNames()throw(NutException)=0;
632++ virtual std::set<std::string> getDeviceNames()=0;
633+ /**
634+ * Retrieve the description of a device.
635+ * \param name Device name.
636+ * \return Device description.
637+ */
638+- virtual std::string getDeviceDescription(const std::string& name)throw(NutException)=0;
639++ virtual std::string getDeviceDescription(const std::string& name)=0;
640+ /** \} */
641+
642+ /**
643+@@ -186,54 +186,54 @@ public:
644+ * \param dev Device name
645+ * \return Variable names
646+ */
647+- virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)throw(NutException)=0;
648++ virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)=0;
649+ /**
650+ * Retrieve names of read/write variables supported by a device.
651+ * \param dev Device name
652+ * \return RW variable names
653+ */
654+- virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev)throw(NutException)=0;
655++ virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev)=0;
656+ /**
657+ * Test if a variable is supported by a device.
658+ * \param dev Device name
659+ * \param name Variable name
660+ * \return true if the variable is supported.
661+ */
662+- virtual bool hasDeviceVariable(const std::string& dev, const std::string& name)throw(NutException);
663++ virtual bool hasDeviceVariable(const std::string& dev, const std::string& name);
664+ /**
665+ * Retrieve the description of a variable.
666+ * \param dev Device name
667+ * \param name Variable name
668+ * \return Variable description if provided.
669+ */
670+- virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name)throw(NutException)=0;
671++ virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name)=0;
672+ /**
673+ * Retrieve values of a variable.
674+ * \param dev Device name
675+ * \param name Variable name
676+ * \return Variable values (usually one) if available.
677+ */
678+- virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name)throw(NutException)=0;
679++ virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name)=0;
680+ /**
681+ * Retrieve values of all variables of a device.
682+ * \param dev Device name
683+ * \return Variable values indexed by variable names.
684+ */
685+- virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev)throw(NutException);
686++ virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev);
687+ /**
688+ * Intend to set the value of a variable.
689+ * \param dev Device name
690+ * \param name Variable name
691+ * \param value Variable value
692+ */
693+- virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)throw(NutException)=0;
694++ virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)=0;
695+ /**
696+ * Intend to set the value of a variable.
697+ * \param dev Device name
698+ * \param name Variable name
699+ * \param value Variable value
700+ */
701+- virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)throw(NutException)=0;
702++ virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)=0;
703+ /** \} */
704+
705+ /**
706+@@ -246,27 +246,27 @@ public:
707+ * \param dev Device name
708+ * \return Command names
709+ */
710+- virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)throw(NutException)=0;
711++ virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)=0;
712+ /**
713+ * Test if a command is supported by a device.
714+ * \param dev Device name
715+ * \param name Command name
716+ * \return true if the command is supported.
717+ */
718+- virtual bool hasDeviceCommand(const std::string& dev, const std::string& name)throw(NutException);
719++ virtual bool hasDeviceCommand(const std::string& dev, const std::string& name);
720+ /**
721+ * Retrieve the description of a command.
722+ * \param dev Device name
723+ * \param name Command name
724+ * \return Command description if provided.
725+ */
726+- virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name)throw(NutException)=0;
727++ virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name)=0;
728+ /**
729+ * Intend to execute a command.
730+ * \param dev Device name
731+ * \param name Command name
732+ */
733+- virtual void executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException)=0;
734++ virtual void executeDeviceCommand(const std::string& dev, const std::string& name)=0;
735+ /** \} */
736+
737+ /**
738+@@ -277,15 +277,15 @@ public:
739+ * Log the current user (if authenticated) for a device.
740+ * \param dev Device name.
741+ */
742+- virtual void deviceLogin(const std::string& dev)throw(NutException)=0;
743++ virtual void deviceLogin(const std::string& dev)=0;
744+ /**
745+ * Retrieve the number of user longged in the specified device.
746+ * \param dev Device name.
747+ * \return Number of logged-in users.
748+ */
749+- virtual int deviceGetNumLogins(const std::string& dev)throw(NutException)=0;
750+- virtual void deviceMaster(const std::string& dev)throw(NutException)=0;
751+- virtual void deviceForcedShutdown(const std::string& dev)throw(NutException)=0;
752++ virtual int deviceGetNumLogins(const std::string& dev)=0;
753++ virtual void deviceMaster(const std::string& dev)=0;
754++ virtual void deviceForcedShutdown(const std::string& dev)=0;
755+
756+ protected:
757+ Client();
758+@@ -309,7 +309,7 @@ public:
759+ * \param host Server host name.
760+ * \param port Server port.
761+ */
762+- TcpClient(const std::string& host, int port = 3493)throw(nut::IOException);
763++ TcpClient(const std::string& host, int port = 3493);
764+ ~TcpClient();
765+
766+ /**
767+@@ -317,13 +317,13 @@ public:
768+ * \param host Server host name.
769+ * \param port Server port.
770+ */
771+- void connect(const std::string& host, int port = 3493)throw(nut::IOException);
772++ void connect(const std::string& host, int port = 3493);
773+
774+ /**
775+ * Connect to the server.
776+ * Host name and ports must have already set (usefull for reconnection).
777+ */
778+- void connect()throw(nut::IOException);
779++ void connect();
780+
781+ /**
782+ * Test if the connection is active.
783+@@ -358,39 +358,37 @@ public:
784+ */
785+ int getPort()const;
786+
787+- virtual void authenticate(const std::string& user, const std::string& passwd)throw(NutException);
788+- virtual void logout()throw(NutException);
789++ virtual void authenticate(const std::string& user, const std::string& passwd);
790++ virtual void logout();
791+
792+- virtual Device getDevice(const std::string& name)throw(NutException);
793+- virtual std::set<std::string> getDeviceNames()throw(NutException);
794+- virtual std::string getDeviceDescription(const std::string& name)throw(NutException);
795+-
796+- virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)throw(NutException);
797+- virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev)throw(NutException);
798+- virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name)throw(NutException);
799+- virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name)throw(NutException);
800+- virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev)throw(NutException);
801+- virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)throw(NutException);
802+- virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)throw(NutException);
803+-
804+- virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)throw(NutException);
805+- virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name)throw(NutException);
806+- virtual void executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException);
807+-
808+- virtual void deviceLogin(const std::string& dev)throw(NutException);
809+- virtual void deviceMaster(const std::string& dev)throw(NutException);
810+- virtual void deviceForcedShutdown(const std::string& dev)throw(NutException);
811+- virtual int deviceGetNumLogins(const std::string& dev)throw(NutException);
812++ virtual Device getDevice(const std::string& name);
813++ virtual std::set<std::string> getDeviceNames();
814++ virtual std::string getDeviceDescription(const std::string& name);
815++
816++ virtual std::set<std::string> getDeviceVariableNames(const std::string& dev);
817++ virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev);
818++ virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name);
819++ virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name);
820++ virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev);
821++ virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value);
822++ virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values);
823++
824++ virtual std::set<std::string> getDeviceCommandNames(const std::string& dev);
825++ virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name);
826++ virtual void executeDeviceCommand(const std::string& dev, const std::string& name);
827++
828++ virtual void deviceLogin(const std::string& dev);
829++ virtual void deviceMaster(const std::string& dev);
830++ virtual void deviceForcedShutdown(const std::string& dev);
831++ virtual int deviceGetNumLogins(const std::string& dev);
832+
833+ protected:
834+- std::string sendQuery(const std::string& req)throw(nut::IOException);
835+- static void detectError(const std::string& req)throw(nut::NutException);
836++ std::string sendQuery(const std::string& req);
837++ static void detectError(const std::string& req);
838+
839+- std::vector<std::string> get(const std::string& subcmd, const std::string& params = "")
840+- throw(nut::NutException);
841++ std::vector<std::string> get(const std::string& subcmd, const std::string& params = "");
842+
843+- std::vector<std::vector<std::string> > list(const std::string& subcmd, const std::string& params = "")
844+- throw(nut::NutException);
845++ std::vector<std::vector<std::string> > list(const std::string& subcmd, const std::string& params = "");
846+
847+ static std::vector<std::string> explode(const std::string& str, size_t begin=0);
848+ static std::string escape(const std::string& str);
849+@@ -455,92 +453,92 @@ public:
850+ /**
851+ * Retrieve the description of the devce if specified.
852+ */
853+- std::string getDescription()throw(NutException);
854++ std::string getDescription();
855+
856+ /**
857+ * Intend to retrieve the value of a variable of the device.
858+ * \param name Name of the variable to get.
859+ * \return Value of the variable, if available.
860+ */
861+- std::vector<std::string> getVariableValue(const std::string& name)throw(NutException);
862++ std::vector<std::string> getVariableValue(const std::string& name);
863+ /**
864+ * Intend to retrieve values of all variables of the devices.
865+ * \return Map of all variables values indexed by their names.
866+ */
867+- std::map<std::string,std::vector<std::string> > getVariableValues()throw(NutException);
868++ std::map<std::string,std::vector<std::string> > getVariableValues();
869+ /**
870+ * Retrieve all variables names supported by the device.
871+ * \return Set of available variable names.
872+ */
873+- std::set<std::string> getVariableNames()throw(NutException);
874++ std::set<std::string> getVariableNames();
875+ /**
876+ * Retrieve all Read/Write variables names supported by the device.
877+ * \return Set of available Read/Write variable names.
878+ */
879+- std::set<std::string> getRWVariableNames()throw(NutException);
880++ std::set<std::string> getRWVariableNames();
881+ /**
882+ * Intend to set the value of a variable of the device.
883+ * \param name Variable name.
884+ * \param value New variable value.
885+ */
886+- void setVariable(const std::string& name, const std::string& value)throw(NutException);
887++ void setVariable(const std::string& name, const std::string& value);
888+ /**
889+ * Intend to set values of a variable of the device.
890+ * \param name Variable name.
891+ * \param value New variable values.
892+ */
893+- void setVariable(const std::string& name, const std::vector<std::string>& values)throw(NutException);
894++ void setVariable(const std::string& name, const std::vector<std::string>& values);
895+
896+ /**
897+ * Retrieve a Variable object representing the specified variable.
898+ * \param name Variable name.
899+ * \return Variable object.
900+ */
901+- Variable getVariable(const std::string& name)throw(NutException);
902++ Variable getVariable(const std::string& name);
903+ /**
904+ * Retrieve Variable objects representing all variables available for the device.
905+ * \return Set of Variable objects.
906+ */
907+- std::set<Variable> getVariables()throw(NutException);
908++ std::set<Variable> getVariables();
909+ /**
910+ * Retrieve Variable objects representing all Read/Write variables available for the device.
911+ * \return Set of Variable objects.
912+ */
913+- std::set<Variable> getRWVariables()throw(NutException);
914++ std::set<Variable> getRWVariables();
915+
916+ /**
917+ * Retrieve names of all commands supported by the device.
918+ * \return Set of available command names.
919+ */
920+- std::set<std::string> getCommandNames()throw(NutException);
921++ std::set<std::string> getCommandNames();
922+ /**
923+ * Retrieve objects for all commands supported by the device.
924+ * \return Set of available Command objects.
925+ */
926+- std::set<Command> getCommands()throw(NutException);
927++ std::set<Command> getCommands();
928+ /**
929+ * Retrieve an object representing a command of the device.
930+ * \param name Command name.
931+ * \return Command object.
932+ */
933+- Command getCommand(const std::string& name)throw(NutException);
934++ Command getCommand(const std::string& name);
935+ /**
936+ * Intend to execute a command on the device.
937+ * \param name Command name.
938+ */
939+- void executeCommand(const std::string& name)throw(NutException);
940++ void executeCommand(const std::string& name);
941+
942+ /**
943+ * Login current client's user for the device.
944+ */
945+- void login()throw(NutException);
946+- void master()throw(NutException);
947+- void forcedShutdown()throw(NutException);
948++ void login();
949++ void master();
950++ void forcedShutdown();
951+ /**
952+ * Retrieve the number of logged user for the device.
953+ * \return Number of users.
954+ */
955+- int getNumLogins()throw(NutException);
956++ int getNumLogins();
957+
958+ protected:
959+ Device(Client* client, const std::string& name);
960+@@ -603,23 +601,23 @@ public:
961+ * Intend to retrieve variable value.
962+ * \return Value of the variable.
963+ */
964+- std::vector<std::string> getValue()throw(NutException);
965++ std::vector<std::string> getValue();
966+ /**
967+ * Intend to retireve variable description.
968+ * \return Variable description if provided.
969+ */
970+- std::string getDescription()throw(NutException);
971++ std::string getDescription();
972+
973+ /**
974+ * Intend to set a value to the variable.
975+ * \param value New variable value.
976+ */
977+- void setValue(const std::string& value)throw(NutException);
978++ void setValue(const std::string& value);
979+ /**
980+ * Intend to set (multiple) values to the variable.
981+ * \param value New variable values.
982+ */
983+- void setValues(const std::vector<std::string>& values)throw(NutException);
984++ void setValues(const std::vector<std::string>& values);
985+
986+ protected:
987+ Variable(Device* dev, const std::string& name);
988+@@ -683,13 +681,13 @@ public:
989+ * Intend to retireve command description.
990+ * \return Command description if provided.
991+ */
992+- std::string getDescription()throw(NutException);
993++ std::string getDescription();
994+
995+ /**
996+ * Intend to retrieve command description.
997+ * \return Command description if provided.
998+ */
999+- void execute()throw(NutException);
1000++ void execute();
1001+
1002+ protected:
1003+ Command(Device* dev, const std::string& name);
1004diff --git a/debian/patches/series b/debian/patches/series
1005index 50dc917..b11be6b 100644
1006--- a/debian/patches/series
1007+++ b/debian/patches/series
1008@@ -11,3 +11,4 @@
1009 0011-use-pkgconfig-module.patch
1010 0012-add-AEG-PROTECT-NAS-support.patch
1011 0013-fix-doc-build.patch
1012+Remove-dynamic-exception-specifications-from-clients.patch

Subscribers

People subscribed via source and target branches