diff options
| author | Vanilla I. Shu <vanilla@FreeBSD.org> | 2016-12-02 03:41:46 +0000 |
|---|---|---|
| committer | Vanilla I. Shu <vanilla@FreeBSD.org> | 2016-12-02 03:41:46 +0000 |
| commit | 951bf73705e853855ae55c00c5a45b7f709a1b34 (patch) | |
| tree | c2ad8af49564883b40496a039de06f0e79438ca9 /chinese/mutt/files/patch-myiconv.c | |
| parent | textproc/codespell: Update to version 1.8. (diff) | |
Fix building with mutt-1.7.2.
MFH: 2016Q4
Notes
Notes:
svn path=/head/; revision=427541
Diffstat (limited to 'chinese/mutt/files/patch-myiconv.c')
| -rw-r--r-- | chinese/mutt/files/patch-myiconv.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/chinese/mutt/files/patch-myiconv.c b/chinese/mutt/files/patch-myiconv.c new file mode 100644 index 000000000000..269934a09a2b --- /dev/null +++ b/chinese/mutt/files/patch-myiconv.c @@ -0,0 +1,170 @@ +--- myiconv.c.orig 2016-12-02 11:18:42.601104000 +0800 ++++ myiconv.c 2016-12-02 11:18:42.601603000 +0800 +@@ -0,0 +1,167 @@ ++/* ++ * Contributed by Kuang-che Wu <kcwu@kcwu.dyndns.org> ++ */ ++#if HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include "mutt.h" ++#include "charset.h" ++#include <hz.h> ++#include <dlfcn.h> ++ ++ ++ ++#ifdef HAVE_ICONV ++ ++typedef struct myiconv { ++ iconv_t cd; ++ int incode,outcode; ++ int myjob; ++} myiconv_t; ++ ++static int is_init; ++static void *dlh; ++static iconv_t (*old_iconv_open)(const char *tocode, const char *fromcode); ++static size_t (*old_iconv)(iconv_t cd, ICONV_CONST char **inbuf, ++ size_t *inbytesleft, char **outbuf, size_t *outbytesleft); ++static int (*old_iconv_close) (iconv_t cd); ++static int inst; ++ ++static void init(void) ++{ ++ hz_setup(); ++ dlh=dlopen("libiconv.so",RTLD_LAZY); ++ if(dlh) { ++ old_iconv_open=dlsym(dlh,"iconv_open"); ++ old_iconv=dlsym(dlh,"iconv"); ++ old_iconv_close=dlsym(dlh,"iconv_close"); ++ } ++ is_init=1; ++} ++ ++static size_t myconv(ICONV_CONST char **inbuf, ++ size_t *inbytesleft, char **outbuf, size_t *outbytesleft) ++{ ++ /* reference to autogb.c */ ++ int count; ++ char buff[MAX_BUFFER*3]; ++ char *pbuf,*ps; ++ size_t rt=0; ++ ++ pbuf=&buff[2]; ++ ++ count=*inbytesleft; ++ if(count>MAX_BUFFER) count=MAX_BUFFER; ++ memcpy(pbuf,*inbuf,count); ++ *inbuf+=count; ++ *inbytesleft-=count; ++ while(count>0) { ++ rt+=count; ++ ps=hz_convert(pbuf,&count,0); ++ memcpy(*outbuf,ps,count); ++ *outbuf+=count; *outbytesleft+=count; ++ pbuf=&buff[2]; ++ ++ count=*inbytesleft; ++ if(count>MAX_BUFFER) count=MAX_BUFFER; ++ memcpy(pbuf,*inbuf,count); ++ *inbuf+=count; ++ *inbytesleft-=count; ++ } ++ return rt; ++} ++ ++int conv_str(const char* str_code) ++{ ++ int i; ++ char *str; ++ struct mapping { ++ char *code; ++ int value; ++ } map[]={ ++ {"gb2312",GB_CODE}, ++ {"euccn",GB_CODE}, ++ {"big5",BIG5_CODE}, ++ {0,OTHER_CODE}, /* should we handle below cases? */ ++ {"hz",HZ_CODE}, ++ {"uni",UNI_CODE}, ++ {"utf7",UTF7_CODE}, ++ {"utf8",UTF8_CODE}, ++ }; ++ str=strdup(str_code); ++ if(strchr(str,'/')) ++ *strchr(str,'/')=0; ++ for(i=0;map[i].code;i++) ++ if(mutt_chscmp(str,map[i].code)) ++ break; ++ free(str); ++ return map[i].value; ++} ++ ++iconv_t iconv_open (const char *tocode, const char *fromcode) ++{ ++ myiconv_t *mycd=(myiconv_t*)-1; ++ iconv_t cd; ++ char *_tocode, *_fromcode; ++ ++ _tocode = tocode; ++ _fromcode = fromcode; ++ ++ if (!mutt_strcmp(tocode,"big5")) _tocode = "big5-hkscs"; ++ if (!mutt_strcmp(fromcode,"big5")) _fromcode = "big5-hkscs"; ++ ++ if(!is_init) init(); ++ if(!old_iconv_open) ++ return (iconv_t)(-1); ++ ++ if((cd=old_iconv_open(_tocode,_fromcode))!=(iconv_t)-1) { ++ mycd=(myiconv_t*)calloc(1,sizeof(myiconv_t)); ++ mycd->cd=cd; ++ mycd->incode=conv_str(fromcode); ++ mycd->outcode=conv_str(tocode); ++ /* inst==0 is because: ++ libhz only has one stack, and ++ it will destroy all instance's data when setup stack. ++ ++ If want to fix, libhz's init func should know which inst. ++ */ ++ if(inst==0 && mycd->incode!=mycd->outcode && ++ hz_search(mycd->incode,mycd->outcode,8)) { ++ inst++; ++ mycd->myjob=1; ++ } ++ } ++ return (iconv_t)mycd; ++} ++ ++size_t iconv (iconv_t cd, ICONV_CONST char **inbuf, size_t *inbytesleft, ++ char **outbuf, size_t *outbytesleft) ++{ ++ myiconv_t *mycd=(myiconv_t*)cd; ++ size_t rt=(size_t)0; ++ if(mycd->myjob) { ++ if(!inbuf || !*inbuf || !outbuf || !*outbuf) ++ hz_search(mycd->incode,mycd->outcode,8); ++ else ++ rt=myconv(inbuf,inbytesleft,outbuf,outbytesleft); ++ } else if(old_iconv) ++ rt=old_iconv(mycd->cd,inbuf,inbytesleft,outbuf,outbytesleft); ++ return rt; ++} ++ ++int iconv_close (iconv_t cd) ++{ ++ myiconv_t *mycd=(myiconv_t*)cd; ++ if(!old_iconv_close) ++ return 0; ++ old_iconv_close(mycd->cd); ++ if(mycd->myjob) ++ inst--; ++ free(mycd); ++ return 0; ++} ++ ++#endif |
