diff options
Diffstat (limited to 'rhtvision/classes/tvintl.cc')
-rw-r--r-- | rhtvision/classes/tvintl.cc | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/rhtvision/classes/tvintl.cc b/rhtvision/classes/tvintl.cc new file mode 100644 index 0000000..974ac16 --- /dev/null +++ b/rhtvision/classes/tvintl.cc @@ -0,0 +1,298 @@ +/* Internationalization support routines. + Copyright by Salvador E. Tropea (SET) (2003-2005) + Covered by the GPL license. */ + +#define Uses_string +#define Uses_ctype +#define Uses_stdlib +#define Uses_stdarg +#define Uses_stdio +#define Uses_snprintf +#define Uses_limits +#ifdef MSS + #define __MSS_USED__ + #undef MSS +#endif +#include <compatlayer.h> +#ifdef __MSS_USED__ + #define MSS + #undef __MSS_USED__ +#endif +#include <locale.h> +#include <tv/ttypes.h> +#define Uses_intl_fprintf +#include <tv/intl.h> +#include <tv.h> + +#ifdef HAVE_INTL_SUPPORT + +#define Uses_TVCodePage +class TVPartitionTree556; +#include <tv/codepage.h> + +// Prototypes, we know they exists +#ifndef _LIBINTL_H +extern "C" { +char *textdomain(const char *domainname); +char *bindtextdomain(const char *domainname, const char *dirname); +char *gettext(const char *msgid); +char *dgettext(const char *domain, const char *msgid); +char *gettext__(const char *msgid); +char *__gettext(const char *msgid); +} +#endif + +// Small mess to determine which function provides "gettext" +// Must use __DJGPP__ here +#ifndef __DJGPP__ +# if !defined(__GLIBC__) || __GLIBC__<2 + // By default use gettext +# define LibGetTextLow gettext +# else +# if (__GLIBC__==2 && __GLIBC_MINOR__>0) || __GLIBC__>2 +# define LibGetTextLow gettext +# else + // exception: glibc 2.0 needs __gettext +# define LibGetTextLow __gettext +# endif +# endif +#else +# define LibGetTextLow gettext__ +#endif + +char TVIntl::translate=0; +char TVIntl::initialized=0; +char TVIntl::needsRecode=0; +int TVIntl::forcedCatalogEncoding=-1; +int TVIntl::catalogEncoding=885901; +uchar TVIntl::recodeTable[256]; +void *TVIntl::previousCPCallBack=NULL; +char TVIntl::packageName[20]; + +const char *TVIntl::defaultEncodingNames[]= +{ + "de", + "es", + "pl", + "ru" +}; +int TVIntl::defaultEncodings[]= +{ + 885901, // de + 885901, // es + 885902, // pl + 100000 // ru +}; +const int numEncs=3; + + +void TVIntl::initialize() +{ + if (initialized) return; + initialized=1; + const char *lang=getenv("LANG"); + if (lang) + { + translate=1; + int i; + char c0=tolower(lang[0]); + char c1=tolower(lang[1]); + for (i=0; i<numEncs; i++) + if (defaultEncodingNames[i][0]==c0 && defaultEncodingNames[i][1]==c1) + { + catalogEncoding=defaultEncodings[i]; + break; + } + previousCPCallBack=(void *)TVCodePage::SetCallBack(codePageCB); + codePageCB(NULL); + CLY_snprintf(packageName,libPackageNameLen,"tvision%s",TV_VERSION); + } +} + +void TVIntl::codePageCB(ushort *map) +{ + int curAppCP=TVCodePage::GetAppCodePage(); + if (translate) + { + int cpCatalog=forcedCatalogEncoding==-1 ? catalogEncoding : forcedCatalogEncoding; + needsRecode=(cpCatalog!=curAppCP); + if (needsRecode) + TVCodePage::FillGenericRemap(cpCatalog,curAppCP,recodeTable); + } + if (map && previousCPCallBack) + ((TVCodePageCallBack)previousCPCallBack)(map); +} + +const char *TVIntl::textDomain(const char *domainname) +{ + initialize(); + return (const char *)textdomain(domainname); +} + +const char *TVIntl::bindTextDomain(const char *domainname, const char *dirname) +{ + initialize(); + return (const char *)bindtextdomain(domainname,dirname); +} + +const char *TVIntl::getText(const char *msgid) +{ + if (!msgid || !msgid[0]) // gettext 0.14.4 feature: "" -> "Project-Id-Version... + return msgid; + const char *msgstr=LibGetTextLow(msgid); + if (msgid==msgstr) + msgstr=dgettext(packageName,msgstr); + return msgstr; +} + +void TVIntl::recodeStr(char *str, int len) +{ + int i; + uchar *s=(uchar *)str; + for (i=0; i<len; i++) + s[i]=s[i]>127 ? recodeTable[s[i]] : s[i]; +} + +char *TVIntl::getTextNew(const char *msgid, Boolean onlyIntl) +{ + if (!msgid) return NULL; + const char *source; + if (translate) + source=getText(msgid); + else + source=msgid; + if (onlyIntl && source==msgid) + return NULL; + int len=strlen(source)+1; + char *ret=new char[len]; + memcpy(ret,source,len); + if (needsRecode) + { + //printf("Recodificando %s a ",ret); + recodeStr(ret,len-1); + //printf("%s\n",ret); + } + return ret; +} + +const char *TVIntl::getText(const char *msgid, stTVIntl *&cache) +{ + if (!translate || !msgid) return msgid; + int curCP=TVCodePage::GetAppCodePage(); + if (!cache) + cache=new stTVIntl; + else + { + if (cache->cp==-2) + return msgid; + if (curCP==cache->cp) + return cache->translation ? cache->translation : msgid; + DeleteArray(cache->translation); + } + cache->translation=getTextNew(msgid,True); + cache->cp=curCP; + return cache->translation ? cache->translation : msgid; +} + +void TVIntl::freeSt(stTVIntl *&cache) +{ + if (!cache) return; + DeleteArray(cache->translation); + delete cache; + cache=NULL; +} + +stTVIntl *TVIntl::emptySt() +{ + stTVIntl *p=new stTVIntl[1]; // It will be inserted in a TStringColletion + // where delete[] is used. + p->translation=NULL; + p->cp=-1; + return p; +} + +stTVIntl *TVIntl::dontTranslateSt() +{ + stTVIntl *p=new stTVIntl; + p->translation=NULL; + p->cp=-2; + return p; +} + +int TVIntl::snprintf(char *dest, size_t sz, const char *fmt, ...) +{ + va_list argptr; + char *intlFmt=getTextNew(fmt); + va_start(argptr,fmt); + int l=CLY_vsnprintf(dest,sz,intlFmt,argptr); + va_end(argptr); + DeleteArray(intlFmt); + return l; +} + +int TVIntl::fprintf(FILE *f, const char *fmt, ...) +{ + va_list argptr; + char *intlFmt=getTextNew(fmt); + va_start(argptr,fmt); + int l=vfprintf(f,intlFmt,argptr); + va_end(argptr); + DeleteArray(intlFmt); + return l; +} + +#if defined(TVOS_DOS) || (defined(TVOS_Win32) && !defined(TVCompf_Cygwin)) + #define NoHomeOrientedOS +#endif + +int TVIntl::autoInit(const char *package, const char *localeDir) +{ + char localedir[PATH_MAX]; + setlocale(LC_ALL, ""); + if (!localeDir) + localeDir=getenv("LOCALEDIR"); + + if (!localeDir) + { + #ifdef NoHomeOrientedOS + // if LOCALEDIR doesn't exists use %DJDIR%/share/locale + localeDir=getenv("DJDIR"); + if (localeDir) + { + strcpy(localedir,localeDir); + strcat(localedir,"/share/locale"); + } + else + return 0; + #else + strcpy(localedir,"/usr/share/locale"); + #endif + } + else + strcpy(localedir,localeDir); + + bindTextDomain(package,localedir); + textDomain(package); + return 1; +} + +#else +int TVIntl::snprintf(char *dest, size_t sz, const char *fmt, ...) +{ + va_list argptr; + va_start(argptr,fmt); + int l=CLY_vsnprintf(dest,sz,fmt,argptr); + va_end(argptr); + return l; +} + +int TVIntl::fprintf(FILE *f, const char *fmt, ...) +{ + va_list argptr; + va_start(argptr,fmt); + int l=vfprintf(f,fmt,argptr); + va_end(argptr); + return l; +} +#endif /* HAVE_INTL_SUPPORT */ + |