#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/convert.h"
+#include "support/qstring_helpers.h"
#include "debug.h"
#include <algorithm>
#include <sstream>
-#ifdef LIBC_WCTYPE_USES_UCS4
-// We can use the libc ctype functions because we unset the LC_CTYPE
-// category of the current locale in gettext.C
-#include <wctype.h>
-#else
-// Steal some code from somewhere else, e.g. glib (look at gunicode.h)
-// The code that we currently use does not really work.
-#endif
-
-
-using lyx::docstring;
using std::transform;
using std::string;
namespace lyx {
namespace support {
-int compare_no_case(string const & s, string const & s2)
-{
- string::const_iterator p = s.begin();
- string::const_iterator p2 = s2.begin();
-
- while (p != s.end() && p2 != s2.end()) {
- int const lc1 = tolower(*p);
- int const lc2 = tolower(*p2);
- if (lc1 != lc2)
- return (lc1 < lc2) ? -1 : 1;
- ++p;
- ++p2;
- }
-
- if (s.size() == s2.size())
- return 0;
- if (s.size() < s2.size())
- return -1;
- return 1;
-}
-
-
int compare_no_case(docstring const & s, docstring const & s2)
{
docstring::const_iterator p = s.begin();
}
-int compare_no_case(string const & s, string const & s2, unsigned int len)
-{
- string::const_iterator p = s.begin();
- string::const_iterator p2 = s2.begin();
- unsigned int i = 0;
- while (i < len && p != s.end() && p2 != s2.end()) {
- int const lc1 = tolower(*p);
- int const lc2 = tolower(*p2);
- if (lc1 != lc2)
- return (lc1 < lc2) ? -1 : 1;
- ++i;
- ++p;
- ++p2;
- }
-
- if (s.size() >= len && s2.size() >= len)
- return 0;
- if (s.size() < s2.size())
- return -1;
- return 1;
-}
-
-
bool isStrInt(string const & str)
{
if (str.empty()) return false;
char lowercase(char c)
{
+ BOOST_ASSERT(static_cast<unsigned char>(c) < 0x80);
return char(tolower(c));
}
char uppercase(char c)
{
+ BOOST_ASSERT(static_cast<unsigned char>(c) < 0x80);
return char(toupper(c));
}
-// FIXME UNICODE
-// for lowercase() and uppercase() function below when wchar_t is not used:
-// 1) std::tolower() and std::toupper() are templates that
-// compile fine with char_type. With the test (c >= 256) we
-// do not trust these function to do the right thing with
-// unicode char.
-// 2) these functions use the current locale, which is wrong
-// if it is not latin1 based (latin1 is a subset of UCS4).
-
char_type lowercase(char_type c)
{
-#ifdef LIBC_WCTYPE_USES_UCS4
- return towlower(c);
-#else
- if (c >= 256)
+ if (!is_utf16(c))
+ // We don't know how to lowercase a non-utf16 char
return c;
-
- return tolower(c);
-#endif
+ return qchar_to_ucs4(ucs4_to_qchar(c).toLower());
}
char_type uppercase(char_type c)
{
-#ifdef LIBC_WCTYPE_USES_UCS4
- return towupper(c);
-#else
- if (c >= 256)
+ if (!is_utf16(c))
+ // We don't know how to uppercase a non-utf16 char
return c;
-
- return toupper(c);
-#endif
+ return qchar_to_ucs4(ucs4_to_qchar(c).toUpper());
}
// calls to std::transform yet, we use these helper clases. (Lgb)
struct local_lowercase {
- char operator()(char c) const {
- return tolower(c);
+ char_type operator()(char_type c) const {
+ if (!is_utf16(c))
+ // We don't know how to lowercase a non-utf16 char
+ return c;
+ return qchar_to_ucs4(ucs4_to_qchar(c).toLower());
}
};
struct local_uppercase {
- char operator()(char c) const {
- return toupper(c);
+ char_type operator()(char_type c) const {
+ if (!is_utf16(c))
+ // We don't know how to uppercase a non-utf16 char
+ return c;
+ return qchar_to_ucs4(ucs4_to_qchar(c).toUpper());
}
};
-struct local_ascii_lowercase {
- char operator()(char c) const {
+template<typename Char> struct local_ascii_lowercase {
+ Char operator()(Char c) const {
return ascii_tolower(c);
}
};
} // end of anon namespace
-string const lowercase(string const & a)
+docstring const lowercase(docstring const & a)
{
- string tmp(a);
+ docstring tmp(a);
transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase());
return tmp;
}
-string const uppercase(string const & a)
+
+docstring const uppercase(docstring const & a)
{
- string tmp(a);
+ docstring tmp(a);
transform(tmp.begin(), tmp.end(), tmp.begin(), local_uppercase());
return tmp;
}
{
string tmp(a);
transform(tmp.begin(), tmp.end(), tmp.begin(),
- local_ascii_lowercase());
+ local_ascii_lowercase<char>());
+ return tmp;
+}
+
+
+docstring const ascii_lowercase(docstring const & a)
+{
+ docstring tmp(a);
+ transform(tmp.begin(), tmp.end(), tmp.begin(),
+ local_ascii_lowercase<char_type>());
return tmp;
}
+bool prefixIs(docstring const & a, char_type c)
+{
+ if (a.empty())
+ return false;
+ return a[0] == c;
+}
+
+
bool prefixIs(string const & a, string const & pre)
{
string::size_type const prelen = pre.length();
}
+bool suffixIs(docstring const & a, char_type c)
+{
+ if (a.empty())
+ return false;
+ return a[a.length() - 1] == c;
+}
+
+
bool suffixIs(string const & a, string const & suf)
{
string::size_type const suflen = suf.length();
}
+docstring const rtrim(docstring const & a, char const * p)
+{
+ BOOST_ASSERT(p);
+
+ if (a.empty() || !*p)
+ return a;
+
+ docstring::size_type r = a.find_last_not_of(from_ascii(p));
+
+ // Is this test really needed? (Lgb)
+ if (r == docstring::npos)
+ return docstring();
+
+ return a.substr(0, r + 1);
+}
+
+
string const ltrim(string const & a, char const * p)
{
BOOST_ASSERT(p);
}
-/// gives a vector of stringparts which have the delimiter delim
-vector<string> const getVectorFromString(string const & str,
- string const & delim)
+namespace {
+
+template<typename String> vector<String> const
+getVectorFromStringT(String const & str, String const & delim)
{
// Lars would like this code to go, but for now his replacement (below)
// doesn't fullfil the same function. I have, therefore, reactivated the
// old code for now. Angus 11 Nov 2002.
#if 1
- vector<string> vec;
+ vector<String> vec;
if (str.empty())
return vec;
- string keys = rtrim(str);
+ String keys = rtrim(str);
for(;;) {
- string::size_type const idx = keys.find(delim);
- if (idx == string::npos) {
+ typename String::size_type const idx = keys.find(delim);
+ if (idx == String::npos) {
vec.push_back(ltrim(keys));
break;
}
- string const key = trim(keys.substr(0, idx));
+ String const key = trim(keys.substr(0, idx));
if (!key.empty())
vec.push_back(key);
- string::size_type const start = idx + delim.size();
+ typename String::size_type const start = idx + delim.size();
keys = keys.substr(start);
}
return vec;
#else
- boost::char_separator<char> sep(delim.c_str());
- boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
- return vector<string>(tokens.begin(), tokens.end());
+ typedef boost::char_separator<typename String::value_type> Separator;
+ typedef boost::tokenizer<Separator, typename String::const_iterator, String> Tokenizer;
+ Separator sep(delim.c_str());
+ Tokenizer tokens(str, sep);
+ return vector<String>(tokens.begin(), tokens.end());
#endif
}
+}
+
+
+vector<string> const getVectorFromString(string const & str,
+ string const & delim)
+{
+ return getVectorFromStringT<string>(str, delim);
+}
+
+
+vector<docstring> const getVectorFromString(docstring const & str,
+ docstring const & delim)
+{
+ return getVectorFromStringT<docstring>(str, delim);
+}
+
// the same vice versa
string const getStringFromVector(vector<string> const & vec,