📄 iconv.c
字号:
} to_index = ap->encoding_index; break; } for (from_wchar = 0;;) { /* Search fromcode in the table. */ for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) { unsigned char c = * (unsigned char *) cp; if (c >= 0x80) goto invalid; if (c >= 'a' && c <= 'z') c -= 'a'-'A'; *bp = c; if (c == '\0') break; if (--count == 0) goto invalid; } if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) { bp -= 10; *bp = '\0'; } if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) { bp -= 8; *bp = '\0'; } if (buf[0] == '\0') { fromcode = locale_charset(); /* Avoid an endless loop that could occur when using an older version of localcharset.c. */ if (fromcode[0] == '\0') goto invalid; continue; } ap = aliases_lookup(buf,bp-buf); if (ap == NULL) { ap = aliases2_lookup(buf); if (ap == NULL) goto invalid; } if (ap->encoding_index == ei_local_char) { fromcode = locale_charset(); /* Avoid an endless loop that could occur when using an older version of localcharset.c. */ if (fromcode[0] == '\0') goto invalid; continue; } if (ap->encoding_index == ei_local_wchar_t) {#if __STDC_ISO_10646__ if (sizeof(wchar_t) == 4) { from_index = ei_ucs4internal; break; } if (sizeof(wchar_t) == 2) { from_index = ei_ucs2internal; break; } if (sizeof(wchar_t) == 1) { from_index = ei_iso8859_1; break; }#endif#if HAVE_WCRTOMB from_wchar = 1; fromcode = locale_charset(); continue;#endif goto invalid; } from_index = ap->encoding_index; break; } cd = (struct conv_struct *) malloc(from_wchar != to_wchar ? sizeof(struct wchar_conv_struct) : sizeof(struct conv_struct)); if (cd == NULL) { errno = ENOMEM; return (iconv_t)(-1); } cd->iindex = from_index; cd->ifuncs = all_encodings[from_index].ifuncs; cd->oindex = to_index; cd->ofuncs = all_encodings[to_index].ofuncs; cd->oflags = all_encodings[to_index].oflags; /* Initialize the loop functions. */#if HAVE_MBRTOWC if (to_wchar) {#if HAVE_WCRTOMB if (from_wchar) { cd->lfuncs.loop_convert = wchar_id_loop_convert; cd->lfuncs.loop_reset = wchar_id_loop_reset; } else#endif { cd->lfuncs.loop_convert = wchar_to_loop_convert; cd->lfuncs.loop_reset = wchar_to_loop_reset; } } else#endif {#if HAVE_WCRTOMB if (from_wchar) { cd->lfuncs.loop_convert = wchar_from_loop_convert; cd->lfuncs.loop_reset = wchar_from_loop_reset; } else#endif { cd->lfuncs.loop_convert = unicode_loop_convert; cd->lfuncs.loop_reset = unicode_loop_reset; } } /* Initialize the states. */ memset(&cd->istate,'\0',sizeof(state_t)); memset(&cd->ostate,'\0',sizeof(state_t)); /* Initialize the operation flags. */ cd->transliterate = transliterate; cd->discard_ilseq = discard_ilseq; /* Initialize additional fields. */ if (from_wchar != to_wchar) { struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) cd; memset(&wcd->state,'\0',sizeof(mbstate_t)); } /* Done. */ return (iconv_t)cd;invalid: errno = EINVAL; return (iconv_t)(-1);}size_t iconv (iconv_t icd, ICONV_CONST char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft){ conv_t cd = (conv_t) icd; if (inbuf == NULL || *inbuf == NULL) return cd->lfuncs.loop_reset(icd,outbuf,outbytesleft); else return cd->lfuncs.loop_convert(icd, (const char* *)inbuf,inbytesleft, outbuf,outbytesleft);}int iconv_close (iconv_t icd){ conv_t cd = (conv_t) icd; free(cd); return 0;}#ifndef LIBICONV_PLUGint iconvctl (iconv_t icd, int request, void* argument){ conv_t cd = (conv_t) icd; switch (request) { case ICONV_TRIVIALP: *(int *)argument = ((cd->lfuncs.loop_convert == unicode_loop_convert && cd->iindex == cd->oindex) || cd->lfuncs.loop_convert == wchar_id_loop_convert ? 1 : 0); return 0; case ICONV_GET_TRANSLITERATE: *(int *)argument = cd->transliterate; return 0; case ICONV_SET_TRANSLITERATE: cd->transliterate = (*(const int *)argument ? 1 : 0); return 0; case ICONV_GET_DISCARD_ILSEQ: *(int *)argument = cd->discard_ilseq; return 0; case ICONV_SET_DISCARD_ILSEQ: cd->discard_ilseq = (*(const int *)argument ? 1 : 0); return 0; default: errno = EINVAL; return -1; }}/* An alias after its name has been converted from 'int' to 'const char*'. */struct nalias { const char* name; unsigned int encoding_index; };static int compare_by_index (const void * arg1, const void * arg2){ const struct nalias * alias1 = (const struct nalias *) arg1; const struct nalias * alias2 = (const struct nalias *) arg2; return (int)alias1->encoding_index - (int)alias2->encoding_index;}static int compare_by_name (const void * arg1, const void * arg2){ const char * name1 = *(const char **)arg1; const char * name2 = *(const char **)arg2; /* Compare alphabetically, but put "CS" names at the end. */ int sign = strcmp(name1,name2); if (sign != 0) { sign = ((name1[0]=='C' && name1[1]=='S') - (name2[0]=='C' && name2[1]=='S')) * 4 + (sign >= 0 ? 1 : -1); } return sign;}void iconvlist (int (*do_one) (unsigned int namescount, const char * const * names, void* data), void* data){#define aliascount1 sizeof(aliases)/sizeof(aliases[0])#ifndef aliases2_lookup#define aliascount2 sizeof(sysdep_aliases)/sizeof(sysdep_aliases[0])#else#define aliascount2 0#endif#define aliascount (aliascount1+aliascount2) struct nalias aliasbuf[aliascount]; const char * namesbuf[aliascount]; size_t num_aliases; { /* Put all existing aliases into a buffer. */ size_t i; size_t j; j = 0; for (i = 0; i < aliascount1; i++) { const struct alias * p = &aliases[i]; if (p->name >= 0 && p->encoding_index != ei_local_char && p->encoding_index != ei_local_wchar_t) { aliasbuf[j].name = stringpool + p->name; aliasbuf[j].encoding_index = p->encoding_index; j++; } }#ifndef aliases2_lookup for (i = 0; i < aliascount2; i++) { aliasbuf[j].name = stringpool2 + sysdep_aliases[i].name; aliasbuf[j].encoding_index = sysdep_aliases[i].encoding_index; j++; }#endif num_aliases = j; } /* Sort by encoding_index. */ if (num_aliases > 1) qsort(aliasbuf, num_aliases, sizeof(struct nalias), compare_by_index); { /* Process all aliases with the same encoding_index together. */ size_t j; j = 0; while (j < num_aliases) { unsigned int ei = aliasbuf[j].encoding_index; size_t i = 0; do namesbuf[i++] = aliasbuf[j++].name; while (j < num_aliases && aliasbuf[j].encoding_index == ei); if (i > 1) qsort(namesbuf, i, sizeof(const char *), compare_by_name); /* Call the callback. */ if (do_one(i,namesbuf,data)) break; } }#undef aliascount#undef aliascount2#undef aliascount1}int _libiconv_version = _LIBICONV_VERSION;#if defined __FreeBSD__ && !defined __gnu_freebsd__/* GNU libiconv is the native FreeBSD iconv implementation since 2002. It wants to define the symbols 'iconv_open', 'iconv', 'iconv_close'. */#define strong_alias(name, aliasname) _strong_alias(name, aliasname)#define _strong_alias(name, aliasname) \ extern __typeof (name) aliasname __attribute__ ((alias (#name)));#undef iconv_open#undef iconv#undef iconv_closestrong_alias (libiconv_open, iconv_open)strong_alias (libiconv, iconv)strong_alias (libiconv_close, iconv_close)#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -