Skip to content
This repository has been archived by the owner on Oct 10, 2019. It is now read-only.

Check for iconv() TRANSLIT support #365

Merged
merged 2 commits into from
Oct 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class utils {
static bool try_fs_lock(const std::string& lock_file, pid_t & pid);
static void remove_fs_lock(const std::string& lock_file);

static std::string translit(const char* tocode, const std::string& fromcode);
static std::string translit(const std::string& tocode, const std::string& fromcode);
static std::string convert_text(const std::string& text, const std::string& tocode, const std::string& fromcode);

static std::string get_command_output(const std::string& cmd);
Expand Down
5 changes: 3 additions & 2 deletions src/stflpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cerrno>

#include <langinfo.h>
#include <utils.h>

namespace newsbeuter {

Expand All @@ -16,7 +17,7 @@ namespace newsbeuter {
*/

stfl::form::form(const std::string& text) : f(0) {
ipool = stfl_ipool_create((std::string(nl_langinfo(CODESET)) + "//TRANSLIT").c_str());
ipool = stfl_ipool_create(utils::translit(nl_langinfo(CODESET), "WCHAR_T").c_str());
if (!ipool) {
throw exception(errno);
}
Expand Down Expand Up @@ -82,7 +83,7 @@ static std::mutex quote_mtx;

std::string stfl::quote(const std::string& text) {
std::lock_guard<std::mutex> lock(quote_mtx);
stfl_ipool * ipool = stfl_ipool_create((std::string(nl_langinfo(CODESET)) + "//TRANSLIT").c_str());
stfl_ipool * ipool = stfl_ipool_create(utils::translit(nl_langinfo(CODESET), "WCHAR_T").c_str());
std::string retval = stfl_ipool_fromwc(ipool,stfl_quote(stfl_ipool_towc(ipool,text.c_str())));
stfl_ipool_destroy(ipool);
return retval;
Expand Down
49 changes: 47 additions & 2 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,59 @@ bool utils::try_fs_lock(const std::string& lock_file, pid_t & pid) {
return false;
}

std::string utils::translit(const char* tocode, const std::string& fromcode)
{
return translit(std::string(tocode), fromcode);
}

std::string utils::translit(const std::string& tocode, const std::string& fromcode)
{
std::string tlit = "//TRANSLIT";

typedef enum translit_state {
UNKNOWN,
SUPPORTED,
UNSUPPORTED
} translit_state_t;

static translit_state_t state = UNKNOWN;

// TRANSLIT is not needed when converting to unicode encodings
if (tocode == "utf-8" || tocode == "WCHAR_T") return tocode;

if (state == UNKNOWN) {
iconv_t cd = ::iconv_open((tocode + "//TRANSLIT").c_str(), fromcode.c_str());

if (cd == reinterpret_cast<iconv_t>(-1)) {
if (errno == EINVAL) {
iconv_t cd = ::iconv_open(tocode.c_str(), fromcode.c_str());
if (cd != reinterpret_cast<iconv_t>(-1)) {
state = UNSUPPORTED;
} else {
fprintf(stderr, "iconv_open('%s', '%s') failed: %s", tocode.c_str(), fromcode.c_str(), strerror(errno));
abort();
}
} else {
fprintf(stderr, "iconv_open('%s//TRANSLIT', '%s') failed: %s", tocode.c_str(), fromcode.c_str(), strerror(errno));
abort();
}
} else {
state = SUPPORTED;
}

iconv_close(cd);
}

return ((state == SUPPORTED) ? (tocode + tlit) : (tocode));
}

std::string utils::convert_text(const std::string& text, const std::string& tocode, const std::string& fromcode) {
std::string result;

if (strcasecmp(tocode.c_str(), fromcode.c_str())==0)
return text;

iconv_t cd = ::iconv_open((tocode + "//TRANSLIT").c_str(), fromcode.c_str());
iconv_t cd = ::iconv_open(translit(tocode, fromcode).c_str(), fromcode.c_str());

if (cd == reinterpret_cast<iconv_t>(-1))
return result;
Expand Down Expand Up @@ -499,7 +544,7 @@ std::wstring utils::str2wstr(const std::string& str) {

std::string utils::wstr2str(const std::wstring& wstr) {
std::string codeset = nl_langinfo(CODESET);
codeset.append("//TRANSLIT");
codeset = translit(codeset, "WCHAR_T");
struct stfl_ipool * ipool = stfl_ipool_create(codeset.c_str());
std::string result = stfl_ipool_fromwc(ipool, wstr.c_str());
stfl_ipool_destroy(ipool);
Expand Down