summaryrefslogtreecommitdiff
path: root/comphelper/source/streaming
AgeCommit message (Collapse)Author
2020-04-18loplugin:flatten in comphelperNoel Grandin
Change-Id: I1a8db4dbd744b87406d1db5609585495f01f4403 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92478 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2020-01-28New loplugin:unsignedcompareStephan Bergmann
"Find explicit casts from signed to unsigned integer in comparison against unsigned integer, where the cast is presumably used to avoid warnings about signed vs. unsigned comparisons, and could thus be replaced with o3tl::make_unsigned for clairty." (compilerplugins/clang/unsignedcompare.cxx) o3tl::make_unsigned requires its argument to be non-negative, and there is a chance that some original code like static_cast<sal_uInt32>(n) >= c used the explicit cast to actually force a (potentially negative) value of sal_Int32 to be interpreted as an unsigned sal_uInt32, rather than using the cast to avoid a false "signed vs. unsigned comparison" warning in a case where n is known to be non-negative. It appears that restricting this plugin to non- equality comparisons (<, >, <=, >=) and excluding equality comparisons (==, !=) is a useful heuristic to avoid such false positives. The only remainging false positive I found was 0288c8ffecff4956a52b9147d441979941e8b87f "Rephrase cast from sal_Int32 to sal_uInt32". But which of course does not mean that there were no further false positivies that I missed. So this commit may accidentally introduce some false hits of the assert in o3tl::make_unsigned. At least, it passed a full (Linux ASan+UBSan --enable-dbgutil) `make check && make screenshot`. It is by design that o3tl::make_unsigned only accepts signed integer parameter types (and is not defined as a nop for unsigned ones), to avoid unnecessary uses which would in general be suspicious. But the STATIC_ARRAY_SELECT macro in include/oox/helper/helper.hxx is used with both signed and unsigned types, so needs a little oox::detail::make_unsigned helper function for now. (The ultimate fix being to get rid of the macro in the first place.) Change-Id: Ia4adc9f44c70ad1dfd608784cac39ee922c32175 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87556 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-01-16tdf#88205 Adapt uses of css::uno::Sequence to use initializer_list ctorMesut Çifci
Change-Id: Ic6ed5dcf6343a4ff59a1f69c77c82b03b4ee6198 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86904 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-01-15clang-tidy modernize-concat-nested-namespace in codemaker..configmgrNoel Grandin
Change-Id: I48452480fae169e11d60b125bbd0226b6a35a25c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86800 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-12-03remove some useless comment linesNoel Grandin
which merely announce that the next declaration is a class Change-Id: Ifdb1398bcd99816b13e0b3769b46d0562bfbc1dc Reviewed-on: https://gerrit.libreoffice.org/84229 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-11-22Extend loplugin:external to warn about classesStephan Bergmann
...following up on 314f15bff08b76bf96acf99141776ef64d2f1355 "Extend loplugin:external to warn about enums". Cases where free functions were moved into an unnamed namespace along with a class, to not break ADL, are in: filter/source/svg/svgexport.cxx sc/source/filter/excel/xelink.cxx sc/source/filter/excel/xilink.cxx svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx All other free functions mentioning moved classes appear to be harmless and not give rise to (silent, even) ADL breakage. (One remaining TODO in compilerplugins/clang/external.cxx is that derived classes are not covered by computeAffectedTypes, even though they could also be affected by ADL-breakage--- but don't seem to be in any acutal case across the code base.) For friend declarations using elaborate type specifiers, like class C1 {}; class C2 { friend class C1; }; * If C2 (but not C1) is moved into an unnamed namespace, the friend declaration must be changed to not use an elaborate type specifier (i.e., "friend C1;"; see C++17 [namespace.memdef]/3: "If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.") * If C1 (but not C2) is moved into an unnamed namespace, the friend declaration must be changed too, see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71882> "elaborated-type-specifier friend not looked up in unnamed namespace". Apart from that, to keep changes simple and mostly mechanical (which should help avoid regressions), out-of-line definitions of class members have been left in the enclosing (named) namespace. But explicit specializations of class templates had to be moved into the unnamed namespace to appease <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92598> "explicit specialization of template from unnamed namespace using unqualified-id in enclosing namespace". Also, accompanying declarations (of e.g. typedefs or static variables) that could arguably be moved into the unnamed namespace too have been left alone. And in some cases, mention of affected types in blacklists in other loplugins needed to be adapted. And sc/qa/unit/mark_test.cxx uses a hack of including other .cxx, one of which is sc/source/core/data/segmenttree.cxx where e.g. ScFlatUInt16SegmentsImpl is not moved into an unnamed namespace (because it is declared in sc/inc/segmenttree.hxx), but its base ScFlatSegmentsImpl is. GCC warns about such combinations with enabled-by-default -Wsubobject-linkage, but "The compiler doesn’t give this warning for types defined in the main .C file, as those are unlikely to have multiple definitions." (<https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Warning-Options.html>) The warned-about classes also don't have multiple definitions in the given test, so disable the warning when including the .cxx. Change-Id: Ib694094c0d8168be68f8fe90dfd0acbb66a3f1e4 Reviewed-on: https://gerrit.libreoffice.org/83239 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2019-09-30fix: SequenceOutputStream does append content correctlyVasily Melenchuk
Previous implementation was just rewriting content on each call to writeBytes() making this stream unusable. Improved and refactored corresponding Java unittest, now it check given above behavior and reacts on failures instead just writing mesages to stdout. Change-Id: Ib56baf07d8767b246a9d75cd5d639a2c2c0e7a5d Reviewed-on: https://gerrit.libreoffice.org/79840 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-09-06Fixing "...."Andrea Gelmini
Change-Id: Id005a7531d546dd43de13b49bcb3e93081c5ad8d Reviewed-on: https://gerrit.libreoffice.org/78679 Tested-by: Jenkins Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
2019-07-31Improved loplugin:stringconstant (now that GCC 7 supports it): comphelperStephan Bergmann
Change-Id: Ie0d3604b8742aed139131d523f6c7371bc02b7c3 Reviewed-on: https://gerrit.libreoffice.org/76691 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2019-07-19cid#1448429 Unchecked return valueCaolán McNamara
Change-Id: Iddbd6bc2126943752e2057b749fd6f9943261be7 Reviewed-on: https://gerrit.libreoffice.org/75888 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
2019-07-08revert part of "small optimisations"Noel Grandin
from commit ad1e790d76492ca4465114ad17e32912242db34f Date: Fri Jul 5 14:12:24 2019 +0200 small optimisations I had in mind that resize() always changes capacity to the specified value, but it actually follows the normal capacity expansion strategy for vector Change-Id: Idf677825d0f1f95b87110a3789ba95356d3771aa Reviewed-on: https://gerrit.libreoffice.org/75193 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-07-06small optimisationsNoel Grandin
In UNOMemoryStream (a) let the vector use it's natural grow strategy, so we avoid extending the vector by only the small amount we need now. (b) don't throw the vector storage away on truncate, we might need it soon In unoidl/ reserve some vector capacities. Change-Id: I6668a679e689d46d311a9e11eb3d0bc3395f3b6e Reviewed-on: https://gerrit.libreoffice.org/75136 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-07-06remove duplicate codeNoel Grandin
Change-Id: I75c43d254cd2da2ffb05c1ebd3aaf075ff3da5ec Reviewed-on: https://gerrit.libreoffice.org/75135 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-04-19tdf#42949 Fix IWYU warnings in comphelperGabor Kelemen
Found with bin/find-unneeded-includes Only removal proposals are dealt with here. Also re-evaluate some blacklisted headers and recheck include/comphelper/ Change-Id: Ib7eea5951e849c07cea2e2782be4e8945f71ad96 Reviewed-on: https://gerrit.libreoffice.org/70899 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
2019-03-31tdf#120703 PVS: remove redundant static castsMike Kaganski
V572 It is odd that the object which was created using 'new' operator is immediately cast to another type. Change-Id: I54976062dc3f62eaaa79f89eff54454f0b24ac2c Reviewed-on: https://gerrit.libreoffice.org/69989 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2018-11-05tdf#120703 PVS: V1028 fix unexpected integer overflowMike Kaganski
V1028 Possible overflow. Consider casting arguments of the operator to the type instead of casting its result. V547 Expression 'nNewSize > ((sal_Int32) 0x7FFFFFFF)' is always false. Change-Id: I7107b162d88c9d3f97019effcac1f9cfab52a66c Reviewed-on: https://gerrit.libreoffice.org/62846 Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
2018-10-08tdf#42949 Fix IWYU warnings in include/comphelper/[m-z]*Gabor Kelemen
Found with bin/find-unneeded-includes Only removal proposals are dealt with here. Change-Id: I04c5ba277d5b3398c07de6ae66713d977636088d Reviewed-on: https://gerrit.libreoffice.org/61347 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
2018-09-24tdf#42949 Fix IWYU warnings in include/comphelper/[a-l]*Gabor Kelemen
Found with bin/find-unneeded-includes Only removal proposals are dealt with here. Change-Id: I22ba2c8aec235e34cd7835b8a0a716bf3057db7a Reviewed-on: https://gerrit.libreoffice.org/60837 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
2018-09-17New loplugin:externalStephan Bergmann
...warning about (for now only) functions and variables with external linkage that likely don't need it. The problems with moving entities into unnamed namespacs and breaking ADL (as alluded to in comments in compilerplugins/clang/external.cxx) are illustrated by the fact that while struct S1 { int f() { return 0; } }; int f(S1 s) { return s.f(); } namespace N { struct S2: S1 { int f() { return 1; } }; int f(S2 s) { return s.f(); } } int main() { return f(N::S2()); } returns 1, both moving just the struct S2 into an nunnamed namespace, struct S1 { int f() { return 0; } }; int f(S1 s) { return s.f(); } namespace N { namespace { struct S2: S1 { int f() { return 1; } }; } int f(S2 s) { return s.f(); } } int main() { return f(N::S2()); } as well as moving just the function f overload into an unnamed namespace, struct S1 { int f() { return 0; } }; int f(S1 s) { return s.f(); } namespace N { struct S2: S1 { int f() { return 1; } }; namespace { int f(S2 s) { return s.f(); } } } int main() { return f(N::S2()); } would each change the program to return 0 instead. Change-Id: I4d09f7ac5e8f9bcd6e6bde4712608444b642265c Reviewed-on: https://gerrit.libreoffice.org/60539 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-07-11clean up UNO available() implementationsNoel Grandin
There seems to be some confusion here. available() is actually the number of bytes that can be read without blocking, but most implementations seems to be just returning the number of bytes remaining in the stream. Since we're doing that, let's do it properly. (*) some of them were just casting, instead of clamping, which will return wrong values sometimes. (*) FileStreamWrapper_Impl/OInputStreamWrapper/OTempFileService were doing unnecessary work, instead of just asking the underlying SvStream for it's remaining size Change-Id: I3ef26e0363e989ed3e00be0fdb993e1cdeb7819f Reviewed-on: https://gerrit.libreoffice.org/57264 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-04-01remove unused processfactory.hxx includesJochen Nitschke
and fix fallout Change-Id: Id06bf31f2075111e426ba40c84c885ae70697bee Reviewed-on: https://gerrit.libreoffice.org/52206 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Jochen Nitschke <j.nitschke+logerrit@ok.de>
2018-01-15More loplugin:cstylecast: comphelperStephan Bergmann
Change-Id: I64421e43afd7086a582fcfae0fd97b2afb6f8ef4
2018-01-12More loplugin:cstylecast: comphelperStephan Bergmann
auto-rewrite with <https://gerrit.libreoffice.org/#/c/47798/> "Enable loplugin:cstylecast for some more cases" plus solenv/clang-format/reformat-formatted-files Change-Id: I71a5092b344f206f2c7de606f2739d3b6e2cf0bb
2017-12-11loplugin:salcall fix functionsNoel Grandin
since cdecl is the default calling convention on Windows for such functions, the annotation is redundant. Change-Id: I1a85fa27e5ac65ce0e04a19bde74c90800ffaa2d Reviewed-on: https://gerrit.libreoffice.org/46164 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-10-23loplugin:includeform: comphelperStephan Bergmann
Change-Id: I9297bd0449633d1055125e7c2f2f6d215a22ae7d
2017-09-21loplugin:flatten in basctl..configmgrNoel Grandin
Change-Id: I674cad57ce30a885e126d3bcc921f8fcb53dc36d Reviewed-on: https://gerrit.libreoffice.org/42577 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-07-10teach unnecessaryparen loplugin about identifiersNoel Grandin
Change-Id: I5710b51e53779c222cec0bf08cd34bda330fec4b Reviewed-on: https://gerrit.libreoffice.org/39737 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-06-20loplugin:oncevar in codemaker..connectivityNoel Grandin
Change-Id: Ia479d9d3d459a699dfc5c1148d01c35e8bc973bd Reviewed-on: https://gerrit.libreoffice.org/39000 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-05-15Translate German comments and debug strings (leftovers in dirs a... to c...)Johnny_M
Translates all (leftovers) found using a custom regex, in directories not shown by /bin/find-german-comments and beginning with "a" to "c". Change-Id: I3b0152ee78ad80a29d714cbd98bf888f31be4763 Reviewed-on: https://gerrit.libreoffice.org/37573 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
2017-04-06split closeOutput upCaolán McNamara
Change-Id: Id6408fa804e1049ceab012ec0220d8e6f8d8e555
2017-02-06Add missing #includesStephan Bergmann
...and remove some unncessary using directives/declarations, in preparation of removing now-unnecessary #includes from cppumaker-generated files, post e57ca02849c3d87142ff5ff9099a212e72b8139c "Remove dynamic exception specifications". Change-Id: Iaf1f268871e2ee1d1c76cf90f03557527ebc9067
2017-01-26Remove dynamic exception specificationsStephan Bergmann
...(for now, from LIBO_INTERNAL_CODE only). See the mail thread starting at <https://lists.freedesktop.org/archives/libreoffice/2017-January/076665.html> "Dynamic Exception Specifications" for details. Most changes have been done automatically by the rewriting loplugin:dynexcspec (after enabling the rewriting mode, to be committed shortly). The way it only removes exception specs from declarations if it also sees a definition, it identified some dead declarations-w/o-definitions (that have been removed manually) and some cases where a definition appeared in multiple include files (which have also been cleaned up manually). There's also been cases of macro paramters (that were used to abstract over exception specs) that have become unused now (and been removed). Furthermore, some code needed to be cleaned up manually (avmedia/source/quicktime/ and connectivity/source/drivers/kab/), as I had no configurations available that would actually build that code. Missing @throws documentation has not been applied in such manual clean-up. Change-Id: I3408691256c9b0c12bc5332de976743626e13960 Reviewed-on: https://gerrit.libreoffice.org/33574 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2016-11-28loplugin:unnecessaryoverride (dtors) in comphelperStephan Bergmann
Change-Id: I13ebc4efa7f8bd0d3732ed65e397c710ae65d14e
2016-09-13loplugin:override: No more need for the "MSVC dtor override" workaroundStephan Bergmann
The issue of 362d4f0cd4e50111edfae9d30c90602c37ed65a2 "Explicitly mark overriding destructors as 'virtual'" appears to no longer be a problem with MSVC 2013. (The little change in the rewriting code of compilerplugins/clang/override.cxx was necessary to prevent an endless loop when adding "override" to OOO_DLLPUBLIC_CHARTTOOLS virtual ~CloseableLifeTimeManager(); in chart2/source/inc/LifeTime.hxx, getting stuck in the leading OOO_DLLPUBLIC_CHARTTOOLS macro. Can't remember what that isAtEndOfImmediateMacroExpansion thing was originally necessary for, anyway.) Change-Id: I534c634504d7216b9bb632c2775c04eaf27e927e
2016-07-09Implement XServiceInfo for com.sun.star.comp.MemoryStreamMatúš Kukan
Change-Id: Ie5499d2ac4aac67dc73fdc58958443b8060c4139
2016-07-09tdf#74608 Constructor function for MemoryStreamYeliz Taneroğlu
Change-Id: I5b0667c4c2808913cde686afa7315ef2319b4d49
2016-07-08loplugin:redundantcast: redundant static_casts in comphelperStephan Bergmann
Change-Id: I6112c3cc40383d00ea134bdc650e457f942e0dcf
2016-06-19loplugin:salbool: Implicit conversions from non-Boolean fundamental typesStephan Bergmann
Change-Id: I67eac95686678e6f5a2d60798535b2c65a9ba5d7
2016-04-08tdf#94306 replace boost::noncopyable in c...Jochen Nitschke
comphelper, connectivity and cppcanvas. Replace with C++11 delete copy-constructur and copy-assignment. Removed unused boost/noncopyable.hpp includes from some source files in cppcanvas. Change-Id: I90780820e21fbfd291ac10c266e7d16616e3a81b Reviewed-on: https://gerrit.libreoffice.org/23905 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <mstahl@redhat.com>
2016-04-05tdf#74608 Constructor function for SequenceOutputStreamServiceYeliz Taneroğlu
Change-Id: I0f162bd0ec61262a182ebab8cea1cfe27419a54e Reviewed-on: https://gerrit.libreoffice.org/23610 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2016-04-05loplugin:constantparam in comphelperNoel Grandin
Change-Id: I81e6af1ee869caa3b40d2d00604e8e22517d92d7 Reviewed-on: https://gerrit.libreoffice.org/23808 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2016-03-29tdf#74608 Constructor function for SequenceInputStreamServiceSteven Guo
Added ctor funtion for SequenceInputStream(Service) in comphelper. Change-Id: I043e46aa283709f316e7ad794e15438f6b2d955f Reviewed-on: https://gerrit.libreoffice.org/23564 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2016-02-09Remove excess newlinesChris Sherlock
A ridiculously fast way of doing this is: for i in $(pcregrep -l -M -r --include='.*[hc]xx$' \ --exclude-dir=workdir --exclude-dir=instdir '^ {3,}' .) do perl -0777 -i -pe 's/^ {3,}/ /gm' $i done Change-Id: Iebb93eccbee9e4fc5c4380474ba595858a27ac2c Reviewed-on: https://gerrit.libreoffice.org/22224 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Chris Sherlock <chris.sherlock79@gmail.com>
2015-11-15use initialiser for Sequence<OUString>Noel Grandin
replaced using: git grep -lP 'Sequence.*OUString.*\(\s*1\s*\)' | xargs perl -0777 -pi -e "s/Sequence<\s*OUString\s*> (\w+)\(\s*1\s*\); .*\[0\] = (\S+);/Sequence<OUString> \1 { \2 };/g" Change-Id: I20ad0489da887a9712982531c3b127339bb8b3b9 Reviewed-on: https://gerrit.libreoffice.org/19969 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2015-11-15use initialiser syntax for Sequence<OUString>Noel Grandin
replaced using the script: git grep -lP 'Sequence.*OUString.*\(1\)' | xargs perl -0777 -pi -e "s/Sequence< OUString > (\w+)\(1\); .*\[0\] = (\S+);/Sequence< OUString > \1 { \2 };/g" Change-Id: I23688a91562051a8eed11fc2a85599545c285c34 Reviewed-on: https://gerrit.libreoffice.org/19967 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2015-11-10loplugin:nullptr (automatic rewrite)Stephan Bergmann
Change-Id: Ibd0e6ae5e3243464b2484a009f2b4781bdaac471
2015-10-30use uno::Reference::set method instead of assignmentNoel Grandin
Change-Id: I080668f86f0ab8b3bba857ee21411f907ae285c4
2015-10-12Replace "SAL_OVERRIDE" with "override" in LIBO_INTERNAL_ONLY codeStephan Bergmann
Change-Id: I2ea407acd763ef2d7dae2d3b8f32525523ac8274
2015-07-27com::sun::star->css in comphelperNoel Grandin
Change-Id: I4aa0b2d15f2a06cbbbf63a363f403ca6435ffbcd Reviewed-on: https://gerrit.libreoffice.org/17365 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2015-07-20tdf#88206 replace cppu::WeakImplHelper* etc.Takeshi Abe
with the variadic variants, for comphelper. This also includes extra changes in other modules required accordingly. Change-Id: Id1537f46f1c90f760a0d8987a6dafa0e1da03b8f Reviewed-on: https://gerrit.libreoffice.org/16929 Reviewed-by: Noel Grandin <noelgrandin@gmail.com> Tested-by: Noel Grandin <noelgrandin@gmail.com>