Age | Commit message (Collapse) | Author |
|
As discussed in the mailing list thread starting at
<https://lists.freedesktop.org/archives/libreoffice/2023-January/089808.html>
"Plan to remove dead C++ UNO bridge implementations (bridges/source/cpp_uno/*)",
the bridge implementation at bridges/source/cpp_uno/gcc3_aix_powerpc is
apparently dead and should thus be removed. However, that was the only bridge
implementation for AIX, which implies that support for the AIX platform as a
whole is dead and should thus be removed.
Change-Id: I96de3f7f97d4fd770ff78256f0ea435383688be9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146057
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
...for C++17 and beyond with
<https://github.com/llvm/llvm-project/commit/681cde7dd8b5613dbafc9ca54e0288477f946be3>
"[libc++] Complete the implementation of N4190". (Unless explicitly opted-in
with _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION. This is similar to the
MSVC standard library needing _HAS_AUTO_PTR_ETC=1 to enable those zombie
functions for quite some time now. Only libstdc++ still supports them
unconditionally.)
Most uses of those zombie functions across LibreOffice itself and the bundled
external/* are indirectly within Boost include files. And many (but not all) of
those Boost include files only use those zombie functions conditionally, based
on BOOST_NO_CXX98_FUNCTION_BASE. For the (Dinkumware-derived) MSVC standard
library, workdir/UnpackedTarball/boost/boost/config/stdlib/dinkumware.hpp
already defined BOOST_NO_CXX98_FUNCTION_BASE. So add a patch to define that
also in workdir/UnpackedTarball/boost/boost/config/stdlib/libcpp.hpp (for all of
C++11 and beyond, even if those functions were still available as deprecated in
C++11 and C++14, but which shouldn't make a difference with our C++17 baseline
anyway; only make sure that things still work if those Boost include files ever
get used by code built with gb_CXX03FLAGS). (Patching our bundled
external/boost of course doesn't help when building with such a new libc++ and
--with-system-boost against an unpatched Boost, but lets consider that "not my
problem". Also, one could always use a sledgehammer like passing
CPPFLAGS=-D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION into gbuild in
such a case.)
Then there are two places that include boost/multi_array.hpp, which indirectly
includes workdir/UnpackedTarball/boost/boost/functional.hpp, which still uses
those zombie functions for non-MSVC builds (at least in the bundled
Boost 1.79.0). Lets do a targeted
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION in those cases.
(Alternatively, we could patch
workdir/UnpackedTarball/boost/boost/functional.hpp. Also, I decided to make
loplugin:reservedid support the new suppression mechanism, rather than extending
its existing ignorelist even further.)
And then there is external/clucene using those zombie functions even outside of
a Boost include file, so extend the existing hack there that was already needed
for MSVC. (And adapt the accompanying comment: For one, we are unconditionally
"in C++17 mode" by now. And for another, the exact places where
external/clucene uses those functions have apparently changed over time.)
Change-Id: Id0eec3bedcfddae86b16d33c02c7b5d3b3f8a16f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136579
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
It seems to run slightly faster in --enable-dbgutil mode and also
builds a bit faster (at least with Clang). But libc++ on Mac
isn't built with debug mode support.
Change-Id: Idf5dba9c4a56aba1f4163aa518a78d34b6837149
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133664
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
|
|
...which has been removed from C++17. libc++ and libstdc++ still silently
support it, but MSVC needs an explicit -D_HAS_AUTO_PTR_ETC, and this change is a
prerequisite to drop that global define again from
solenv/gbuild/platform/com_MSC_defs.mk (it had been added there with
61c88ae6945c241f5f2aeb844eeca0776b487132 "gbuild: always compile as C++17 with
MSVC 2017", but code including external/clucene, like
helpcompiler/source/LuceneHelper.cxx, appears to be the only code relying on
that global define)
Change-Id: I512d56f833c516dba3874cb0b4ef5190a88d3faf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124900
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Change-Id: Id9e0010575110ef6fae5cf93943bb226a7727e09
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120770
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
The relevant constructor is defined as deleted since incorporating
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2166r1.html> "A
Proposal to Prohibit std::basic_string and std::basic_string_view construction
from nullptr" into the upcoming C++23, and has caused undefined behavior in
prior versions (see the referenced document for details). That caused
> workdir/UnpackedTarball/clucene/src/core/CLucene/index/SegmentInfos.cpp:361:13: error: conversion function from 'long' to 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char>>') invokes a deleted function
> return NULL;
> ^~~~
> ~/llvm/inst/lib/clang/14.0.0/include/stddef.h:84:18: note: expanded from macro 'NULL'
> # define NULL __null
> ^~~~~~
> ~/llvm/inst/bin/../include/c++/v1/string:849:5: note: 'basic_string' has been explicitly marked deleted here
> basic_string(nullptr_t) = delete;
> ^
at least when building --with-latest-c++ against recent libc++ 14 trunk (on
macOS).
(There might be a chance that the CLucene code naively relied on
SegmentInfo::getDelFileName actually returning a std::string for which c_str()
would return null at least at some of the call sites, which I did not inspect in
detail. However, this would unlikely have worked in the past anyway, as it is
undefined behavior and at least contemporary libstdc++ throws a std::logic_error
when constructing a std::string from null, and at least a full `make check` with
this fix applied built fine for me.)
Change-Id: I2b8cf96b089848d666ec37aa7ee0deacc4798d35
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120745
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
This patch includes:
* A README.help.md as a general documentation for the different
help types, the LO code and help-related build options.
* Adds --disable-xmlhelp for removing the xmlhelp support from the
build. Disable for iOS, Android and Emscripten. This was partly
included in HAVE_FEATURE_DESKTOP before.
* Rename WITH_HELP define to WITH_HELPPACKS, which reflects the
actual usage AFAIK.
* Depend --with-omindex on --with-help=online and don't override
the --with-help setting. Error out on conflicting options.
* Depend --with-helppack-integration on build help variants, which
actually result in help packs.
Kind of reverts commit 2c38ea6d16b910294220cefaf8ae6a0683e6405a
("Building without --with-help is not supposed to disable help
functionality").
Change-Id: Ie4cb73905b3ed94e991d9f1bd75cfbd6de9da385
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116222
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
|
|
...which is apparently enabled at least in MSVC 2019 16.8.3 when building with
--with-latest-c++ (i.e., /std:c++latest):
> C:/lo/core/workdir/UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp(124): error C2664: 'bool lucene::analysis::PorterStemmer::ends(TCHAR *)': cannot convert argument 1 from 'const wchar_t [5]' to 'TCHAR *'
> C:/lo/core/workdir/UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp(124): note: Conversion from string literal loses const qualifier (see /Zc:strictStrings)
> C:/lo/core/workdir/UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp(97): note: see declaration of 'lucene::analysis::PorterStemmer::ends'
etc. (and which is not silenced by gb_Library_set_warnings_disabled in
external/clucene/Library_clucene.mk, unlike the corresponding Clang/GCC
-Wwrite-strings)
Change-Id: Id3c8eefa4658bf942de6c8ae9b219212eba79995
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108840
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Change-Id: Iaa3e251648afaa4bd3178dcff99594ce609083eb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96591
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
...<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2237> "Can a
template-id name a constructor?", as implemented by GCC 11 trunk since
<https://gcc.gnu.org/git/?p=gcc.git;a=commit;
h=4b38d56dbac6742b038551a36ec80200313123a1> "c++: C++20 DR 2237, disallow
simple-template-id in cdtor."
Change-Id: I507fc5bde20fdf09b4e31a3db8a7554a473f1a9f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96549
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Change-Id: Idb60ae8a2389197bcfe8b1c7848c08f551702c93
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92839
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
...as seen during a --with-lang=ALL build with ASan on Linux:
> [XHC] nlpsolver ja
> =================================================================
> ==51396==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100000ed00 at pc 0x7fe425640f53 bp 0x7ffd6a0cc900 sp 0x7ffd6a0cc8f8
> READ of size 4 at 0x62100000ed00 thread T0
> #0 in lucene::analysis::cjk::CJKTokenizer::next(lucene::analysis::Token*) at workdir/UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp:70:19
> #1 in lucene::index::DocumentsWriter::ThreadState::FieldData::invertField(lucene::document::Field*, lucene::analysis::Analyzer*, int) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriterThreadState.cpp:901:32
> #2 in lucene::index::DocumentsWriter::ThreadState::FieldData::processField(lucene::analysis::Analyzer*) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriterThreadState.cpp:798:9
> #3 in lucene::index::DocumentsWriter::ThreadState::processDocument(lucene::analysis::Analyzer*) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriterThreadState.cpp:557:24
> #4 in lucene::index::DocumentsWriter::updateDocument(lucene::document::Document*, lucene::analysis::Analyzer*, lucene::index::Term*) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriter.cpp:946:16
> #5 in lucene::index::DocumentsWriter::addDocument(lucene::document::Document*, lucene::analysis::Analyzer*) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriter.cpp:930:10
> #6 in lucene::index::IndexWriter::addDocument(lucene::document::Document*, lucene::analysis::Analyzer*) at workdir/UnpackedTarball/clucene/src/core/CLucene/index/IndexWriter.cpp:681:28
> #7 in HelpIndexer::indexDocuments() at helpcompiler/source/HelpIndexer.cxx:66:20
> #8 in main at helpcompiler/source/HelpIndexer_main.cxx:79:22
> 0x62100000ed00 is located 0 bytes to the right of 4096-byte region [0x62100000dd00,0x62100000ed00)
> allocated by thread T0 here:
> #0 in realloc at /data/sbergman/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:164:3
> #1 in lucene::util::StreamBuffer<wchar_t>::setSize(int) at workdir/UnpackedTarball/clucene/src/core/CLucene/util/_streambuffer.h:114:17
> #2 in lucene::util::StreamBuffer<wchar_t>::makeSpace(int) at workdir/UnpackedTarball/clucene/src/core/CLucene/util/_streambuffer.h:150:5
> #3 in lucene::util::BufferedStreamImpl<wchar_t>::setMinBufSize(int) at workdir/UnpackedTarball/clucene/src/core/CLucene/util/_bufferedstream.h:69:16
> #4 in lucene::util::SimpleInputStreamReader::Internal::JStreamsBuffer::JStreamsBuffer(lucene::util::CLStream<signed char>*, int) at workdir/UnpackedTarball/clucene/src/core/CLucene/util/Reader.cpp:375:6
Note that this is not a proper fix, which would need to properly detect
surrogate pairs split across buffer boundaries. But for one the comment says
"however, gunichartables doesn't seem to classify any of the surrogates as
alpha, so they are skipped anyway", and for another the behavior until now was
to replace the high surrogate with soemthing that was likely garbage and leave
the low surrogate at the start of the next buffer (if any) alone, so leaving
both surrogates alone is likely at least no worse behavior.
Change-Id: Ib6f6f1bc20ef8efe0418bf2e715783c8555068de
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92792
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Change-Id: I96785db3e7b94b55b3ab3ae911e5fb3058c6502b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92718
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
(which looks plausible esp. given the matching mentions of
<http://sourceforge.net/mailarchive/> in
external/clucene/UnpackedTarball_clucene.mk)
Change-Id: I21234a2dd611a561c9eb9c03880ee6d673694be5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92712
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html> "char8_t
backward compatibility remediation", as implemented now by <https://gcc.gnu.org/
git/?p=gcc.git;a=commit;h=0c5b35933e5b150df0ab487efb2f11ef5685f713> "libstdc++:
P1423R3 char8_t remediation (2/4)" for -std=c++2a, deletes operator << overloads
that would print a pointer rather than a (presumably expected) string.
So this infoStream output appears to have always been broken (the strings use
TCHAR, which appears to unconditionally be a typedef for wchar_t, see
workdir/UnpackedTarball/clucene/src/shared/CLucene/clucene-config.h), and
appears to be just of informative nature, so just simplify it to not try to
print any problematic parts.
Change-Id: Ie9f8edb03aff461a15718a0c025af57004aba0a9
Reviewed-on: https://gerrit.libreoffice.org/84320
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
I think this is all external libs where it makes sense for them
to have their own PCH and be worth it. Maybe some smaller externals
can also use the common system PCH, but unfortunately many externals
use all kinds of defines that affect system headers, which is
a problem for the common system PCH.
Change-Id: I2c589ac55d93728daf3b158df110722e5f055d45
Reviewed-on: https://gerrit.libreoffice.org/80728
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
|
|
As in, really disable, so that they do not even show. This moreover
avoids tons of D9025 warnings from MSVC about overriding -W4 with -w.
Change-Id: Ia2e72fd72d883d91bdd89e467ee42f259e2ae033
Reviewed-on: https://gerrit.libreoffice.org/72899
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
|
|
Building against libstdc++ effectively always requires -pthread anyway (as
various standard C++ headers require it, see the comment added to
solenv/gbuild/platform/unxgcc.mk), so many explicit uses of -pthread/-lpthread
can be removed.
Doing a (partial) test build on Linux with Clang -stdlib=libc++ suggests that
libc++ indeed doesn't need -pthread as libstdc++ does.
The remaining uses of -pthread/-lpthread are mostly in configure.ac for the
various BSDs (which somebody else might want to clean up now), and related to
external projects. I tried to be careful to remove -pthread/-lpthread from
makefiles only when C++ object files are involved (so -pthread will now be
included on the link command line by default).
Change-Id: I936e082839cb9a434bd273ce5a1f187a4245dfa1
Reviewed-on: https://gerrit.libreoffice.org/71291
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Similar to libc++ in C++17 mode, some types like std::auto_ptr are indeed
removed in C++17 mode by default, and need _HAS_AUTO_PTR_ETC=1 to be enabled
(see <https://blogs.msdn.microsoft.com/vcblog/2017/12/08/c17-feature-removals-
and-deprecations/>).
Unlike libc++, also std::binary_function and std::unary_function are removed
(and need the same _HAS_AUTO_PTR_ETC=1 to enable). So either set that flag to
make external code build, or use patches (for external/mdds) to make externals'
files included in LO proper still work there.
Change-Id: I886cc0de8196255334ee03ec48cb4bc54d460afd
Reviewed-on: https://gerrit.libreoffice.org/46514
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Change-Id: I931f0d95cad0a63d344c84d89ba7c80f14be8ec9
|
|
Change-Id: I68d93b260db1f542bb3b44858b61b2d30ae93530
Reviewed-on: https://gerrit.libreoffice.org/34856
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
|
|
In OOo times, there'd originally been efforts to allow building on Windows with
MinGW. Later, in LO times, this has been shifted to an attempt of cross-
compiling for Windows on Linux. That attempt can be considered abandoned, and
the relevant code rotting.
Due to this heritage, there are now three kinds of MinGW-specific code in LO:
* Code from the original OOo native Windows effort that is no longer relevant
for the LO cross-compilation effort, but has never been removed properly.
* Code from the original OOo native Windows effort that is re-purposed for the
LO cross-compilation effort.
* Code that has been added specifially for the LO cross-compilation effort.
All three kinds of code are removed.
(An unrelated, remaining use of MinGW is for --enable-build-unowinreg, utilizing
--with-mingw-cross-compiler, MINGWCXX, and MINGWSTRIP.)
Change-Id: I49daad8669b4cbe49fa923050c4a4a6ff7dda568
Reviewed-on: https://gerrit.libreoffice.org/34127
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Currently LFS_CFLAGS are only used in a handful of libraries but there's
no obvious reason why it can't just be set everywhere.
Also set it in windows.mk, i have no idea if it's needed for MinGW
(certainly not for MSVC).
Change-Id: I5f62e3011c2089abbf5539fc54c7ff10e07b1599
|
|
...which choke on
#pragma GCC diagnostic ignored "-Wpragmas"
Change-Id: I40100b43078320b79cb9e3d4e3fb369db0bed9fe
|
|
Change-Id: If726008f6755db59b01784ad6b479bbfe2d23e96
|
|
Change-Id: I9a067605f7c477f4e057338577a437cda7f2aa3d
|
|
Change-Id: I23da54974f39da5fccb619d6fa68eff38e70f5a5
|
|
...after 3b59dbbffdb73e48f9e2398bb1eecc24e3d95e13 "remove
HAVE_GCC_PRAGMA_DIAGNOSTIC_SCOPE check and macro"
Change-Id: I0e9f3c15d48affe104dd6b5df9828ef5e62dfa88
|
|
Change-Id: I225d9c5eb1d9c9851b3f64f7c654cfede6297933
Reviewed-on: https://gerrit.libreoffice.org/17339
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
|
|
This is supported in GCC 4.6.0 already:
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html
Change-Id: I2f67e588eea3a323a2e9c81e39e56ab2e715a817
|
|
Change-Id: Ibf6f1d60fc7ec92e24fc366dc193cbd70f13c18c
|
|
Change-Id: I102160cb6fac41f5ba3caa5cb947aebbcd62681f
|
|
...as reported by AddressSanitizer, where src/core/CLucene/index/IndexWriter.cpp
initializes IndexWriter::MAX_TERM_LENGTH with the value of
DocumentsWriter::MAX_TERM_LENGTH before the latter is initialized in
src/core/CLucene/index/DocumentsWriter.cpp. But turns out that
IndexWriter::MAX_TERM_LENGTH is completely unused.
Change-Id: Ica01186584ec05a989a13dc58823f4751e8724e2
|
|
Change-Id: I210b995d4a8eb3e2f00ba982f7a6cf5ecd8e6f0d
|
|
> pthread_mutex_destroy (/usr/src/debug/valgrind-3.9.0/helgrind/hg_intercepts.c:478)
> lucene::util::mutex_thread::~mutex_thread() (workdir/UnpackedTarball/clucene/src/shared/CLucene/config/threads.cpp:179)
> lucene::store::FSDirectory::FSIndexInput::close() (workdir/UnpackedTarball/clucene/src/core/CLucene/store/FSDirectory.cpp:225)
> lucene::index::SegmentInfos::read(lucene::store::Directory*, char const*) (workdir/UnpackedTarball/clucene/src/core/CLucene/index/SegmentInfos.cpp:770)
> lucene::index::IndexFileDeleter::IndexFileDeleter(lucene::store::Directory*, lucene::index::IndexDeletionPolicy*, lucene::index::SegmentInfos*, std::ostream*, lucene::index::DocumentsWriter*) (workdir/UnpackedTarball/clucene/src/core/CLucene/index/IndexFileDeleter.cpp:149)
> lucene::index::IndexWriter::init(lucene::store::Directory*, lucene::analysis::Analyzer*, bool, bool, lucene::index::IndexDeletionPolicy*, bool) (workdir/UnpackedTarball/clucene/src/core/CLucene/index/IndexWriter.cpp:262)
> lucene::index::IndexWriter::IndexWriter(char const*, lucene::analysis::Analyzer*, bool) (workdir/UnpackedTarball/clucene/src/core/CLucene/index/IndexWriter.cpp:158)
> HelpIndexer::indexDocuments() (helpcompiler/source/HelpIndexer.cxx:55)
Change-Id: I19cb9bd49b339d206a624c1f1d3dacdd909f4e25
|
|
Change-Id: I40132f735eabbead0a1f16d44dbd8878b03902ce
|
|
It's easier to type 'make ENABLE_WERROR= <module>' if one wants that.
Change-Id: I2bb9911259f41ecae27dc110723f3364b3ff09cf
|
|
Change-Id: Iedb2d7c62f6498691bffd0beb529e479d62d004e
|
|
... it breaks dependency generation.
Change-Id: I992e47ecea697617820358f711b7a6408fdabbe3
|
|
Change-Id: Id6023dc3751fe70984f489682be17d1ab1855f71
|
|
Change-Id: Ia9b7b18526119e29e21eb315d84d099861e15ea0
Reviewed-on: https://gerrit.libreoffice.org/6285
Reviewed-by: Björn Michaelsen <bjoern.michaelsen@canonical.com>
Tested-by: Björn Michaelsen <bjoern.michaelsen@canonical.com>
|