Hi,

while playing with strings, I've just run into a mysterious linking error [1] 
which, after a bit of digging, turned out to be decrypted as [2]. Basically, 
[2] is obtained by removing all templatization code for bformat() in 
lstrings.h. All template implementations are completely specialized on specific 
types, and do NOT make any actual use of the template machinery (indeed, LyX 
compiles and links :-) ). Leaving aside the specific error of the code snippet, 
as [2] is way more readable than [1], I'd be totally in favor of pushing such a 
patch, which I'm attaching. Any thoughts?

Thanks,

        T.

  CXXLD    lyx
liblyxcore.a(Converter.o): In function `lyx::Converters::checkAuth(lyx::Converter const&, 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > 
const&)':
/home/tommaso/lyx-trunk-ws/lyx/src/Converter.cpp:289: undefined reference to `std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > 
lyx::support::bformat<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&, 
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> >)'
collect2: error: ld returned 1 exit status
Makefile:2170: recipe for target 'lyx' failed

[2]

Converter.cpp: In member function ‘bool lyx::Converters::checkAuth(const 
lyx::Converter&, const string&)’:
Converter.cpp:289:115: error: no matching function for call to ‘bformat(const 
docstring, const string, const string, const string)’
   "files, if instructed to do so by a maliciously crafted .lyx document."), 
conv.command(), conv.from(), conv.to());
                                                                                
                                   ^
In file included from Converter.cpp:35:0:
support/lstrings.h:348:11: note: candidate: lyx::docstring 
lyx::support::bformat(const docstring&, int)
 docstring bformat(docstring const & fmt, int arg1);
           ^~~~~~~
support/lstrings.h:348:11: note: candidate: lyx::docstring 
lyx::support::bformat(const docstring&, int)
...
>From a7307afb7f12c2117dea72a639417a57a8cb8df3 Mon Sep 17 00:00:00 2001
From: Tommaso Cucinotta <tomm...@lyx.org>
Date: Thu, 24 Nov 2016 00:30:13 +0100
Subject: [PATCH] Remove unneeded templatization code from bformat().

---
 src/support/lstrings.cpp | 24 ++++++------------------
 src/support/lstrings.h   | 37 ++++++++++++-------------------------
 2 files changed, 18 insertions(+), 43 deletions(-)

diff --git a/src/support/lstrings.cpp b/src/support/lstrings.cpp
index 9eb9e43d..0dd8075e 100644
--- a/src/support/lstrings.cpp
+++ b/src/support/lstrings.cpp
@@ -1408,7 +1408,6 @@ std::string formatFPNumber(double x)
 }
 
 
-template<>
 docstring bformat(docstring const & fmt, int arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1417,7 +1416,6 @@ docstring bformat(docstring const & fmt, int arg1)
 }
 
 
-template<>
 docstring bformat(docstring const & fmt, long arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1427,7 +1425,6 @@ docstring bformat(docstring const & fmt, long arg1)
 
 
 #ifdef LYX_USE_LONG_LONG
-template<>
 docstring bformat(docstring const & fmt, long long arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1437,7 +1434,6 @@ docstring bformat(docstring const & fmt, long long arg1)
 #endif
 
 
-template<>
 docstring bformat(docstring const & fmt, unsigned int arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1446,8 +1442,7 @@ docstring bformat(docstring const & fmt, unsigned int arg1)
 }
 
 
-template<>
-docstring bformat(docstring const & fmt, docstring arg1)
+docstring bformat(docstring const & fmt, docstring const & arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	docstring const str = subst(fmt, from_ascii("%1$s"), arg1);
@@ -1455,7 +1450,6 @@ docstring bformat(docstring const & fmt, docstring arg1)
 }
 
 
-template<>
 docstring bformat(docstring const & fmt, char * arg1)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
@@ -1464,8 +1458,7 @@ docstring bformat(docstring const & fmt, char * arg1)
 }
 
 
-template<>
-docstring bformat(docstring const & fmt, docstring arg1, docstring arg2)
+docstring bformat(docstring const & fmt, docstring const & arg1, docstring const & arg2)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	LATTEST(contains(fmt, from_ascii("%2$s")));
@@ -1475,8 +1468,7 @@ docstring bformat(docstring const & fmt, docstring arg1, docstring arg2)
 }
 
 
-template<>
-docstring bformat(docstring const & fmt, docstring arg1, int arg2)
+docstring bformat(docstring const & fmt, docstring const & arg1, int arg2)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	LATTEST(contains(fmt, from_ascii("%2$d")));
@@ -1486,8 +1478,7 @@ docstring bformat(docstring const & fmt, docstring arg1, int arg2)
 }
 
 
-template<>
-docstring bformat(docstring const & fmt, char const * arg1, docstring arg2)
+docstring bformat(docstring const & fmt, char const * arg1, docstring const & arg2)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	LATTEST(contains(fmt, from_ascii("%2$s")));
@@ -1497,7 +1488,6 @@ docstring bformat(docstring const & fmt, char const * arg1, docstring arg2)
 }
 
 
-template<>
 docstring bformat(docstring const & fmt, int arg1, int arg2)
 {
 	LATTEST(contains(fmt, from_ascii("%1$d")));
@@ -1508,8 +1498,7 @@ docstring bformat(docstring const & fmt, int arg1, int arg2)
 }
 
 
-template<>
-docstring bformat(docstring const & fmt, docstring arg1, docstring arg2, docstring arg3)
+docstring bformat(docstring const & fmt, docstring const & arg1, docstring const & arg2, docstring const & arg3)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	LATTEST(contains(fmt, from_ascii("%2$s")));
@@ -1521,9 +1510,8 @@ docstring bformat(docstring const & fmt, docstring arg1, docstring arg2, docstri
 }
 
 
-template<>
 docstring bformat(docstring const & fmt,
-	       docstring arg1, docstring arg2, docstring arg3, docstring arg4)
+	       docstring const & arg1, docstring const & arg2, docstring const & arg3, docstring const & arg4)
 {
 	LATTEST(contains(fmt, from_ascii("%1$s")));
 	LATTEST(contains(fmt, from_ascii("%2$s")));
diff --git a/src/support/lstrings.h b/src/support/lstrings.h
index fa61414d..97195135 100644
--- a/src/support/lstrings.h
+++ b/src/support/lstrings.h
@@ -345,33 +345,20 @@ int findToken(char const * const str[], std::string const & search_token);
 std::string formatFPNumber(double);
 
 
-template <class Arg1>
-docstring bformat(docstring const & fmt, Arg1);
-
-template <class Arg1, class Arg2>
-docstring bformat(docstring const & fmt, Arg1, Arg2);
-
-template <class Arg1, class Arg2, class Arg3>
-docstring bformat(docstring const & fmt, Arg1, Arg2, Arg3);
-
-template <class Arg1, class Arg2, class Arg3, class Arg4>
-docstring bformat(docstring const & fmt, Arg1, Arg2, Arg3, Arg4);
-
-
-template<> docstring bformat(docstring const & fmt, int arg1);
-template<> docstring bformat(docstring const & fmt, long arg1);
+docstring bformat(docstring const & fmt, int arg1);
+docstring bformat(docstring const & fmt, long arg1);
 #ifdef LYX_USE_LONG_LONG
-template<> docstring bformat(docstring const & fmt, long long arg1);
+docstring bformat(docstring const & fmt, long long arg1);
 #endif
-template<> docstring bformat(docstring const & fmt, unsigned int arg1);
-template<> docstring bformat(docstring const & fmt, docstring arg1);
-template<> docstring bformat(docstring const & fmt, char * arg1);
-template<> docstring bformat(docstring const & fmt, docstring arg1, docstring arg2);
-template<> docstring bformat(docstring const & fmt, docstring arg1, int arg2);
-template<> docstring bformat(docstring const & fmt, char const * arg1, docstring arg2);
-template<> docstring bformat(docstring const & fmt, int arg1, int arg2);
-template<> docstring bformat(docstring const & fmt, docstring arg1, docstring arg2, docstring arg3);
-template<> docstring bformat(docstring const & fmt, docstring arg1, docstring arg2, docstring arg3, docstring arg4);
+docstring bformat(docstring const & fmt, unsigned int arg1);
+docstring bformat(docstring const & fmt, docstring const & arg1);
+docstring bformat(docstring const & fmt, char * arg1);
+docstring bformat(docstring const & fmt, docstring const & arg1, docstring const & arg2);
+docstring bformat(docstring const & fmt, docstring const & arg1, int arg2);
+docstring bformat(docstring const & fmt, char const * arg1, docstring const & arg2);
+docstring bformat(docstring const & fmt, int arg1, int arg2);
+docstring bformat(docstring const & fmt, docstring const & arg1, docstring const & arg2, docstring const & arg3);
+docstring bformat(docstring const & fmt, docstring const & arg1, docstring const & arg2, docstring const & arg3, docstring const & arg4);
 
 
 } // namespace support
-- 
2.9.3

Reply via email to