]> git.lyx.org Git - lyx.git/blobdiff - src/support/docstring.cpp
fix warning on possibly(?) unused precompiled headers due to different -fPic settings...
[lyx.git] / src / support / docstring.cpp
index 35414934168f5a967418ea7aa83e1b428e605e5c..c232fec5fc91d23b00184e3d728165458de4e1e0 100644 (file)
@@ -13,6 +13,7 @@
 #include "docstring.h"
 #include "qstring_helpers.h"
 #include "unicode.h"
+#include "lstrings.h"
 
 #include <locale>
 #include <iostream>
@@ -140,9 +141,9 @@ std::string const to_filesystem8bit(docstring const & s)
 }
 
 
-docstring const normalize_kc(docstring const & s)
+docstring const normalize_c(docstring const & s)
 {
-       return qstring_to_ucs4(toqstr(s).normalized(QString::NormalizationForm_KC));
+       return qstring_to_ucs4(toqstr(s).normalized(QString::NormalizationForm_C));
 }
 
 
@@ -217,7 +218,7 @@ lyx::docstring & operator+=(lyx::docstring & l, char r)
 
 } // namespace lyx
 
-#if (!defined(HAVE_WCHAR_T) || SIZEOF_WCHAR_T != 4) && defined(__GNUC__)
+#if ! defined(USE_WCHAR_T) && defined(__GNUC__)
 
 // gcc does not have proper locale facets for lyx::char_type if
 // sizeof(wchar_t) == 2, so we have to implement them on our own.
@@ -560,19 +561,148 @@ public:
                string_num_get_facet() : std::num_get<char, std::basic_string<char>::iterator>(1) {}
        };
 
-private:
-       bool isNumpunct(lyx::char_type const c) const
+       /// Numpunct facet defining the I/O format.
+       class numpunct_facet : public std::numpunct<char>
        {
-               /// Only account for the standard numpunct "C" locale facet.
-               return c < 0x80 && (c == '-' || c == '+' || isdigit(c)
-                       || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
-                       || c == 'x' || c == 'X');
-       }
+       public:
+               numpunct_facet() : std::numpunct<char>(1) {}
+       };
 
 protected:
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, bool & v) const
+       {
+               if (b.flags() & std::ios_base::boolalpha) {
+                       numpunct_facet p;
+                       lyx::docstring const truename = from_local8bit(p.truename());
+                       lyx::docstring const falsename = from_local8bit(p.falsename());
+                       lyx::docstring s;
+                       s.resize(16);
+                       bool ok = true;
+                       size_t n = 0;
+                       size_t const tsize = truename.size();
+                       size_t const fsize = falsename.size();
+                       for (; iit != eit; ++iit) {
+                               s += *iit;
+                               ++n;
+                               bool true_ok = lyx::support::prefixIs(truename, s);
+                               bool false_ok = lyx::support::prefixIs(falsename, s);
+                               if (!true_ok && !false_ok) {
+                                       ++iit;
+                                       ok = false;
+                                       break;
+                               }
+                               if ((true_ok && n == tsize) ||
+                                   (false_ok && n == fsize)) {
+                                       ++iit;
+                                       break;
+                               }
+                       }
+                       if (ok) {
+                               err = std::ios_base::goodbit;
+                               v = truename == s ? true : false;
+                       } else
+                               err = std::ios_base::failbit;
+                       if (iit == eit)
+                               err |= std::ios_base::eofbit;
+                       return iit;
+               } else {
+                       long l;
+                       iter_type end = this->do_get(iit, eit, b, err, l);
+                       if (!(err & std::ios_base::failbit)) {
+                               if (l == 0)
+                                       v = false;
+                               else if (l == 1)
+                                       v = true;
+                               else
+                                       err |= std::ios_base::failbit;
+                       }
+                       return end;
+               }
+       }
+
        iter_type
        do_get(iter_type iit, iter_type eit, std::ios_base & b,
                std::ios_base::iostate & err, long & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, unsigned short & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, unsigned int & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, unsigned long & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, long long & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, unsigned long long & v) const
+       {
+               return do_get_integer(iit, eit, b, err, v);
+       }
+#endif
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, float & v) const
+       {
+               return do_get_float(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, double & v) const
+       {
+               return do_get_float(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, long double & v) const
+       {
+               return do_get_float(iit, eit, b, err, v);
+       }
+
+       iter_type
+       do_get(iter_type iit, iter_type eit, std::ios_base & b,
+               std::ios_base::iostate & err, void * & v) const
+       {
+               unsigned long val;
+               iter_type end = do_get_integer(iit, eit, b, err, val);
+               if (!(err & std::ios_base::failbit))
+                       v = reinterpret_cast<void *>(val);
+               return end;
+       }
+
+private:
+       template <typename ValueType>
+       iter_type
+       do_get_integer(iter_type iit, iter_type eit, std::ios_base & b,
+                       std::ios_base::iostate & err, ValueType & v) const
        {
                std::string s;
                s.reserve(64);
@@ -585,9 +715,65 @@ protected:
                s += ' ';
                string_num_get_facet f;
                f.get(s.begin(), s.end(), b, err, v);
+               if (iit == eit)
+                   err |= std::ios_base::eofbit;
+
+               return iit;
+       }
+
+       bool isNumpunct(lyx::char_type const c) const
+       {
+               /// Only account for the standard numpunct "C" locale facet.
+               return c < 0x80 && (c == '-' || c == '+' || isdigit(c)
+                       || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
+                       || c == 'x' || c == 'X');
+       }
+
+       template <typename ValueType>
+       iter_type
+       do_get_float(iter_type iit, iter_type eit, std::ios_base & b,
+                       std::ios_base::iostate & err, ValueType & v) const
+       {
+               // Gather a string of the form
+               // [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
+               std::string s;
+               s.reserve(64);
+               char c;
+               numpunct_facet p;
+               char const dot = p.decimal_point();
+               char const sep = p.thousands_sep();
+               // Get an optional sign
+               if (iit != eit && (*iit == '-' || *iit == '+')) {
+                       s += static_cast<char>(*iit);
+                       ++iit;
+               }
+               for (; iit != eit && isDigitOrSep(*iit, sep); ++iit)
+                       s += static_cast<char>(*iit);
+               if (iit != eit && *iit == dot) {
+                       s += dot;
+                       ++iit;
+                       for (; iit != eit && isDigitOrSep(*iit, 0); ++iit)
+                               s += static_cast<char>(*iit);
+                       if (iit != eit && (*iit == 'e' || *iit == 'E')) {
+                               s += static_cast<char>(*iit);
+                               ++iit;
+                               for (; iit != eit && isDigitOrSep(*iit, 0); ++iit)
+                                       s += static_cast<char>(*iit);
+                       }
+               }
+               s += '\n';
+               string_num_get_facet f;
+               f.get(s.begin(), s.end(), b, err, v);
+               if (iit == eit)
+                   err |= std::ios_base::eofbit;
 
                return iit;
        }
+
+       bool isDigitOrSep(lyx::char_type const c, char const sep) const
+       {
+               return (c >= '0' && c <= '9') || (c != 0 && c == sep);
+       }
 };