2006-09-01 15:41:38 +00:00
|
|
|
/**
|
Rename files in src/support, step one.
src/support/package.h src/support/Package.h Package
src/support/package.C.in src/support/Package.C.in Package
src/support/path.h src/support/Path.h Path
src/support/fs_extras.h src/support/fs_extras.h NOCLASSES
src/support/RandomAccessList.h src/support/RandomAccessList.h RandomAccessList
src/support/lyxmanip.h src/support/lyxmanip.h NOCLASSES
src/support/rename.C src/support/rename.cpp NOCLASSES
src/support/abort.C src/support/abort.cpp NOCLASSES
src/support/lyxlib.h src/support/lyxlib.h NOCLASSES
src/support/ExceptionMessage.h src/support/ExceptionMessage.h ExceptionMessage
src/support/copy.C src/support/copy.cpp NOCLASSES
src/support/limited_stack.h src/support/limited_stack.h limited_stack
src/support/filefilterlist.C src/support/FileFilterList.cpp ['FileFilterList', 'Filter']
src/support/cow_ptr.h src/support/cow_ptr.h cow_ptr
src/support/os_unix.C src/support/os_unix.cpp NOCLASSES
src/support/socktools.h src/support/socktools.h NOCLASSES
src/support/forkedcontr.h src/support/ForkedcallsController.h ForkedcallsController
src/support/os.h src/support/os.h NOCLASSES
src/support/FileMonitor.h src/support/FileMonitor.h FileMonitor
src/support/copied_ptr.h src/support/copied_ptr.h copied_ptr
src/support/translator.h src/support/Translator.h Translator
src/support/filetools.C src/support/filetools.cpp NOCLASSES
src/support/unlink.C src/support/unlink.cpp NOCLASSES
src/support/os_win32.C src/support/os_win32.cpp GetFolderPath
src/support/lstrings.C src/support/lstrings.cpp NOCLASSES
src/support/qstring_helpers.C src/support/qstring_helpers.cpp NOCLASSES
src/support/getcwd.C src/support/getcwd.cpp NOCLASSES
src/support/systemcall.C src/support/Systemcall.cpp Systemcall
src/support/lyxalgo.h src/support/lyxalgo.h NOCLASSES
src/support/filefilterlist.h src/support/FileFilterList.h ['FileFilterList', 'Filter']
src/support/unicode.C src/support/unicode.cpp IconvProcessor
src/support/userinfo.C src/support/userinfo.cpp NOCLASSES
src/support/lyxtime.C src/support/lyxtime.cpp NOCLASSES
src/support/kill.C src/support/kill.cpp NOCLASSES
src/support/docstring.C src/support/docstring.cpp to_local8bit_failure
src/support/os_cygwin.C src/support/os_cygwin.cpp NOCLASSES
src/support/lyxsum.C src/support/lyxsum.cpp NOCLASSES
src/support/environment.C src/support/environment.cpp NOCLASSES
src/support/filetools.h src/support/filetools.h NOCLASSES
src/support/textutils.C src/support/textutils.cpp NOCLASSES
src/support/mkdir.C src/support/mkdir.cpp NOCLASSES
src/support/forkedcall.C src/support/Forkedcall.cpp ['ForkedProcess', 'Forkedcall']
src/support/tempname.C src/support/tempname.cpp NOCLASSES
src/support/os_win32.h src/support/os_win32.h GetFolderPath
src/support/types.h src/support/types.h NOCLASSES
src/support/lstrings.h src/support/lstrings.h NOCLASSES
src/support/forkedcallqueue.C src/support/ForkedCallQueue.cpp ForkedCallQueue
src/support/qstring_helpers.h src/support/qstring_helpers.h NOCLASSES
src/support/convert.C src/support/convert.cpp NOCLASSES
src/support/filename.C src/support/FileName.cpp ['FileName', 'DocFileName']
src/support/tests/convert.C src/support/tests/convert.cpp NOCLASSES
src/support/tests/filetools.C src/support/tests/filetools.cpp NOCLASSES
src/support/tests/lstrings.C src/support/tests/lstrings.cpp NOCLASSES
src/support/tests/boost.C src/support/tests/boost.cpp NOCLASSES
src/support/docstream.C src/support/docstream.cpp ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/std_istream.h src/support/std_istream.h NOCLASSES
src/support/systemcall.h src/support/Systemcall.h Systemcall
src/support/chdir.C src/support/chdir.cpp NOCLASSES
src/support/std_ostream.h src/support/std_ostream.h NOCLASSES
src/support/unicode.h src/support/unicode.h IconvProcessor
src/support/path.C src/support/Path.cpp Path
src/support/fs_extras.C src/support/fs_extras.cpp NOCLASSES
src/support/userinfo.h src/support/userinfo.h NOCLASSES
src/support/lyxtime.h src/support/lyxtime.h NOCLASSES
src/support/docstring.h src/support/docstring.h to_local8bit_failure
src/support/debugstream.h src/support/debugstream.h basic_debugstream
src/support/environment.h src/support/environment.h NOCLASSES
src/support/textutils.h src/support/textutils.h NOCLASSES
src/support/forkedcall.h src/support/Forkedcall.h ['ForkedProcess', 'Forkedcall']
src/support/socktools.C src/support/socktools.cpp NOCLASSES
src/support/forkedcallqueue.h src/support/ForkedCallQueue.h ForkedCallQueue
src/support/forkedcontr.C src/support/ForkedcallsController.cpp ForkedcallsController
src/support/os.C src/support/os.cpp NOCLASSES
src/support/convert.h src/support/convert.h NOCLASSES
src/support/filename.h src/support/FileName.h ['FileName', 'DocFileName']
src/support/docstream.h src/support/docstream.h ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/FileMonitor.C src/support/FileMonitor.cpp FileMonitor
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18024 a592a061-630c-0410-9148-cb99ea01b6c8
2007-04-26 05:12:52 +00:00
|
|
|
* \file docstring.cpp
|
2006-09-01 15:41:38 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Georg Baum
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-11-29 07:04:28 +00:00
|
|
|
#include "support/docstring.h"
|
|
|
|
|
2008-05-29 17:57:57 +00:00
|
|
|
#include "support/lassert.h"
|
2007-11-29 07:04:28 +00:00
|
|
|
#include "support/lstrings.h"
|
|
|
|
#include "support/qstring_helpers.h"
|
|
|
|
#include "support/unicode.h"
|
2006-09-01 15:41:38 +00:00
|
|
|
|
2008-05-29 17:57:57 +00:00
|
|
|
#include <QFile>
|
|
|
|
|
2012-11-18 16:42:02 +00:00
|
|
|
//Needed in Ubuntu
|
2012-11-12 12:06:22 +00:00
|
|
|
#include <typeinfo>
|
2012-11-12 11:11:42 +00:00
|
|
|
#if ! defined(USE_WCHAR_T) && defined(__GNUC__)
|
|
|
|
#include <locale>
|
|
|
|
#include <iostream>
|
|
|
|
#endif
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
using namespace std;
|
2006-09-01 15:41:38 +00:00
|
|
|
|
2010-12-07 22:53:07 +00:00
|
|
|
using lyx::support::isHexChar;
|
2006-09-01 15:41:38 +00:00
|
|
|
|
2008-05-29 17:57:57 +00:00
|
|
|
namespace lyx {
|
2006-10-28 15:16:30 +00:00
|
|
|
|
2006-09-01 15:41:38 +00:00
|
|
|
docstring const from_ascii(char const * ascii)
|
|
|
|
{
|
|
|
|
docstring s;
|
2008-06-17 16:33:19 +00:00
|
|
|
if (int n = strlen(ascii)) {
|
|
|
|
s.resize(n);
|
|
|
|
char_type *d = &s[0];
|
|
|
|
while (--n >= 0) {
|
|
|
|
d[n] = ascii[n];
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(static_cast<unsigned char>(ascii[n]) < 0x80);
|
2008-06-17 16:33:19 +00:00
|
|
|
}
|
2006-09-01 15:41:38 +00:00
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
docstring const from_ascii(string const & ascii)
|
2006-09-01 15:41:38 +00:00
|
|
|
{
|
|
|
|
int const len = ascii.length();
|
|
|
|
for (int i = 0; i < len; ++i)
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(static_cast<unsigned char>(ascii[i]) < 0x80);
|
2006-09-01 15:41:38 +00:00
|
|
|
return docstring(ascii.begin(), ascii.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string const to_ascii(docstring const & ucs4)
|
2006-10-08 09:44:26 +00:00
|
|
|
{
|
|
|
|
int const len = ucs4.length();
|
2007-12-12 19:28:07 +00:00
|
|
|
string ascii;
|
2006-10-08 09:44:26 +00:00
|
|
|
ascii.resize(len);
|
|
|
|
for (int i = 0; i < len; ++i) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(ucs4[i] < 0x80);
|
2006-10-08 09:44:26 +00:00
|
|
|
ascii[i] = static_cast<char>(ucs4[i]);
|
|
|
|
}
|
|
|
|
return ascii;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
void utf8_to_ucs4(string const & utf8, docstring & ucs4)
|
2006-10-28 15:16:30 +00:00
|
|
|
{
|
|
|
|
size_t n = utf8.size();
|
|
|
|
// as utf8 is a multi-byte encoding, there would be at most
|
|
|
|
// n characters:
|
|
|
|
ucs4.resize(n);
|
|
|
|
if (n == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int maxoutsize = n * 4;
|
|
|
|
// basic_string::data() is not recognized by some old gcc version
|
|
|
|
// so we use &(ucs4[0]) instead.
|
|
|
|
char * outbuf = (char *)(&(ucs4[0]));
|
2006-11-18 17:47:12 +00:00
|
|
|
int bytes = utf8ToUcs4().convert(utf8.c_str(), n, outbuf, maxoutsize);
|
2006-10-28 15:16:30 +00:00
|
|
|
|
|
|
|
// adjust to the real converted size
|
|
|
|
ucs4.resize(bytes/4);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
docstring const from_utf8(string const & utf8)
|
2006-09-01 15:41:38 +00:00
|
|
|
{
|
2006-10-28 15:16:30 +00:00
|
|
|
docstring ucs4;
|
|
|
|
utf8_to_ucs4(utf8, ucs4);
|
|
|
|
return ucs4;
|
2006-09-01 15:41:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string const to_utf8(docstring const & ucs4)
|
2006-09-01 15:41:38 +00:00
|
|
|
{
|
2008-06-16 18:27:11 +00:00
|
|
|
vector<char> const utf8 = ucs4_to_utf8(ucs4.data(), ucs4.size());
|
2007-12-12 19:28:07 +00:00
|
|
|
return string(utf8.begin(), utf8.end());
|
2006-09-01 15:41:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
docstring const from_local8bit(string const & s)
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
{
|
|
|
|
return qstring_to_ucs4(QString::fromLocal8Bit(s.data(), s.length()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-31 08:05:37 +00:00
|
|
|
/// Exception thrown by to_local8bit if the string could not be converted
|
2007-12-12 19:28:07 +00:00
|
|
|
class to_local8bit_failure : public bad_cast {
|
2007-10-31 08:05:37 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
to_local8bit_failure() throw() : bad_cast() {}
|
2007-10-31 08:05:37 +00:00
|
|
|
virtual ~to_local8bit_failure() throw() {}
|
|
|
|
virtual const char* what() const throw()
|
|
|
|
{
|
|
|
|
return "A string could not be converted from unicode to the local 8 bit encoding.";
|
|
|
|
}
|
|
|
|
};
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string const to_local8bit(docstring const & s)
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
{
|
|
|
|
// This conversion can fail, depending on input.
|
|
|
|
if (s.empty())
|
2007-12-12 19:28:07 +00:00
|
|
|
return string();
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
QByteArray const local = toqstr(s).toLocal8Bit();
|
2012-10-21 19:14:16 +00:00
|
|
|
if (local.isEmpty())
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
throw to_local8bit_failure();
|
2007-12-12 19:28:07 +00:00
|
|
|
return string(local.begin(), local.end());
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
docstring const from_filesystem8bit(string const & s)
|
2007-01-18 20:47:27 +00:00
|
|
|
{
|
|
|
|
QByteArray const encoded(s.c_str(), s.length());
|
|
|
|
return qstring_to_ucs4(QFile::decodeName(encoded));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string const to_filesystem8bit(docstring const & s)
|
2007-01-22 02:58:47 +00:00
|
|
|
{
|
|
|
|
QByteArray const encoded = QFile::encodeName(toqstr(s));
|
2007-12-12 19:28:07 +00:00
|
|
|
return string(encoded.begin(), encoded.end());
|
2007-01-22 02:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-10 10:24:10 +00:00
|
|
|
string const to_iconv_encoding(docstring const & s, string const & encoding)
|
|
|
|
{
|
|
|
|
std::vector<char> const encoded =
|
|
|
|
ucs4_to_eightbit(s.data(), s.length(), encoding);
|
|
|
|
return string(encoded.begin(), encoded.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring const from_iconv_encoding(string const & s, string const & encoding)
|
|
|
|
{
|
|
|
|
std::vector<char_type> const ucs4 =
|
|
|
|
eightbit_to_ucs4(s.data(), s.length(), encoding);
|
|
|
|
return docstring(ucs4.begin(), ucs4.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-05 14:45:00 +00:00
|
|
|
docstring const normalize_c(docstring const & s)
|
2007-04-03 08:15:39 +00:00
|
|
|
{
|
2007-07-05 14:45:00 +00:00
|
|
|
return qstring_to_ucs4(toqstr(s).normalized(QString::NormalizationForm_C));
|
2007-04-03 08:15:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-01 15:41:38 +00:00
|
|
|
bool operator==(lyx::docstring const & l, char const * r)
|
|
|
|
{
|
2007-04-21 22:39:04 +00:00
|
|
|
lyx::docstring::const_iterator it = l.begin();
|
|
|
|
lyx::docstring::const_iterator end = l.end();
|
|
|
|
for (; it != end; ++it, ++r) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(*r) < 0x80, return false);
|
2007-04-21 22:39:04 +00:00
|
|
|
if (!*r)
|
2006-09-01 15:41:38 +00:00
|
|
|
return false;
|
2007-04-21 22:39:04 +00:00
|
|
|
if (*it != static_cast<lyx::docstring::value_type>(*r))
|
2006-09-01 15:41:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
2007-04-21 22:39:04 +00:00
|
|
|
return *r == '\0';
|
2006-09-01 15:41:38 +00:00
|
|
|
}
|
2006-09-11 07:13:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
lyx::docstring operator+(lyx::docstring const & l, char const * r)
|
|
|
|
{
|
|
|
|
lyx::docstring s(l);
|
|
|
|
for (char const * c = r; *c; ++c) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(*c) < 0x80, return l);
|
2006-09-11 07:13:56 +00:00
|
|
|
s.push_back(*c);
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lyx::docstring operator+(char const * l, lyx::docstring const & r)
|
|
|
|
{
|
|
|
|
lyx::docstring s;
|
|
|
|
for (char const * c = l; *c; ++c) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(*c) < 0x80, return r);
|
2006-09-11 07:13:56 +00:00
|
|
|
s.push_back(*c);
|
|
|
|
}
|
|
|
|
s += r;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lyx::docstring operator+(lyx::docstring const & l, char r)
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(r) < 0x80, return l);
|
2007-10-31 22:40:34 +00:00
|
|
|
docstring s = l;
|
|
|
|
s += docstring::value_type(r);
|
|
|
|
return s;
|
2006-09-11 07:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lyx::docstring operator+(char l, lyx::docstring const & r)
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(l) < 0x80, return r);
|
2006-09-11 07:13:56 +00:00
|
|
|
return lyx::docstring::value_type(l) + r;
|
|
|
|
}
|
2006-10-03 19:27:17 +00:00
|
|
|
|
|
|
|
|
2006-10-08 09:59:17 +00:00
|
|
|
lyx::docstring & operator+=(lyx::docstring & l, char const * r)
|
2006-10-08 09:44:26 +00:00
|
|
|
{
|
|
|
|
for (char const * c = r; *c; ++c) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(*c) < 0x80, return l);
|
2006-10-08 09:44:26 +00:00
|
|
|
l.push_back(*c);
|
|
|
|
}
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-08 09:59:17 +00:00
|
|
|
lyx::docstring & operator+=(lyx::docstring & l, char r)
|
2006-10-08 09:44:26 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(static_cast<unsigned char>(r) < 0x80, return l);
|
2006-10-08 09:44:26 +00:00
|
|
|
l.push_back(r);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|
2006-10-08 09:44:26 +00:00
|
|
|
|
2007-06-27 18:02:54 +00:00
|
|
|
#if ! defined(USE_WCHAR_T) && defined(__GNUC__)
|
2006-10-03 19:27:17 +00:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
|
|
|
|
// We get undefined references to these virtual methods. This looks like
|
|
|
|
// a bug in gcc. The implementation here does not do anything useful, since
|
|
|
|
// it is overriden in ascii_ctype_facet.
|
|
|
|
namespace std {
|
|
|
|
template<> ctype<lyx::char_type>::~ctype() {}
|
|
|
|
template<> bool
|
|
|
|
ctype<lyx::char_type>::do_is(ctype<lyx::char_type>::mask, lyx::char_type) const { return false; }
|
|
|
|
template<> lyx::char_type const *
|
|
|
|
ctype<lyx::char_type>::do_is(const lyx::char_type *, const lyx::char_type *, ctype<lyx::char_type>::mask *) const { return 0; }
|
|
|
|
template<> const lyx::char_type *
|
|
|
|
ctype<lyx::char_type>::do_scan_is(ctype<lyx::char_type>::mask, const lyx::char_type *, const lyx::char_type *) const { return 0; }
|
|
|
|
template<> const lyx::char_type *
|
|
|
|
ctype<lyx::char_type>::do_scan_not(ctype<lyx::char_type>::mask, const lyx::char_type *, const lyx::char_type *) const { return 0; }
|
|
|
|
template<> lyx::char_type ctype<lyx::char_type>::do_toupper(lyx::char_type) const { return 0; }
|
|
|
|
template<> const lyx::char_type * ctype<lyx::char_type>::do_toupper(lyx::char_type *, lyx::char_type const *) const { return 0; }
|
|
|
|
template<> lyx::char_type ctype<lyx::char_type>::do_tolower(lyx::char_type) const { return 0; }
|
|
|
|
template<> const lyx::char_type * ctype<lyx::char_type>::do_tolower(lyx::char_type *, lyx::char_type const *) const { return 0; }
|
|
|
|
template<> lyx::char_type ctype<lyx::char_type>::do_widen(char) const { return 0; }
|
|
|
|
template<> const char *
|
|
|
|
ctype<lyx::char_type>::do_widen(const char *, const char *, lyx::char_type *) const { return 0; }
|
|
|
|
template<> char
|
|
|
|
ctype<lyx::char_type>::do_narrow(const lyx::char_type, char) const { return 0; }
|
|
|
|
template<> const lyx::char_type *
|
|
|
|
ctype<lyx::char_type>::do_narrow(const lyx::char_type *, const lyx::char_type *, char, char *) const { return 0; }
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace std
|
2006-10-03 19:27:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
class ctype_failure : public bad_cast {
|
2006-10-03 19:27:17 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
ctype_failure() throw() : bad_cast() {}
|
2006-10-03 19:27:17 +00:00
|
|
|
virtual ~ctype_failure() throw() {}
|
|
|
|
virtual const char* what() const throw()
|
|
|
|
{
|
|
|
|
return "The ctype<lyx::char_type> locale facet does only support ASCII characters on this platform.";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
class num_put_failure : public bad_cast {
|
2006-11-11 00:04:28 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
num_put_failure() throw() : bad_cast() {}
|
2006-11-11 00:04:28 +00:00
|
|
|
virtual ~num_put_failure() throw() {}
|
|
|
|
virtual const char* what() const throw()
|
|
|
|
{
|
|
|
|
return "The num_put locale facet does only support ASCII characters on this platform.";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-10-03 19:27:17 +00:00
|
|
|
/// ctype facet for UCS4 characters. The implementation does only support pure
|
|
|
|
/// ASCII, since we do not need anything else for now.
|
2007-12-12 19:28:07 +00:00
|
|
|
/// The code is partly stolen from ctype<wchar_t> from gcc.
|
|
|
|
class ascii_ctype_facet : public ctype<lyx::char_type>
|
2006-10-03 19:27:17 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef lyx::char_type char_type;
|
|
|
|
typedef wctype_t wmask_type;
|
2007-12-12 19:28:07 +00:00
|
|
|
explicit ascii_ctype_facet(size_t refs = 0) : ctype<char_type>(refs)
|
2006-10-03 19:27:17 +00:00
|
|
|
{
|
|
|
|
M_initialize_ctype();
|
|
|
|
}
|
|
|
|
protected:
|
|
|
|
bool M_narrow_ok;
|
|
|
|
char M_narrow[128];
|
|
|
|
wint_t M_widen[1 + static_cast<unsigned char>(-1)];
|
|
|
|
mask M_bit[16];
|
|
|
|
wmask_type M_wmask[16];
|
|
|
|
wmask_type M_convert_to_wmask(const mask m) const
|
|
|
|
{
|
|
|
|
wmask_type ret;
|
|
|
|
switch (m) {
|
|
|
|
case space: ret = wctype("space"); break;
|
|
|
|
case print: ret = wctype("print"); break;
|
|
|
|
case cntrl: ret = wctype("cntrl"); break;
|
|
|
|
case upper: ret = wctype("upper"); break;
|
|
|
|
case lower: ret = wctype("lower"); break;
|
|
|
|
case alpha: ret = wctype("alpha"); break;
|
|
|
|
case digit: ret = wctype("digit"); break;
|
|
|
|
case punct: ret = wctype("punct"); break;
|
|
|
|
case xdigit: ret = wctype("xdigit"); break;
|
|
|
|
case alnum: ret = wctype("alnum"); break;
|
|
|
|
case graph: ret = wctype("graph"); break;
|
|
|
|
default: ret = wmask_type();
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
void M_initialize_ctype()
|
|
|
|
{
|
|
|
|
wint_t i;
|
|
|
|
for (i = 0; i < 128; ++i) {
|
|
|
|
const int c = wctob(i);
|
|
|
|
if (c == EOF)
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
M_narrow[i] = static_cast<char>(c);
|
|
|
|
}
|
|
|
|
if (i == 128)
|
|
|
|
M_narrow_ok = true;
|
|
|
|
else
|
|
|
|
M_narrow_ok = false;
|
|
|
|
for (size_t i = 0; i < sizeof(M_widen) / sizeof(wint_t); ++i)
|
|
|
|
M_widen[i] = btowc(i);
|
|
|
|
|
|
|
|
for (size_t i = 0; i <= 15; ++i) {
|
|
|
|
M_bit[i] = static_cast<mask>(1 << i);
|
|
|
|
M_wmask[i] = M_convert_to_wmask(M_bit[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virtual ~ascii_ctype_facet() {}
|
|
|
|
char_type do_toupper(char_type c) const
|
|
|
|
{
|
|
|
|
if (c >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
return toupper(static_cast<int>(c));
|
|
|
|
}
|
|
|
|
char_type const * do_toupper(char_type * lo, char_type const * hi) const
|
|
|
|
{
|
|
|
|
while (lo < hi) {
|
|
|
|
if (*lo >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
*lo = toupper(static_cast<int>(*lo));
|
|
|
|
++lo;
|
|
|
|
}
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
char_type do_tolower(char_type c) const
|
|
|
|
{
|
|
|
|
if (c >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
return tolower(c);
|
|
|
|
}
|
|
|
|
char_type const * do_tolower(char_type * lo, char_type const * hi) const
|
|
|
|
{
|
|
|
|
while (lo < hi) {
|
|
|
|
if (*lo >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
*lo = tolower(*lo);
|
|
|
|
++lo;
|
|
|
|
}
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
bool do_is(mask m, char_type c) const
|
|
|
|
{
|
|
|
|
if (c >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
// The code below works because c is in the ASCII range.
|
|
|
|
// We could not use iswctype() which is designed for a 2byte
|
|
|
|
// whar_t without encoding conversion otherwise.
|
|
|
|
bool ret = false;
|
|
|
|
// Generically, 15 (instead of 10) since we don't know the numerical
|
|
|
|
// encoding of the various categories in /usr/include/ctype.h.
|
|
|
|
const size_t bitmasksize = 15;
|
|
|
|
for (size_t bitcur = 0; bitcur <= bitmasksize; ++bitcur)
|
|
|
|
if (m & M_bit[bitcur] &&
|
|
|
|
iswctype(static_cast<int>(c), M_wmask[bitcur])) {
|
|
|
|
ret = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
char_type const * do_is(char_type const * lo, char_type const * hi, mask * vec) const
|
|
|
|
{
|
|
|
|
for (;lo < hi; ++vec, ++lo) {
|
|
|
|
if (*lo >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
// The code below works because c is in the ASCII range.
|
|
|
|
// We could not use iswctype() which is designed for a 2byte
|
|
|
|
// whar_t without encoding conversion otherwise.
|
|
|
|
// Generically, 15 (instead of 10) since we don't know the numerical
|
|
|
|
// encoding of the various categories in /usr/include/ctype.h.
|
|
|
|
const size_t bitmasksize = 15;
|
|
|
|
mask m = 0;
|
|
|
|
for (size_t bitcur = 0; bitcur <= bitmasksize; ++bitcur)
|
|
|
|
if (iswctype(static_cast<int>(*lo), M_wmask[bitcur]))
|
|
|
|
m |= M_bit[bitcur];
|
|
|
|
*vec = m;
|
|
|
|
}
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
char_type const * do_scan_is(mask m, char_type const * lo, char_type const * hi) const
|
|
|
|
{
|
|
|
|
while (lo < hi && !this->do_is(m, *lo))
|
|
|
|
++lo;
|
|
|
|
return lo;
|
|
|
|
}
|
|
|
|
char_type const * do_scan_not(mask m, char_type const * lo, char_type const * hi) const
|
|
|
|
{
|
|
|
|
while (lo < hi && this->do_is(m, *lo) != 0)
|
|
|
|
++lo;
|
|
|
|
return lo;
|
|
|
|
}
|
|
|
|
char_type do_widen(char c) const
|
|
|
|
{
|
|
|
|
if (static_cast<unsigned char>(c) < 0x80)
|
|
|
|
return c;
|
|
|
|
throw ctype_failure();
|
|
|
|
}
|
|
|
|
const char* do_widen(const char* lo, const char* hi, char_type* dest) const
|
|
|
|
{
|
|
|
|
while (lo < hi) {
|
|
|
|
if (static_cast<unsigned char>(*lo) >= 0x80)
|
|
|
|
throw ctype_failure();
|
|
|
|
*dest = *lo;
|
|
|
|
++lo;
|
|
|
|
++dest;
|
|
|
|
}
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
char do_narrow(char_type wc, char) const
|
|
|
|
{
|
|
|
|
if (wc < 0x80)
|
|
|
|
return static_cast<char>(wc);
|
|
|
|
throw ctype_failure();
|
|
|
|
}
|
|
|
|
const char_type * do_narrow(const char_type * lo, const char_type * hi, char, char * dest) const
|
|
|
|
{
|
|
|
|
while (lo < hi) {
|
|
|
|
if (*lo < 0x80)
|
|
|
|
*dest = static_cast<char>(*lo);
|
|
|
|
else
|
|
|
|
throw ctype_failure();
|
|
|
|
++lo;
|
|
|
|
++dest;
|
|
|
|
}
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-11-11 00:04:28 +00:00
|
|
|
/// Facet for outputting numbers to odocstreams as ascii.
|
|
|
|
/// Here we simply need defining the virtual do_put functions.
|
2007-12-12 19:28:07 +00:00
|
|
|
class ascii_num_put_facet : public num_put<lyx::char_type, ostreambuf_iterator<lyx::char_type, char_traits<lyx::char_type> > >
|
2006-11-11 00:04:28 +00:00
|
|
|
{
|
2007-12-12 19:28:07 +00:00
|
|
|
typedef ostreambuf_iterator<lyx::char_type, char_traits<lyx::char_type> > iter_type;
|
2006-11-11 00:04:28 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
ascii_num_put_facet(size_t refs = 0) : num_put<lyx::char_type, iter_type>(refs) {}
|
2006-11-11 00:04:28 +00:00
|
|
|
|
|
|
|
/// Facet for converting numbers to ascii strings.
|
2007-12-12 19:28:07 +00:00
|
|
|
class string_num_put_facet : public num_put<char, basic_string<char>::iterator>
|
2006-11-11 00:04:28 +00:00
|
|
|
{
|
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
string_num_put_facet() : num_put<char, basic_string<char>::iterator>(1) {}
|
2006-11-11 00:04:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, bool v) const
|
2006-12-14 00:31:18 +00:00
|
|
|
{
|
2006-12-15 00:30:46 +00:00
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
2006-12-14 00:31:18 +00:00
|
|
|
|
2006-12-15 00:30:46 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, long v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
2006-12-14 00:31:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, unsigned long v) const
|
2006-12-14 00:31:18 +00:00
|
|
|
{
|
2006-12-15 00:30:46 +00:00
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
2006-12-14 00:31:18 +00:00
|
|
|
|
2019-03-21 13:05:50 +00:00
|
|
|
#ifdef HAVE_LONG_LONG_INT
|
2006-12-15 00:30:46 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, long long v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
2006-12-14 00:31:18 +00:00
|
|
|
|
2006-12-15 00:30:46 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, unsigned long long v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
2006-12-14 00:31:18 +00:00
|
|
|
}
|
2006-12-15 00:30:46 +00:00
|
|
|
#endif
|
2006-12-14 00:31:18 +00:00
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, double v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, long double v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put(iter_type oit, ios_base & b, char_type fill, void const * v) const
|
2006-12-15 00:30:46 +00:00
|
|
|
{
|
|
|
|
return do_put_helper(oit, b, fill, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
template <typename ValueType>
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_put_helper(iter_type oit, ios_base & b, char_type fill, ValueType v) const
|
2006-11-11 00:04:28 +00:00
|
|
|
{
|
|
|
|
if (fill >= 0x80)
|
|
|
|
throw num_put_failure();
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
streamsize const sz = b.width() > b.precision() ?
|
2006-12-15 22:53:06 +00:00
|
|
|
b.width() : b.precision();
|
|
|
|
// 64 is large enough, unless width or precision are bigger
|
2007-12-12 19:28:07 +00:00
|
|
|
streamsize const wd = (sz > 56 ? sz : 56) + 8;
|
|
|
|
string s(wd, '\0');
|
2006-11-11 00:04:28 +00:00
|
|
|
string_num_put_facet f;
|
2007-12-12 19:28:07 +00:00
|
|
|
string::const_iterator cit = s.begin();
|
|
|
|
string::const_iterator end =
|
2006-11-11 00:04:28 +00:00
|
|
|
f.put(s.begin(), b, fill, v);
|
|
|
|
for (; cit != end; ++cit, ++oit)
|
|
|
|
*oit = *cit;
|
|
|
|
|
|
|
|
return oit;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-11-17 19:27:42 +00:00
|
|
|
/// Facet for inputting ascii representations of numbers from idocstreams.
|
|
|
|
/// Here we simply need defining the virtual do_get functions.
|
2007-12-12 19:28:07 +00:00
|
|
|
class ascii_num_get_facet : public num_get<lyx::char_type, istreambuf_iterator<lyx::char_type, char_traits<lyx::char_type> > >
|
2006-11-17 19:27:42 +00:00
|
|
|
{
|
2007-12-12 19:28:07 +00:00
|
|
|
typedef istreambuf_iterator<lyx::char_type, char_traits<lyx::char_type> > iter_type;
|
2006-11-17 19:27:42 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
ascii_num_get_facet(size_t refs = 0) : num_get<lyx::char_type, iter_type>(refs) {}
|
2006-11-17 19:27:42 +00:00
|
|
|
|
|
|
|
/// Facet for converting ascii representation of numbers to a value.
|
2007-12-12 19:28:07 +00:00
|
|
|
class string_num_get_facet : public num_get<char, basic_string<char>::iterator>
|
2006-11-17 19:27:42 +00:00
|
|
|
{
|
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
string_num_get_facet() : num_get<char, basic_string<char>::iterator>(1) {}
|
2006-11-17 19:27:42 +00:00
|
|
|
};
|
|
|
|
|
2007-07-30 13:15:27 +00:00
|
|
|
/// Numpunct facet defining the I/O format.
|
2007-12-12 19:28:07 +00:00
|
|
|
class numpunct_facet : public numpunct<char>
|
2006-11-17 19:27:42 +00:00
|
|
|
{
|
2007-07-30 13:15:27 +00:00
|
|
|
public:
|
2007-12-12 19:28:07 +00:00
|
|
|
numpunct_facet() : numpunct<char>(1) {}
|
2007-07-30 13:15:27 +00:00
|
|
|
};
|
2006-11-17 19:27:42 +00:00
|
|
|
|
|
|
|
protected:
|
2007-07-30 13:15:27 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, bool & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
2007-12-12 19:28:07 +00:00
|
|
|
if (b.flags() & ios_base::boolalpha) {
|
2007-07-30 13:15:27 +00:00
|
|
|
numpunct_facet p;
|
|
|
|
lyx::docstring const truename = from_local8bit(p.truename());
|
|
|
|
lyx::docstring const falsename = from_local8bit(p.falsename());
|
2007-07-31 13:13:23 +00:00
|
|
|
lyx::docstring s;
|
|
|
|
s.resize(16);
|
|
|
|
bool ok = true;
|
2007-07-30 13:15:27 +00:00
|
|
|
size_t n = 0;
|
2007-07-31 13:13:23 +00:00
|
|
|
size_t const tsize = truename.size();
|
|
|
|
size_t const fsize = falsename.size();
|
2007-07-30 13:15:27 +00:00
|
|
|
for (; iit != eit; ++iit) {
|
2007-07-31 13:13:23 +00:00
|
|
|
s += *iit;
|
2007-07-30 13:15:27 +00:00
|
|
|
++n;
|
2007-12-12 21:09:51 +00:00
|
|
|
bool true_ok = support::prefixIs(truename, s);
|
|
|
|
bool false_ok = support::prefixIs(falsename, s);
|
2007-07-31 13:13:23 +00:00
|
|
|
if (!true_ok && !false_ok) {
|
|
|
|
++iit;
|
|
|
|
ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ((true_ok && n == tsize) ||
|
|
|
|
(false_ok && n == fsize)) {
|
2007-07-30 13:15:27 +00:00
|
|
|
++iit;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-07-31 13:13:23 +00:00
|
|
|
if (ok) {
|
2007-12-12 19:28:07 +00:00
|
|
|
err = ios_base::goodbit;
|
2007-07-31 13:13:23 +00:00
|
|
|
v = truename == s ? true : false;
|
2007-07-30 13:15:27 +00:00
|
|
|
} else
|
2007-12-12 19:28:07 +00:00
|
|
|
err = ios_base::failbit;
|
2007-07-30 13:15:27 +00:00
|
|
|
if (iit == eit)
|
2007-12-12 19:28:07 +00:00
|
|
|
err |= ios_base::eofbit;
|
2007-07-30 13:15:27 +00:00
|
|
|
return iit;
|
|
|
|
} else {
|
|
|
|
long l;
|
|
|
|
iter_type end = this->do_get(iit, eit, b, err, l);
|
2007-12-12 19:28:07 +00:00
|
|
|
if (!(err & ios_base::failbit)) {
|
2007-07-30 13:15:27 +00:00
|
|
|
if (l == 0)
|
|
|
|
v = false;
|
|
|
|
else if (l == 1)
|
|
|
|
v = true;
|
|
|
|
else
|
2007-12-12 19:28:07 +00:00
|
|
|
err |= ios_base::failbit;
|
2007-07-30 13:15:27 +00:00
|
|
|
}
|
|
|
|
return end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-17 19:27:42 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, long & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, unsigned short & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, unsigned int & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, unsigned long & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
2019-03-21 13:05:50 +00:00
|
|
|
#ifdef HAVE_LONG_LONG_INT
|
2007-07-30 13:15:27 +00:00
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, long long & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, unsigned long long & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_integer(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, float & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_float(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, double & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_float(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, long double & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
return do_get_float(iit, eit, b, err, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, void * & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
unsigned long val;
|
|
|
|
iter_type end = do_get_integer(iit, eit, b, err, val);
|
2007-12-12 19:28:07 +00:00
|
|
|
if (!(err & ios_base::failbit))
|
2007-07-30 13:15:27 +00:00
|
|
|
v = reinterpret_cast<void *>(val);
|
|
|
|
return end;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
template <typename ValueType>
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get_integer(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, ValueType & v) const
|
2006-11-17 19:27:42 +00:00
|
|
|
{
|
2007-12-12 19:28:07 +00:00
|
|
|
string s;
|
2006-11-27 01:52:26 +00:00
|
|
|
s.reserve(64);
|
|
|
|
for (; iit != eit && isNumpunct(*iit); ++iit)
|
|
|
|
s += static_cast<char>(*iit);
|
2006-11-28 19:15:05 +00:00
|
|
|
// We add another character, not part of the numpunct facet,
|
|
|
|
// in order to avoid setting the eofbit in the stream state,
|
2006-11-29 13:39:49 +00:00
|
|
|
// which would prevent any further read. The space seems a
|
2006-11-28 19:15:05 +00:00
|
|
|
// good choice here.
|
2006-11-29 13:39:49 +00:00
|
|
|
s += ' ';
|
2006-11-17 19:27:42 +00:00
|
|
|
string_num_get_facet f;
|
|
|
|
f.get(s.begin(), s.end(), b, err, v);
|
2007-07-30 13:15:27 +00:00
|
|
|
if (iit == eit)
|
2007-12-12 19:28:07 +00:00
|
|
|
err |= ios_base::eofbit;
|
2007-07-30 13:15:27 +00:00
|
|
|
|
|
|
|
return iit;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isNumpunct(lyx::char_type const c) const
|
|
|
|
{
|
|
|
|
/// Only account for the standard numpunct "C" locale facet.
|
2010-12-07 00:13:19 +00:00
|
|
|
return c == '-' || c == '+'
|
|
|
|
|| c == 'x' || c == 'X'
|
|
|
|
|| isHexChar(c);
|
2007-07-30 13:15:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ValueType>
|
|
|
|
iter_type
|
2007-12-12 19:28:07 +00:00
|
|
|
do_get_float(iter_type iit, iter_type eit, ios_base & b,
|
|
|
|
ios_base::iostate & err, ValueType & v) const
|
2007-07-30 13:15:27 +00:00
|
|
|
{
|
|
|
|
// Gather a string of the form
|
|
|
|
// [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
|
2007-12-12 19:28:07 +00:00
|
|
|
string s;
|
2007-07-30 13:15:27 +00:00
|
|
|
s.reserve(64);
|
|
|
|
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)
|
2007-12-12 19:28:07 +00:00
|
|
|
err |= ios_base::eofbit;
|
2006-11-17 19:27:42 +00:00
|
|
|
|
|
|
|
return iit;
|
|
|
|
}
|
2007-07-30 13:15:27 +00:00
|
|
|
|
|
|
|
bool isDigitOrSep(lyx::char_type const c, char const sep) const
|
|
|
|
{
|
|
|
|
return (c >= '0' && c <= '9') || (c != 0 && c == sep);
|
|
|
|
}
|
2006-11-17 19:27:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-11-11 00:04:28 +00:00
|
|
|
/// class to add our facets to the global locale
|
2006-10-03 19:27:17 +00:00
|
|
|
class locale_initializer {
|
|
|
|
public:
|
|
|
|
locale_initializer()
|
|
|
|
{
|
2007-12-12 19:28:07 +00:00
|
|
|
locale global;
|
|
|
|
locale const loc1(global, new ascii_ctype_facet);
|
|
|
|
locale const loc2(loc1, new ascii_num_put_facet);
|
|
|
|
locale const loc3(loc2, new ascii_num_get_facet);
|
|
|
|
locale::global(loc3);
|
2006-10-03 19:27:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2006-11-11 00:04:28 +00:00
|
|
|
/// make sure that our facets get used
|
2006-10-03 19:27:17 +00:00
|
|
|
static locale_initializer initializer;
|
|
|
|
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace
|
|
|
|
} // namespace lyx
|
2006-10-03 19:27:17 +00:00
|
|
|
#endif
|