diff --git a/golded3/geglob.cpp b/golded3/geglob.cpp index 753ce7f..a8995af 100644 --- a/golded3/geglob.cpp +++ b/golded3/geglob.cpp @@ -81,6 +81,10 @@ EscTab* I51TP = NULL; EscTab* MNETP = NULL; ChsTab* ChsTP = NULL; +#ifdef HAS_ICONV +iconv_t iconv_cd = (iconv_t)(-1); +#endif + bool quiet = true; bool ignore = false; int cfgerrors = 0; diff --git a/golded3/geglob.h b/golded3/geglob.h index 5fc9fdc..a20b0e9 100644 --- a/golded3/geglob.h +++ b/golded3/geglob.h @@ -35,6 +35,10 @@ // ------------------------------------------------------------------ +#ifdef HAS_ICONV + #include +#endif + extern glog LOG; extern gareafile* AFILE; @@ -128,6 +132,10 @@ extern EscTab* I51TP; extern EscTab* MNETP; extern ChsTab* ChsTP; +#ifdef HAS_ICONV +extern iconv_t iconv_cd; +#endif + //extern char gversion[]; extern bool quiet; diff --git a/golded3/geline.cpp b/golded3/geline.cpp index cecfe27..c1d4d01 100644 --- a/golded3/geline.cpp +++ b/golded3/geline.cpp @@ -34,6 +34,10 @@ #include #endif +#ifdef HAS_ICONV + #include +#endif + // ------------------------------------------------------------------ @@ -1731,12 +1735,29 @@ void Latin2Local(std::string &str) str = temp; } +// ------------------------------------------------------------------ + +#ifdef HAS_ICONV +void IconvClear(void){ + if( iconv_cd!=(iconv_t)(-1) ){ + iconv_close(iconv_cd); + iconv_cd = (iconv_t)(-1); + } +} +#endif // ------------------------------------------------------------------ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded, bool i51) { - if(not chrtbl) + if( src==NULL ) + return dest; + + if( not chrtbl +#ifdef HAS_ICONV + && iconv_cd==(iconv_t)(-1) +#endif + ) return stpcpy(dest, src); uint n; @@ -1749,6 +1770,12 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded char dochar; ChsTab* chrs = chrtbl ? chrtbl->t : (ChsTab*)NULL; +#ifdef HAS_ICONV + size_t iconvrc=-1; + if( iconv_cd!=(iconv_t)(-1) ){ + iconvrc=iconv( iconv_cd, NULL, NULL, NULL, NULL ); // init iconv + } +#endif while(*sptr) { switch(*sptr) { case 0x02: @@ -1858,6 +1885,31 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded dochar = *sptr++; chardo: // Translate level 1 and 2 + #ifdef HAS_ICONV + if( iconv_cd!=(iconv_t)(-1) ){ + unsigned srcleft=1; + unsigned dstleft=3; + char* tsptr = &dochar; + + iconvrc=iconv( iconv_cd, &tsptr, &srcleft, &dptr, &dstleft ); + if( iconvrc==((size_t)-1) ){ + switch( errno ){ + case EINVAL: + LOG.printf("An incomplete multibyte sequence has been encountered before:"); + LOG.printf("%s",sptr); + case EILSEQ: + LOG.printf("An invalid multibyte sequence has been encountered in the input before:"); + LOG.printf("%s",sptr); + case E2BIG: + LOG.printf("There is not sufficient destination size before '%s'", sptr); + default: + LOG.printf("Unknown error %u in iconv() before %s", errno, sptr); + } + } + } + else + #endif + if (((level == 1) || (level == 2)) && chrs) { tptr = (char*)chrs[(byte)dochar]; @@ -2968,6 +3020,16 @@ int LoadCharset(const char* imp, const char* exp, int query) { break; } +#ifdef HAS_ICONV + if( iconv_cd != (iconv_t)(-1) ) + iconv_close(iconv_cd); + iconv_cd = iconv_open(imp,exp); + if(iconv_cd != (iconv_t)(-1) ) + LOG.printf("iconv is initialised to convert from %s to %s", imp, exp); + else + LOG.printf("Can't initialise iconv to convert from %s to %s", imp, exp); +#endif + // Find and load charset table std::vector::iterator xlt; for(n = 0, xlt = CFG->xlatcharset.begin(); xlt != CFG->xlatcharset.end(); xlt++, n++) diff --git a/golded3/geprot.h b/golded3/geprot.h index ef11cc3..e2c2da9 100644 --- a/golded3/geprot.h +++ b/golded3/geprot.h @@ -186,7 +186,10 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded char* mime_header_decode(char* decoded, const char* encoded, char* charset = NULL); char* strxmimecpy(char* dest, const char* source, int level, int size, bool detect = false); void InvalidateControlInfo(GMsg *msg); - +#ifdef HAS_ICONV +void IconvClear(void); +#endif + // ------------------------------------------------------------------ // GEMENU prototypes @@ -444,7 +447,7 @@ uint32_t getClassicMsgId(); // ------------------------------------------------------------------ // SOFTCR management - + inline bool issoftcr(char c) { return (c == SOFTCR) and not WideDispsoftcr; diff --git a/golded3/geread.cpp b/golded3/geread.cpp index b1a7a46..c343788 100644 --- a/golded3/geread.cpp +++ b/golded3/geread.cpp @@ -1041,6 +1041,10 @@ void Reader() { // Invalidate reader_msg since the actual data has just been freed. reader_msg = NULL; + #ifdef HAS_ICONV + IconvClear(); + #endif + HandleGEvent(EVTT_EXIT); }