Skip to content

Commit

Permalink
add iconv from noxcuse
Browse files Browse the repository at this point in the history
git://git.etalabs.net/noxcuse
17409cfa46726ad40781ba41d719640db61e5346
  • Loading branch information
rofl0r committed May 24, 2014
1 parent a48ddb2 commit c2d5f8f
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
110 changes: 110 additions & 0 deletions KEEP/iconv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* iconv.c
* Implementation of SUSv4 XCU iconv utility
* Copyright © 2011 Rich Felker
* Licensed under the terms of the GNU General Public License, v2 or later
*/

#include <stdlib.h>
#include <stdio.h>
#include <iconv.h>
#include <locale.h>
#include <langinfo.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
const char *from=0, *to=0;
int b;
iconv_t cd;
char buf[BUFSIZ];
char outbuf[BUFSIZ*4];
char *in, *out;
size_t inb;
size_t l;
size_t unitsize=0;
int err=0;
FILE *f;

while ((b = getopt(argc, argv, "f:t:csl")) != EOF) switch(b) {
case 'l':
puts("UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF32-LE, UCS-2BE, UCS-2LE, WCHAR_T,\n"
"US_ASCII, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,\n"
"ISO8859-6, ISO8859-7, ...");
exit(0);
case 'c': case 's': break;
case 'f': from=optarg; break;
case 't': to=optarg; break;
default: exit(1);
}

if (!from || !to) {
setlocale(LC_CTYPE, "");
if (!to) to = nl_langinfo(CODESET);
if (!from) from = nl_langinfo(CODESET);
}
cd = iconv_open(to, from);
if (cd == (iconv_t)-1) {
if (iconv_open(to, "WCHAR_T") == (iconv_t)-1)
fprintf(stderr, "iconv: destination charset %s", to);
else
fprintf(stderr, "iconv: source charset %s", from);
perror("");
exit(1);
}
if (optind == argc) argv[argc++] = "-";

for (; optind < argc; optind++) {
if (argv[optind][0]=='-' && !argv[optind][1]) {
f = stdin;
argv[optind] = "(stdin)";
} else if (!(f = fopen(argv[optind], "rb"))) {
fprintf(stderr, "iconv: %s", argv[optind]);
perror("");
err = 1;
continue;
}
inb = 0;
for (;;) {
in = buf;
out = outbuf;
l = fread(buf+inb, 1, sizeof(buf)-inb, f);
inb += l;
if (!inb) break;
if (iconv(cd, &in, &inb, &out, (size_t [1]){sizeof outbuf})==-1
&& errno == EILSEQ) {
if (!unitsize) {
wchar_t wc='0';
char dummy[4], *dummyp=dummy;
iconv_t cd2 = iconv_open(from, "WCHAR_T");
if (cd == (iconv_t)-1) {
unitsize = 1;
} else {
iconv(cd2,
(char *[1]){(char *)&wc},
(size_t[1]){1},
&dummyp, (size_t[1]){4});
unitsize = dummyp-dummy;
if (!unitsize) unitsize=1;
}
}
inb-=unitsize;
in+=unitsize;
}
if (inb && !l && errno==EINVAL) break;
if (out>outbuf && !fwrite(outbuf, out-outbuf, 1, stdout)) {
perror("iconv: write error");
exit(1);
}
if (inb) memmove(buf, in, inb);
}
if (ferror(f)) {
fprintf(stderr, "iconv: %s", argv[optind]);
perror("");
err = 1;
}
}
return err;
}
4 changes: 4 additions & 0 deletions pkg/iconv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[build]
"$CC" $optcflags -std=gnu99 -o iconv "$K"/iconv.c -static $optldflags || exit 1

mv iconv "$butch_prefix"/bin/

0 comments on commit c2d5f8f

Please sign in to comment.