[rkward/frameworks] rkward/rbackend: Replace locale update hack with Qt's new mechnism for updating the current default QTextCodec.
Thomas Friedrichsmeier
null at kde.org
Fri May 19 10:47:05 UTC 2017
Git commit 3e2b9a16960cb3eb2061c219c58a200175cf5567 by Thomas Friedrichsmeier.
Committed on 19/05/2017 at 10:45.
Pushed by tfry into branch 'frameworks'.
Replace locale update hack with Qt's new mechnism for updating the current default QTextCodec.
Also, use QTextEncoder / QTextDecoder to get defined behavior on non-representable characters.
This should hopefully fix a crash on startup on Windows.
D +0 -269 rkward/rbackend/rklocalesupport.cpp
D +0 -26 rkward/rbackend/rklocalesupport.h
M +24 -19 rkward/rbackend/rkrbackend.cpp
M +10 -3 rkward/rbackend/rkrbackend.h
M +2 -2 rkward/rbackend/rkrsupport.cpp
https://commits.kde.org/rkward/3e2b9a16960cb3eb2061c219c58a200175cf5567
diff --git a/rkward/rbackend/rklocalesupport.cpp b/rkward/rbackend/rklocalesupport.cpp
deleted file mode 100644
index 49a6d268..00000000
--- a/rkward/rbackend/rklocalesupport.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/***************************************************************************
- rklocalesupport - description
- -------------------
- begin : Sun Mar 11 2007
- copyright : (C) 2007, 2009 by Thomas Friedrichsmeier
- email : thomas.friedrichsmeier at kdemail.net
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "rklocalesupport.h"
-
-#include <qtextcodec.h>
-#include <QByteArray>
-
-#ifndef Q_OS_WIN
- // see http://sourceforge.net/p/rkward/patches/4/
- // seems to be needed for GCC 4.3 as well.
-# include <langinfo.h>
-#endif
-#include <stdlib.h>
-#include <locale.h>
-#include <ctype.h>
-
-/* NOTE: The code in this file is an almost literal copy taken from setupLocaleMapper in qtextcodec.cpp in Qt 3.3.8 !*/
-
-QTextCodec *checkForCodec(const char *name) {
- QTextCodec *c = QTextCodec::codecForName(name);
- if (!c) {
- const char *at = strchr(name, '@');
- if (at) {
- QByteArray n(name, at - name);
- c = QTextCodec::codecForName(n.data());
- }
- }
- return c;
-}
-
-/* locale names mostly copied from XFree86 */
-static const char * const iso8859_2locales[] = {
- "croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
- "hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
- "ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
- "sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
-
-static const char * const iso8859_3locales[] = {
- "eo", 0 };
-
-static const char * const iso8859_4locales[] = {
- "ee", "ee_EE", 0 };
-
-static const char * const iso8859_5locales[] = {
- "mk", "mk_MK", "sp", "sp_YU", 0 };
-
-static const char * const cp_1251locales[] = {
- "be", "be_BY", "bg", "bg_BG", "bulgarian", 0 };
-
-static const char * const pt_154locales[] = {
- "ba_RU", "ky", "ky_KG", "kk", "kk_KZ", 0 };
-
-static const char * const iso8859_6locales[] = {
- "ar_AA", "ar_SA", "arabic", 0 };
-
-static const char * const iso8859_7locales[] = {
- "el", "el_GR", "greek", 0 };
-
-static const char * const iso8859_8locales[] = {
- "hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
-
-static const char * const iso8859_9locales[] = {
- "tr", "tr_TR", "turkish", 0 };
-
-static const char * const iso8859_13locales[] = {
- "lt", "lt_LT", "lv", "lv_LV", 0 };
-
-static const char * const iso8859_15locales[] = {
- "et", "et_EE",
- // Euro countries
- "br_FR", "ca_ES", "de", "de_AT", "de_BE", "de_DE", "de_LU", "en_IE",
- "es", "es_ES", "eu_ES", "fi", "fi_FI", "finnish", "fr", "fr_FR",
- "fr_BE", "fr_LU", "french", "ga_IE", "gl_ES", "it", "it_IT", "oc_FR",
- "nl", "nl_BE", "nl_NL", "pt", "pt_PT", "sv_FI", "wa_BE",
- 0 };
-
-static const char * const koi8_ulocales[] = {
- "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
-
-static const char * const tis_620locales[] = {
- "th", "th_TH", "thai", 0 };
-
-static const char * const tcvnlocales[] = {
- "vi", "vi_VN", 0 };
-
-static bool try_locale_list( const char * const locale[], const char * lang )
-{
- int i;
- for( i=0; locale[i] && *locale[i] && strcmp(locale[i], lang); i++ )
- ;
- return locale[i] != 0;
-}
-
-// For the probably_koi8_locales we have to look. the standard says
-// these are 8859-5, but almost all Russian users use KOI8-R and
-// incorrectly set $LANG to ru_RU. We'll check tolower() to see what
-// tolower() thinks ru_RU means.
-
-// If you read the history, it seems that many Russians blame ISO and
-// Perestroika for the confusion.
-//
-// The real bug is that some programs break if the user specifies
-// ru_RU.KOI8-R.
-
-static const char * const probably_koi8_rlocales[] = {
- "ru", "ru_SU", "ru_RU", "russian", 0 };
-
-static QTextCodec * ru_RU_hack( const char * i ) {
- QTextCodec * ru_RU_codec = 0;
-
- QByteArray origlocale(setlocale(LC_CTYPE, i));
- // unicode koi8r latin5 name
- // 0x044E 0xC0 0xEE CYRILLIC SMALL LETTER YU
- // 0x042E 0xE0 0xCE CYRILLIC CAPITAL LETTER YU
- int latin5 = tolower( 0xCE );
- int koi8r = tolower( 0xE0 );
- if ( koi8r == 0xC0 && latin5 != 0xEE ) {
- ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
- } else if ( koi8r != 0xC0 && latin5 == 0xEE ) {
- ru_RU_codec = QTextCodec::codecForName( "ISO 8859-5" );
- } else {
- // something else again... let's assume... *throws dice*
- ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
- qWarning( "QTextCodec: using KOI8-R, probe failed (%02x %02x %s)",
- koi8r, latin5, i );
- }
- setlocale( LC_CTYPE, origlocale.data() );
-
- return ru_RU_codec;
-}
-
-QTextCodec *RKGetCurrentLocaleCodec () {
-
- QTextCodec *localeMapper = 0;
-
-#ifdef Q_OS_WIN32
- localeMapper = QTextCodec::codecForName( "System" );
-#else
-
-#if defined (_XOPEN_UNIX) && !defined(Q_OS_QNX6) && !defined(Q_OS_OSF) && !defined(Q_OS_MAC)
- char *charset = nl_langinfo (CODESET);
- if ( charset )
- localeMapper = QTextCodec::codecForName( charset );
-#endif
-
- if ( !localeMapper ) {
- // Very poorly defined and followed standards causes lots of code
- // to try to get all the cases...
-
- // Try to determine locale codeset from locale name assigned to
- // LC_CTYPE category.
-
- // First part is getting that locale name. First try setlocale() which
- // definitely knows it, but since we cannot fully trust it, get ready
- // to fall back to environment variables.
- char * ctype = qstrdup( setlocale( LC_CTYPE, 0 ) );
-
- // Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
- // environment variables.
- char * lang = qstrdup( getenv("LC_ALL") );
- if ( !lang || lang[0] == 0 || strcmp( lang, "C" ) == 0 ) {
- if ( lang ) delete [] lang;
- lang = qstrdup( getenv("LC_CTYPE") );
- }
- if ( !lang || lang[0] == 0 || strcmp( lang, "C" ) == 0 ) {
- if ( lang ) delete [] lang;
- lang = qstrdup( getenv("LANG") );
- }
-
- // Now try these in order:
- // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
- // 2. CODESET from lang if it contains a .CODESET part
- // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
- // 4. locale (ditto)
- // 5. check for "@euro"
- // 6. guess locale from ctype unless ctype is "C"
- // 7. guess locale from lang
-
- // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15)
- char * codeset = ctype ? strchr( ctype, '.' ) : 0;
- if ( codeset && *codeset == '.' )
- localeMapper = checkForCodec( codeset + 1 );
-
- // 2. CODESET from lang if it contains a .CODESET part
- codeset = lang ? strchr( lang, '.' ) : 0;
- if ( !localeMapper && codeset && *codeset == '.' )
- localeMapper = checkForCodec( codeset + 1 );
-
- // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
- if ( !localeMapper && ctype && *ctype != 0 && strcmp (ctype, "C") != 0 )
- localeMapper = checkForCodec( ctype );
-
- // 4. locale (ditto)
- if ( !localeMapper && lang && *lang != 0 )
- localeMapper = checkForCodec( lang );
-
- // 5. "@euro"
- if ( !localeMapper && ctype && strstr( ctype, "@euro" ) || lang && strstr( lang, "@euro" ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-15" );
-
- // 6. guess locale from ctype unless ctype is "C"
- // 7. guess locale from lang
- char * try_by_name = ctype;
- if ( ctype && *ctype != 0 && strcmp (ctype, "C") != 0 )
- try_by_name = lang;
-
- // Now do the guessing.
- if ( lang && *lang && !localeMapper && try_by_name && *try_by_name ) {
- if ( try_locale_list( iso8859_15locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-15" );
- else if ( try_locale_list( iso8859_2locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-2" );
- else if ( try_locale_list( iso8859_3locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-3" );
- else if ( try_locale_list( iso8859_4locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-4" );
- else if ( try_locale_list( iso8859_5locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-5" );
- else if ( try_locale_list( iso8859_6locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-6" );
- else if ( try_locale_list( iso8859_7locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-7" );
- else if ( try_locale_list( iso8859_8locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-8-I" );
- else if ( try_locale_list( iso8859_9locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-9" );
- else if ( try_locale_list( iso8859_13locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-13" );
- else if ( try_locale_list( tis_620locales, lang ) )
- localeMapper = QTextCodec::codecForName( "ISO 8859-11" );
- else if ( try_locale_list( koi8_ulocales, lang ) )
- localeMapper = QTextCodec::codecForName( "KOI8-U" );
- else if ( try_locale_list( cp_1251locales, lang ) )
- localeMapper = QTextCodec::codecForName( "CP 1251" );
- else if ( try_locale_list( pt_154locales, lang ) )
- localeMapper = QTextCodec::codecForName( "PT 154" );
- else if ( try_locale_list( probably_koi8_rlocales, lang ) )
- localeMapper = ru_RU_hack( lang );
- }
-
- delete [] ctype;
- delete [] lang;
- }
- if ( localeMapper && localeMapper->mibEnum() == 11 )
- localeMapper = QTextCodec::codecForName( "ISO 8859-8-I" );
-
- // If everything failed, we default to 8859-1
- // We could perhaps default to 8859-15.
- if ( !localeMapper )
- localeMapper = QTextCodec::codecForName( "ISO 8859-1" );
-#endif
- return localeMapper;
-}
-
diff --git a/rkward/rbackend/rklocalesupport.h b/rkward/rbackend/rklocalesupport.h
deleted file mode 100644
index 866a175f..00000000
--- a/rkward/rbackend/rklocalesupport.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/***************************************************************************
- rklocalesupport - description
- -------------------
- begin : Sun Mar 11 2007
- copyright : (C) 2007 by Thomas Friedrichsmeier
- email : thomas.friedrichsmeier at kdemail.net
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef RKLOCALESUPPORT_H
-#define RKLOCALESUPPORT_H
-
-class QTextCodec;
-
-/** Helper function to determine the QTextCodec best suited to recode the current CTYPE to UTF-8 */
-QTextCodec *RKGetCurrentLocaleCodec ();
-
-#endif
diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index bc3eebb5..ce5bab98 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -45,7 +45,6 @@ void* RKRBackend::default_global_context = 0;
#include "rkrsupport.h"
#include "rkstructuregetter.h"
-#include "rklocalesupport.h"
#include "rksignalsupport.h"
#include "rkreventloop.h"
#include "../misc/rkcommonfunctions.h"
@@ -307,7 +306,7 @@ int RReadConsole (const char* prompt, unsigned char* buf, int buflen, int hist)
RKRBackend::repl_status.user_command_completely_transmitted = false;
RKRBackend::repl_status.user_command_parsed_up_to = 0;
RKRBackend::repl_status.user_command_successful_up_to = 0;
- RKRBackend::repl_status.user_command_buffer = RKRBackend::this_pointer->current_locale_codec->fromUnicode (command->command);
+ RKRBackend::repl_status.user_command_buffer = RKRBackend::fromUtf8 (command->command);
RKTransmitNextUserCommandChunk (buf, buflen);
RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::UserCommandTransmitted;
return 1;
@@ -317,7 +316,7 @@ int RReadConsole (const char* prompt, unsigned char* buf, int buflen, int hist)
// fully transmitted, but R is still asking for more? This looks like an incomplete statement.
// HOWEVER: It may also have been an empty statement such as " ", so let's check whether the prompt looks like a "continue" prompt
bool incomplete = false;
- if (RKRBackend::this_pointer->current_locale_codec->toUnicode (prompt) == RKRSupport::SEXPToString (Rf_GetOption (Rf_install ("continue"), R_BaseEnv))) {
+ if (RKRBackend::toUtf8 (prompt) == RKRSupport::SEXPToString (Rf_GetOption (Rf_install ("continue"), R_BaseEnv))) {
incomplete = true;
}
if (incomplete) RKRBackend::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorIncomplete;
@@ -416,7 +415,7 @@ int RReadConsole (const char* prompt, unsigned char* buf, int buflen, int hist)
RK_ASSERT (false); // should not reach this point.
}
- QByteArray localres = RKRBackend::this_pointer->current_locale_codec->fromUnicode (request.params["result"].toString ());
+ QByteArray localres = RKRBackend::fromUtf8 (request.params["result"].toString ());
// need to append a newline, here. TODO: theoretically, RReadConsole comes back for more, if \0 was encountered before \n.
qstrncpy ((char *) buf, localres.left (buflen - 2).append ('\n').data (), buflen);
return 1;
@@ -448,7 +447,7 @@ bool RKRBackend::fetchStdoutStderr (bool forcibly) {
if (bytes <= 0) break;
buffer[bytes] = '\0';
// NOTE: we must not risk blocking inside handleOutput, while the stdout_stderr_mutex is locked!
- handleOutput (current_locale_codec->toUnicode (buffer, bytes), bytes, ROutput::Warning, false);
+ handleOutput (RKRBackend::toUtf8 (buffer), bytes, ROutput::Warning, false);
}
stdout_stderr_mutex.unlock ();
@@ -479,7 +478,7 @@ void RWriteConsoleEx (const char *buf, int buflen, int type) {
if (RKRBackend::this_pointer->killed == RKRBackend::AlreadyDead) return; // this check is mostly for fork()ed clients
if (RKRBackend::repl_status.browser_context == RKRBackend::RKReplStatus::InBrowserContextPreventRecursion) return;
RKRBackend::this_pointer->fetchStdoutStderr (true);
- RKRBackend::this_pointer->handleOutput (RKRBackend::this_pointer->current_locale_codec->toUnicode (buf, buflen), buflen, type == 0 ? ROutput::Output : ROutput::Warning);
+ RKRBackend::this_pointer->handleOutput (RKRBackend::toUtf8 (buf), buflen, type == 0 ? ROutput::Output : ROutput::Warning);
}
/** For R callbacks that we want to disable, entirely */
@@ -596,7 +595,7 @@ int RChooseFile (int isnew, char *buf, int len) {
RKRBackend::this_pointer->handleRequest (&request);
- QByteArray localres = RKRBackend::this_pointer->current_locale_codec->fromUnicode (request.params["result"].toString ());
+ QByteArray localres = RKRBackend::fromUtf8 (request.params["result"].toString ());
qstrncpy ((char *) buf, localres.data (), len);
// return length of filename (strlen (buf))
@@ -731,7 +730,7 @@ void RBusy (int busy) {
if (RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::UserCommandTransmitted) {
if (RKRBackend::this_pointer->current_command->type & RCommand::CCCommand) {
QByteArray chunk = RKRBackend::repl_status.user_command_buffer.mid (RKRBackend::repl_status.user_command_parsed_up_to, RKRBackend::repl_status.user_command_transmitted_up_to - RKRBackend::repl_status.user_command_parsed_up_to);
- RKRBackend::this_pointer->printCommand (RKRBackend::this_pointer->current_locale_codec->toUnicode (chunk));
+ RKRBackend::this_pointer->printCommand (RKRBackend::toUtf8 (chunk));
}
if (RKRBackend::this_pointer->current_command->type & RCommand::CCOutput) {
// flush any previous output caputre and start a new one
@@ -746,11 +745,13 @@ void RBusy (int busy) {
// ############## R Standard callback overrides END ####################
+SEXP doUpdateLocale ();
// NOTE: stdout_stderr_mutex is recursive to support fork()s, better
RKRBackend::RKRBackend () : stdout_stderr_mutex (QMutex::Recursive) {
RK_TRACE (RBACKEND);
- current_locale_codec = QTextCodec::codecForLocale ();
+ current_locale_encoder = 0; // marks locale as not yet initialized
+ doUpdateLocale ();
r_running = false;
current_command = 0;
@@ -915,8 +916,15 @@ SEXP doUpdateLocale () {
RK_TRACE (RBACKEND);
RK_DEBUG (RBACKEND, DL_WARNING, "Changing locale");
- RKRBackend::this_pointer->current_locale_codec = RKGetCurrentLocaleCodec ();
- RK_DEBUG (RBACKEND, DL_WARNING, "New locale codec is %s", RKRBackend::this_pointer->current_locale_codec->name ().data ());
+ if (RKRBackend::this_pointer->current_locale_encoder) {
+ delete (RKRBackend::this_pointer->current_locale_encoder);
+ delete (RKRBackend::this_pointer->current_locale_decoder);
+ QTextCodec::setCodecForLocale (0);
+ RK_ASSERT (QTextCodec::codecForLocale ());
+ RKRBackend::this_pointer->current_locale_encoder = QTextCodec::codecForLocale ()->makeEncoder (QTextCodec::DefaultConversion); // NOTE: shall pass non-representable characters unmodified, rather than stripping them.
+ RKRBackend::this_pointer->current_locale_decoder = QTextCodec::codecForLocale ()->makeDecoder (QTextCodec::DefaultConversion);
+ }
+ RK_DEBUG (RBACKEND, DL_WARNING, "New locale codec is %s", QTextCodec::codecForLocale ()->name ().data ());
return R_NilValue;
}
@@ -925,10 +933,10 @@ SEXP doUpdateLocale () {
SEXP doLocaleName () {
RK_TRACE (RBACKEND);
- RK_ASSERT (RKRBackend::this_pointer->current_locale_codec);
+ RK_ASSERT (QTextCodec::codecForLocale());
SEXP res = Rf_allocVector(STRSXP, 1);
PROTECT (res);
- SET_STRING_ELT (res, 0, Rf_mkChar (RKRBackend::this_pointer->current_locale_codec->name ().data ()));
+ SET_STRING_ELT (res, 0, Rf_mkChar (QTextCodec::codecForLocale()->name ().data ()));
UNPROTECT (1);
return res;
}
@@ -1031,9 +1039,6 @@ bool RKRBackend::startR () {
RKSignalSupport::installSignalProxies (); // for the crash signals
RKSignalSupport::installSigIntAndUsrHandlers (RK_scheduleIntr);
- RKRBackend::this_pointer->current_locale_codec = RKGetCurrentLocaleCodec (); // Ok, why is this needed? Beats me (mostly), but the result is different form codecForLocale() used in initialization:
- // This one will turn non-representable characters into unicode numbers, the other one will just strip them...
- // KF5 TODO: Use makeEncoder() and makeDecoder() to get defined behavior on this
// register our functions
R_CallMethodDef callMethods [] = {
@@ -1140,7 +1145,7 @@ SEXP parseCommand (const QString &command_qstring, RKRBackend::RKWardRError *err
SafeParseWrap wrap;
wrap.status = PARSE_NULL;
- QByteArray localc = RKRBackend::this_pointer->current_locale_codec->fromUnicode (command_qstring); // needed so the string below does not go out of scope
+ QByteArray localc = RKRBackend::fromUtf8 (command_qstring); // needed so the string below does not go out of scope
const char *command = localc.data ();
PROTECT(wrap.cv=Rf_allocVector(STRSXP, 1));
@@ -1366,7 +1371,7 @@ void RKRBackend::catToOutputFile (const QString &out) {
RK_ASSERT (false);
return;
}
- f.write (current_locale_codec->fromUnicode (out));
+ f.write (RKRBackend::fromUtf8 (out));
f.close ();
}
@@ -1427,7 +1432,7 @@ void RKRBackend::commandFinished (bool check_object_updates_needed) {
// This method may look a bit over-complex, but remember that repl_status.user_command_successful_up_to works on an *encoded* buffer
QByteArray remainder_encoded = repl_status.user_command_buffer.mid (repl_status.user_command_successful_up_to);
- QString remainder = current_locale_codec->toUnicode (remainder_encoded);
+ QString remainder = RKRBackend::toUtf8 (remainder_encoded);
current_command->has_been_run_up_to = current_command->command.length () - remainder.length ();
}
diff --git a/rkward/rbackend/rkrbackend.h b/rkward/rbackend/rkrbackend.h
index 637db015..44a056f6 100644
--- a/rkward/rbackend/rkrbackend.h
+++ b/rkward/rbackend/rkrbackend.h
@@ -25,6 +25,8 @@
#include <QMutex>
#include <QStringList>
#include <QEvent>
+#include <QTextEncoder>
+#include <QTextDecoder>
#include "rcommand.h"
#include "rcommandstack.h"
@@ -34,8 +36,6 @@
void RK_scheduleIntr();
#endif
-class QStringList;
-class QTextCodec;
class RInterface;
struct ROutput;
@@ -139,7 +139,14 @@ handleHistoricalSubstackRequest(). Exactly which requests get handled by which f
void kill () { killed = ExitNow; };
bool isKilled () { return (killed != NotKilled); };
- QTextCodec *current_locale_codec;
+ static QString toUtf8 (const char *local_coded) {
+ return this_pointer->current_locale_decoder->toUnicode (local_coded);
+ }
+ static QByteArray fromUtf8 (const QString &uni_coded) {
+ return this_pointer->current_locale_encoder->fromUnicode (uni_coded);
+ }
+ QTextEncoder *current_locale_encoder;
+ QTextDecoder *current_locale_decoder;
struct RKReplStatus {
QByteArray user_command_buffer;
diff --git a/rkward/rbackend/rkrsupport.cpp b/rkward/rbackend/rkrsupport.cpp
index b2726656..e31f188b 100644
--- a/rkward/rbackend/rkrsupport.cpp
+++ b/rkward/rbackend/rkrsupport.cpp
@@ -118,7 +118,7 @@ QStringList RKRSupport::SEXPToStringList (SEXP from_exp) {
} else if (IS_LATIN1 (dummy)) {
list.append (QString::fromLatin1 ((char *) STRING_PTR (dummy)));
} else {
- list.append (RKRBackend::this_pointer->current_locale_codec->toUnicode ((char *) STRING_PTR (dummy)));
+ list.append (RKRBackend::toUtf8 ((char *) STRING_PTR (dummy)));
}
}
}
@@ -136,7 +136,7 @@ SEXP RKRSupport::StringListToSEXP (const QStringList& list) {
SET_STRING_ELT (ret, i, Rf_mkCharCE (list[i].toUtf8 (), CE_UTF8));
#else
// TODO Rf_mkCharCE _might_ have been introduced earlier. Check if still an ongoing concern.
- SET_STRING_ELT (ret, i, Rf_mkChar (RKRBackend::this_pointer->current_locale_codec->fromUnicode (list[i]).data ()));
+ SET_STRING_ELT (ret, i, Rf_mkChar (RKRBackend::fromUtf8 (list[i]).data ()));
#endif
}
return ret;
More information about the rkward-tracker
mailing list