diff options
| author | Ron Yorston <rmy@pobox.com> | 2020-02-14 13:51:46 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2020-02-14 14:32:51 +0000 |
| commit | 99f757c114ffbbdc9bfcb665fe2091982122a3db (patch) | |
| tree | d463a2f613cc1c87eb46a44f02dd0b44ec82b6b1 /miscutils | |
| parent | d8448f76cd40595673b2240b1015f0cbb3f36b56 (diff) | |
| download | busybox-w32-99f757c114ffbbdc9bfcb665fe2091982122a3db.tar.gz busybox-w32-99f757c114ffbbdc9bfcb665fe2091982122a3db.tar.bz2 busybox-w32-99f757c114ffbbdc9bfcb665fe2091982122a3db.zip | |
iconv: code shrink (2)
Rewrite iconv_open/iconv/iconv_close to merge Windows-specific
code. Make them static.
Use getopt32() to process options.
Saves 400 bytes.
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/iconv.c | 120 |
1 files changed, 34 insertions, 86 deletions
diff --git a/miscutils/iconv.c b/miscutils/iconv.c index ce0b2087c..0c98ced05 100644 --- a/miscutils/iconv.c +++ b/miscutils/iconv.c | |||
| @@ -54,18 +54,14 @@ typedef unsigned int uint; | |||
| 54 | 54 | ||
| 55 | typedef void* iconv_t; | 55 | typedef void* iconv_t; |
| 56 | 56 | ||
| 57 | iconv_t iconv_open(const char *tocode, const char *fromcode); | 57 | static iconv_t iconv_open(const char *tocode, const char *fromcode); |
| 58 | int iconv_close(iconv_t cd); | 58 | static int iconv_close(iconv_t cd); |
| 59 | size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); | 59 | static size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); |
| 60 | 60 | ||
| 61 | typedef struct compat_t compat_t; | 61 | typedef struct compat_t compat_t; |
| 62 | typedef struct csconv_t csconv_t; | 62 | typedef struct csconv_t csconv_t; |
| 63 | typedef struct rec_iconv_t rec_iconv_t; | 63 | typedef struct rec_iconv_t rec_iconv_t; |
| 64 | 64 | ||
| 65 | typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode); | ||
| 66 | typedef int (*f_iconv_close)(iconv_t cd); | ||
| 67 | typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); | ||
| 68 | typedef int* (*f_errno)(void); | ||
| 69 | typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); | 65 | typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); |
| 70 | typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); | 66 | typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); |
| 71 | typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); | 67 | typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); |
| @@ -94,17 +90,10 @@ struct csconv_t { | |||
| 94 | 90 | ||
| 95 | struct rec_iconv_t { | 91 | struct rec_iconv_t { |
| 96 | iconv_t cd; | 92 | iconv_t cd; |
| 97 | f_iconv_close iconv_close; | ||
| 98 | f_iconv iconv; | ||
| 99 | f_errno _errno; | ||
| 100 | csconv_t from; | 93 | csconv_t from; |
| 101 | csconv_t to; | 94 | csconv_t to; |
| 102 | }; | 95 | }; |
| 103 | 96 | ||
| 104 | static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); | ||
| 105 | static int win_iconv_close(iconv_t cd); | ||
| 106 | static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); | ||
| 107 | |||
| 108 | static int load_mlang(void); | 97 | static int load_mlang(void); |
| 109 | static int make_csconv(const char *name, csconv_t *cv); | 98 | static int make_csconv(const char *name, csconv_t *cv); |
| 110 | static int name_to_codepage(const char *name); | 99 | static int name_to_codepage(const char *name); |
| @@ -697,7 +686,7 @@ load_mlang(void) | |||
| 697 | return TRUE; | 686 | return TRUE; |
| 698 | } | 687 | } |
| 699 | 688 | ||
| 700 | iconv_t | 689 | static iconv_t |
| 701 | iconv_open(const char *tocode, const char *fromcode) | 690 | iconv_open(const char *tocode, const char *fromcode) |
| 702 | { | 691 | { |
| 703 | rec_iconv_t *cd; | 692 | rec_iconv_t *cd; |
| @@ -707,54 +696,24 @@ iconv_open(const char *tocode, const char *fromcode) | |||
| 707 | /* reset the errno to prevent reporting wrong error code. | 696 | /* reset the errno to prevent reporting wrong error code. |
| 708 | * 0 for unsorted error. */ | 697 | * 0 for unsorted error. */ |
| 709 | errno = 0; | 698 | errno = 0; |
| 710 | if (win_iconv_open(cd, tocode, fromcode)) | 699 | if (make_csconv(fromcode, &cd->from) && make_csconv(tocode, &cd->to)) { |
| 700 | cd->cd = (iconv_t)cd; | ||
| 711 | return (iconv_t)cd; | 701 | return (iconv_t)cd; |
| 702 | } | ||
| 712 | 703 | ||
| 713 | free(cd); | 704 | free(cd); |
| 714 | |||
| 715 | return (iconv_t)(-1); | 705 | return (iconv_t)(-1); |
| 716 | } | 706 | } |
| 717 | 707 | ||
| 718 | int | ||
| 719 | iconv_close(iconv_t _cd) | ||
| 720 | { | ||
| 721 | rec_iconv_t *cd = (rec_iconv_t *)_cd; | ||
| 722 | int r = cd->iconv_close(cd->cd); | ||
| 723 | int e = *(cd->_errno()); | ||
| 724 | free(cd); | ||
| 725 | errno = e; | ||
| 726 | return r; | ||
| 727 | } | ||
| 728 | |||
| 729 | size_t | ||
| 730 | iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) | ||
| 731 | { | ||
| 732 | rec_iconv_t *cd = (rec_iconv_t *)_cd; | ||
| 733 | size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft); | ||
| 734 | errno = *(cd->_errno()); | ||
| 735 | return r; | ||
| 736 | } | ||
| 737 | |||
| 738 | static int | 708 | static int |
| 739 | win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) | 709 | iconv_close(iconv_t _cd) |
| 740 | { | ||
| 741 | if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to)) | ||
| 742 | return FALSE; | ||
| 743 | cd->iconv_close = win_iconv_close; | ||
| 744 | cd->iconv = win_iconv; | ||
| 745 | cd->_errno = _errno; | ||
| 746 | cd->cd = (iconv_t)cd; | ||
| 747 | return TRUE; | ||
| 748 | } | ||
| 749 | |||
| 750 | static int | ||
| 751 | win_iconv_close(iconv_t cd UNUSED_PARAM) | ||
| 752 | { | 710 | { |
| 711 | free(_cd); | ||
| 753 | return 0; | 712 | return 0; |
| 754 | } | 713 | } |
| 755 | 714 | ||
| 756 | static size_t | 715 | static size_t |
| 757 | win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) | 716 | iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) |
| 758 | { | 717 | { |
| 759 | rec_iconv_t *cd = (rec_iconv_t *)_cd; | 718 | rec_iconv_t *cd = (rec_iconv_t *)_cd; |
| 760 | ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ | 719 | ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ |
| @@ -1778,53 +1737,41 @@ static void process_file(iconv_t cd, FILE *in, FILE *out) | |||
| 1778 | bb_perror_msg_and_die("conversion error"); | 1737 | bb_perror_msg_and_die("conversion error"); |
| 1779 | } | 1738 | } |
| 1780 | 1739 | ||
| 1740 | enum { | ||
| 1741 | OPT_f = (1 << 0), | ||
| 1742 | OPT_t = (1 << 1), | ||
| 1743 | OPT_l = (1 << 2), | ||
| 1744 | OPT_c = (1 << 3), | ||
| 1745 | OPT_o = (1 << 4), | ||
| 1746 | }; | ||
| 1747 | |||
| 1781 | int iconv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1748 | int iconv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 1782 | int iconv_main(int argc, char **argv) | 1749 | int iconv_main(int argc, char **argv) |
| 1783 | { | 1750 | { |
| 1784 | char *fromcode = NULL; | 1751 | char *fromcode, *tocode, *outfile; |
| 1785 | char *tocode = NULL; | 1752 | int i, opt; |
| 1786 | int i; | ||
| 1787 | iconv_t cd; | 1753 | iconv_t cd; |
| 1788 | FILE *in = stdin; | 1754 | FILE *in = stdin; |
| 1789 | FILE *out = stdout; | 1755 | FILE *out = stdout; |
| 1790 | int ignore = 0; | ||
| 1791 | const char *alias; | ||
| 1792 | |||
| 1793 | while ((i = getopt(argc, argv, "f:t:lco:")) != -1) { | ||
| 1794 | switch (i) { | ||
| 1795 | case 'l': | ||
| 1796 | alias = cp_alias; | ||
| 1797 | while (*alias) { | ||
| 1798 | printf("%s\n", alias); | ||
| 1799 | alias += strlen(alias) + 1; | ||
| 1800 | } | ||
| 1801 | return 0; | ||
| 1802 | |||
| 1803 | case 'f': | ||
| 1804 | fromcode = optarg; | ||
| 1805 | break; | ||
| 1806 | 1756 | ||
| 1807 | case 't': | 1757 | opt = getopt32(argv, "f:t:lco:", &fromcode, &tocode, &outfile); |
| 1808 | tocode = optarg; | ||
| 1809 | break; | ||
| 1810 | 1758 | ||
| 1811 | case 'c': | 1759 | if (opt & OPT_l) { |
| 1812 | ignore = 1; | 1760 | const char *alias = cp_alias; |
| 1813 | break; | 1761 | while (*alias) { |
| 1814 | 1762 | printf("%s\n", alias); | |
| 1815 | case 'o': | 1763 | alias += strlen(alias) + 1; |
| 1816 | out = xfopen(optarg, "wb"); | ||
| 1817 | break; | ||
| 1818 | |||
| 1819 | default: | ||
| 1820 | bb_show_usage(); | ||
| 1821 | } | 1764 | } |
| 1765 | return 0; | ||
| 1822 | } | 1766 | } |
| 1823 | 1767 | ||
| 1824 | if (fromcode == NULL || tocode == NULL) | 1768 | if ((opt & (OPT_f|OPT_t)) != (OPT_f|OPT_t)) |
| 1825 | bb_show_usage(); | 1769 | bb_show_usage(); |
| 1826 | 1770 | ||
| 1827 | if (ignore) | 1771 | if (opt & OPT_o) |
| 1772 | out = xfopen(outfile, "wb"); | ||
| 1773 | |||
| 1774 | if (opt & OPT_c) | ||
| 1828 | tocode = xasprintf("%s//IGNORE", tocode); | 1775 | tocode = xasprintf("%s//IGNORE", tocode); |
| 1829 | 1776 | ||
| 1830 | cd = iconv_open(tocode, fromcode); | 1777 | cd = iconv_open(tocode, fromcode); |
| @@ -1843,6 +1790,7 @@ int iconv_main(int argc, char **argv) | |||
| 1843 | } | 1790 | } |
| 1844 | } | 1791 | } |
| 1845 | 1792 | ||
| 1846 | iconv_close(cd); | 1793 | if (ENABLE_FEATURE_CLEAN_UP) |
| 1794 | iconv_close(cd); | ||
| 1847 | return 0; | 1795 | return 0; |
| 1848 | } | 1796 | } |
