File: charconv.c

package info (click to toggle)
euslisp 9.27%2Bdfsg-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 55,344 kB
  • sloc: ansic: 41,162; lisp: 3,339; makefile: 256; sh: 208; asm: 138; python: 53
file content (97 lines) | stat: -rw-r--r-- 2,663 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* charconv.c 
/* (c) 2003, Toshihiro Matsui, Digital Human Research Lab, AIST
Character code conversion using iconv library.

% cc -c -fpic -Di486 -DLinux charconv.c -I/usr/local/eus/include
% ld  -o charconv.so -shared charconv.o
eus$ (load "charconv.so")
eus$ (iconv "euc-jp" "Shift-jis" "松井")

*/

#include <stdlib.h>
#include <iconv.h>
#include <errno.h>

#include "eus.h"

static pointer cconv(context *ctx, int n, pointer *argv)
{
  iconv_t cd;
  size_t inbytesleft, outbytesleft;
  char *outbufp1, *outbufp2, *instrp;
  size_t ret;
  pointer instr=argv[2], outstr;
  size_t len=vecsize(instr); 

  inbytesleft=len;
  outbytesleft=len*2;
  outbufp1= outbufp2= malloc(outbytesleft);
  instrp= &(instr->c.str.chars[0]);

  /* get acceptable codings by 'iconv --list' */
  /* cd=iconv_open(to_code, from_code); */
  /* cd=iconv_open("Shift_JIS", "EUC-JP"); */
  cd=iconv_open(argv[1]->c.str.chars, argv[0]->c.str.chars);
  if (cd == (iconv_t)-1) { outstr= (pointer)makeint(errno); goto conv_end;}

  ret=iconv(cd, &instrp, &inbytesleft, &outbufp2, &outbytesleft);
  if (ret == -1) { outstr=makeint(-errno); goto conv_end;}
  else  outstr=makestring(outbufp1, len*2-outbytesleft);

  conv_end: 
  iconv_close(cd);
  cfree(outbufp1);
  return(outstr);
  }

pointer ICONVOPEN(context *ctx, int n, pointer *argv)
{ int cd;
  ckarg(2);
  if (!isstring(argv[0])) error (E_NOSTRING, argv[0]);
  if (!isstring(argv[1])) error (E_NOSTRING, argv[1]);
  cd=iconv_open(argv[0]->c.str.chars, argv[1]->c.str.chars);
  return(mkbigint(cd));}

pointer ICONVCLOSE(context *ctx, int n, pointer *argv)
{ int cd, ret;
  ckarg(1);
  cd=bigintval(argv[0]);
  ret=iconv_close(cd);
  return(makeint(ret));
  }

pointer ICONV(context *ctx, int n, pointer *argv)
{ int cd, ret, malloced=NULL;
  char *srcstrp, *deststrp, *deststrpv, deststr[1024];
  size_t srcstrlen, deststrlen;
  pointer dest;

  ckarg(2);
  cd=bigintval(argv[0]);
  if (!isstring(argv[1])) error(E_NOSTRING);
  srcstrp=argv[1]->c.str.chars;
  srcstrlen=strlength(argv[1]);
  deststrlen=2*srcstrlen;
  if (deststrlen>=1024) {
    deststrp=malloc(deststrlen);
    malloced=1;}
  else deststrp=deststr;
  deststrpv=deststrp;
  ret=iconv(cd, &srcstrp, &srcstrlen, &deststrpv, &deststrlen);
  if (ret== -1) { dest=NIL; goto iconvend;}
  dest=makestring(deststrp, 2*strlength(argv[1])-deststrlen);
  iconvend:
  if (malloced) cfree(deststrp);
  return(dest);
  }

charconv(context *ctx, int n, pointer argv[])
{ pointer mod=argv[0];
  defun(ctx,"CHARCONV",mod,cconv,NULL);
  defun(ctx,"ICONV-OPEN", mod, ICONVOPEN,NULL);
  defun(ctx,"ICONV-CLOSE", mod, ICONVCLOSE,NULL);
  defun(ctx, "ICONV", mod, ICONV,NULL);
  }