summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/iconvenc/Makefile132
-rw-r--r--packages/iconvenc/Makefile.fpc4
-rw-r--r--packages/iconvenc/fpmake.pp3
-rwxr-xr-xpackages/iconvenc/src/iconvenc.pas147
-rwxr-xr-xpackages/iconvenc/src/iconvenc_dyn.pas106
-rw-r--r--packages/iconvenc/src/iconvert.inc60
6 files changed, 273 insertions, 179 deletions
diff --git a/packages/iconvenc/Makefile b/packages/iconvenc/Makefile
index 4c493ceff0..b73c9bf3d9 100644
--- a/packages/iconvenc/Makefile
+++ b/packages/iconvenc/Makefile
@@ -1,5 +1,5 @@
#
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/10/22]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/04/25]
#
default: all
MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
@@ -265,178 +265,178 @@ PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(F
override PACKAGE_NAME=iconvenc
override PACKAGE_VERSION=2.2.2
ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_UNITS+=iconvenc
+override TARGET_UNITS+=iconvenc iconvenc_dyn
endif
ifeq ($(FULL_TARGET),i386-linux)
override TARGET_EXAMPLEDIRS+=examples
@@ -1213,6 +1213,7 @@ endif
ifeq ($(OS_TARGET),go32v2)
STATICLIBPREFIX=
SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),watcom)
STATICLIBPREFIX=
@@ -1220,6 +1221,7 @@ OEXT=.obj
ASMEXT=.asm
SHAREDLIBEXT=.dll
SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),linux)
BATCHEXT=.sh
@@ -1256,6 +1258,7 @@ STATICLIBPREFIX=
SHAREDLIBEXT=.dll
SHORTSUFFIX=os2
ECHO=echo
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),emx)
BATCHEXT=.cmd
@@ -1264,6 +1267,7 @@ STATICLIBPREFIX=
SHAREDLIBEXT=.dll
SHORTSUFFIX=emx
ECHO=echo
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),amiga)
EXEEXT=
@@ -1303,17 +1307,20 @@ ifeq ($(OS_TARGET),netware)
EXEEXT=.nlm
STATICLIBPREFIX=
SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
endif
ifeq ($(OS_TARGET),netwlibc)
EXEEXT=.nlm
STATICLIBPREFIX=
SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
endif
ifeq ($(OS_TARGET),macos)
BATCHEXT=
EXEEXT=
DEBUGSYMEXT=.xcoff
SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
endif
ifeq ($(OS_TARGET),darwin)
BATCHEXT=.sh
@@ -1340,14 +1347,17 @@ STATICLIBEXT=.a1
SHAREDLIBEXT=.so1
STATICLIBPREFIX=
SHORTSUFFIX=v1
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),go32v2)
STATICLIBPREFIX=
SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),watcom)
STATICLIBPREFIX=
SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),linux)
BATCHEXT=.sh
@@ -1394,6 +1404,7 @@ STATICLIBEXT=.ao2
SHAREDLIBEXT=.dll
SHORTSUFFIX=os2
ECHO=echo
+IMPORTLIBPREFIX=
endif
ifeq ($(OS_TARGET),amiga)
EXEEXT=
@@ -1454,6 +1465,7 @@ STATICLIBEXT=.a
SHAREDLIBEXT=.nlm
EXEEXT=.nlm
SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
endif
ifeq ($(OS_TARGET),netwlibc)
STATICLIBPREFIX=
@@ -1465,6 +1477,7 @@ STATICLIBEXT=.a
SHAREDLIBEXT=.nlm
EXEEXT=.nlm
SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
endif
ifeq ($(OS_TARGET),macos)
BATCHEXT=
@@ -1476,6 +1489,7 @@ STATICLIBEXT=.a
EXEEXT=
DEBUGSYMEXT=.xcoff
SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
endif
endif
ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
diff --git a/packages/iconvenc/Makefile.fpc b/packages/iconvenc/Makefile.fpc
index f08930b81a..1e532070a1 100644
--- a/packages/iconvenc/Makefile.fpc
+++ b/packages/iconvenc/Makefile.fpc
@@ -3,11 +3,11 @@
#
[package]
-name=iconvenc
+name=iconvenc
version=2.2.2
[target]
-units=iconvenc
+units=iconvenc iconvenc_dyn
exampledirs=examples
[require]
diff --git a/packages/iconvenc/fpmake.pp b/packages/iconvenc/fpmake.pp
index e8f090f5d3..59f0f3a3c6 100644
--- a/packages/iconvenc/fpmake.pp
+++ b/packages/iconvenc/fpmake.pp
@@ -28,6 +28,9 @@ begin
P.IncludePath.Add('src');
T:=P.Targets.AddUnit('iconvenc.pas');
+ T.Dependencies.AddInclude('iconvert.inc');
+ T:=P.Targets.AddUnit('iconvenc_dyn.pas');
+ T.Dependencies.AddInclude('iconvert.inc');
P.ExamplePath.Add('examples');
P.Targets.AddExampleProgram('iconvtest.pp');
diff --git a/packages/iconvenc/src/iconvenc.pas b/packages/iconvenc/src/iconvenc.pas
index d151daf1bd..e90ace9e5d 100755
--- a/packages/iconvenc/src/iconvenc.pas
+++ b/packages/iconvenc/src/iconvenc.pas
@@ -19,13 +19,9 @@ unit iconvenc;
interface
{$mode objfpc}{$H+}
-{DEFINE LOADDYNAMIC}
uses
ctypes,unixtype,baseunix,
- {$ifdef LOADDYNAMIC}
- dl,
- {$endif}
initc;
const
@@ -43,135 +39,50 @@ type
Ticonv = function(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl;
Ticonv_close = function(__cd: iconv_t): cint; cdecl;
-{$IFNDEF LOADDYNAMIC}
-{$ifndef Linux} // and other OSes with iconv in libc.
-{$linklib iconv}
+{$if not defined(linux) and not defined(solaris)} // Linux (and maybe glibc pl
+ {$if defined(haiku)}
+ {$linklib textencoding}
+ {$else}
+ {$linklib iconv}
+ {$endif}
+ {$define useiconv}
+{$endif linux}
+
+Const
+{$ifndef useiconv}
+ libiconvname='c'; // is in libc under Linux.
+{$else}
+ {$ifdef haiku}
+ libiconvname='textencoding'; // is in libtextencoding under Haiku
+ {$else}
+ libiconvname='iconv';
+ {$endif}
{$endif}
-function iconv_open(__tocode: pchar; __fromcode: pchar): iconv_t; cdecl; external;
-function iconv (__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl; external;
-function iconv_close (__cd: iconv_t): cint; cdecl; external;
-var
- IconvLibFound: boolean = False;
+{$if defined(darwin) and defined(cpupowerpc32)}
+ iconvprefix='lib';
+{$else}
+ iconvprefix='';
+{$endif}
+
+function iconv_open(__tocode: pchar; __fromcode: pchar): iconv_t; cdecl; external libiconvname name iconvprefix+'iconv_open';
+function iconv (__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl; external libiconvname name iconvprefix+'iconv';
+function iconv_close (__cd: iconv_t): cint; cdecl; external libiconvname name iconvprefix+'iconv_close';
-{$ELSE}
var
- iconv_lib: pointer;
- iconv_open: Ticonv_open;
- iconv: Ticonv;
- iconv_close: Ticonv_close;
- IconvLibFound: boolean = true;
-
-function TryLoadLib(LibName: string; var error: string): boolean; // can be used to load non standard libname
-{$endif}
+ IconvLibFound: boolean = False;
function Iconvert(s: string; var res: string; FromEncoding, ToEncoding: string): cint;
function InitIconv(var error: string): boolean;
implementation
-{$IFDEF LOADDYNAMIC}
-function TryLoadLib(LibName: string; var error: string): boolean;
-
- function resolvesymbol (var funcptr; symbol: string): Boolean;
- begin
- pointer(funcptr) := pointer(dlsym(iconv_lib, pchar(symbol)));
- result := assigned(pointer(funcptr));
- if not result then
- error := error+#13#10+dlerror();
- end;
-
-var
- res: boolean;
-begin
- result := false;
- Error := Error+#13#10'Trying '+LibName;
- iconv_lib := dlopen(pchar(libname), RTLD_NOW);
- if Assigned(iconv_lib) then
- begin
- result := true;
- result := result and resolvesymbol(pointer(iconv),'iconv');
- result := result and resolvesymbol(pointer(iconv_open),'iconv_open');
- result := result and resolvesymbol(pointer(iconv_close),'iconv_close');
-// if not res then
-// dlclose(iconv_lib);
- end else
- error:=error+#13#10+dlerror();
-end;
-
-{$ENDIF}
-
function InitIconv(var error: string): boolean;
begin
result := true;
- {$ifdef LOADDYNAMIC}
- error := '';
- if not TryLoadLib('libc.so.6', error) then
- if not TryLoadLib('libiconv.so', error) then
- result := false;
- {$endif}
iconvlibfound := iconvlibfound or result;
end;
-function Iconvert(S: string; var Res: string; FromEncoding, ToEncoding: string): cint;
-var
- InLen, OutLen, Offset: size_t;
- Src, Dst: pchar;
- H: iconv_t;
- lerr: cint;
- iconvres: size_t;
-begin
- H := iconv_open(PChar(ToEncoding), PChar(FromEncoding));
- if not assigned(H) then
- begin
- Res := S;
- exit(-1);
- end;
-
- try
- SetLength(Res, Length(S));
- InLen := Length(S);
- OutLen := Length(Res);
- Src := PChar(S);
- Dst := PChar(Res);
-
- while InLen > 0 do
- begin
- iconvres := iconv(H, @Src, @InLen, @Dst, @OutLen);
- if iconvres = size_t(-1) then
- begin
- lerr := cerrno;
- if lerr = ESysEILSEQ then // unknown char, skip
- begin
- Dst^ := Src^;
- Inc(Src);
- Inc(Dst);
- Dec(InLen);
- Dec(OutLen);
- end
- else
- if lerr = ESysE2BIG then
- begin
- Offset := Dst - PChar(Res);
- SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
- Dst := PChar(Res) + Offset;
- OutLen := Length(Res) - Offset;
- end
- else
- exit(-1)
- end;
- end;
-
- // iconv has a buffer that needs flushing, specially if the last char is not #0
- iconv(H, nil, nil, @Dst, @Outlen);
-
- // trim output buffer
- SetLength(Res, Length(Res) - Outlen);
- finally
- iconv_close(H);
- end;
-
- Result := 0;
-end;
+{$i iconvert.inc}
end.
diff --git a/packages/iconvenc/src/iconvenc_dyn.pas b/packages/iconvenc/src/iconvenc_dyn.pas
new file mode 100755
index 0000000000..87d6436f21
--- /dev/null
+++ b/packages/iconvenc/src/iconvenc_dyn.pas
@@ -0,0 +1,106 @@
+{
+ This file is part of the Free Pascal run time library.
+ Copyright (c) 2000 by Marco van de Voort(marco@freepascal.org)
+ member of the Free Pascal development team
+
+ libiconv header translation + a helper routine
+ http://wiki.freepascal.org/iconvenc Dynamic version
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright. (LGPL)
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+}
+unit iconvenc_dyn;
+
+interface
+{$mode objfpc}{$H+}
+
+uses
+ ctypes,unixtype,baseunix,
+ dl,
+ initc;
+
+const
+ n = 1;
+
+{$ifdef beos}
+ ESysEILSEQ = EILSEQ;
+{$endif}
+
+type
+ piconv_t = ^iconv_t;
+ iconv_t = pointer;
+
+ Ticonv_open = function(__tocode: pchar; __fromcode: pchar): iconv_t; cdecl;
+ Ticonv = function(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl;
+ Ticonv_close = function(__cd: iconv_t): cint; cdecl;
+
+var
+ iconv_lib: pointer;
+ iconv_open: Ticonv_open;
+ iconv: Ticonv;
+ iconv_close: Ticonv_close;
+ IconvLibFound: boolean = true;
+
+function TryLoadLib(LibName: string; var error: string): boolean; // can be used to load non standard libname
+function Iconvert(s: string; var res: string; FromEncoding, ToEncoding: string): cint;
+function InitIconv(var error: string): boolean;
+
+implementation
+
+function TryLoadLib(LibName: string; var error: string): boolean;
+
+ function resolvesymbol (var funcptr; symbol: string): Boolean;
+ begin
+ pointer(funcptr) := pointer(dlsym(iconv_lib, pchar(symbol)));
+ result := assigned(pointer(funcptr));
+ if not result then
+ error := error+#13#10+dlerror();
+ end;
+
+var
+ res: boolean;
+begin
+ result := false;
+ Error := Error+#13#10'Trying '+LibName;
+ iconv_lib := dlopen(pchar(libname), RTLD_NOW);
+ if Assigned(iconv_lib) then
+ begin
+ result := true;
+ result := result and resolvesymbol(pointer(iconv),'iconv');
+ result := result and resolvesymbol(pointer(iconv_open),'iconv_open');
+ result := result and resolvesymbol(pointer(iconv_close),'iconv_close');
+ if not result then
+ begin
+ result:=true;
+ result := result and resolvesymbol(pointer(iconv),'libiconv');
+ result := result and resolvesymbol(pointer(iconv_open),'libiconv_open');
+ result := result and resolvesymbol(pointer(iconv_close),'libiconv_close');
+ end;
+// if not res then
+// dlclose(iconv_lib);
+ end else
+ error:=error+#13#10+dlerror();
+end;
+
+
+function InitIconv(var error: string): boolean;
+begin
+ result := true;
+ error := '';
+ if not TryLoadLib('libc.so.6', error) then
+ if not TryLoadLib('libiconv.so', error) then
+ {$if defined(haiku)}
+ if not TryLoadLib('libtextencoding.so', error) then
+ {$ifend}
+ result := false;
+ iconvlibfound := iconvlibfound or result;
+end;
+
+{$i iconvert.inc}
+
+end.
diff --git a/packages/iconvenc/src/iconvert.inc b/packages/iconvenc/src/iconvert.inc
new file mode 100644
index 0000000000..bee2a9d2f6
--- /dev/null
+++ b/packages/iconvenc/src/iconvert.inc
@@ -0,0 +1,60 @@
+function Iconvert(S: string; var Res: string; FromEncoding, ToEncoding: string): cint;
+var
+ InLen, OutLen, Offset: size_t;
+ Src, Dst: pchar;
+ H: iconv_t;
+ lerr: cint;
+ iconvres: size_t;
+begin
+ H := iconv_open(PChar(ToEncoding), PChar(FromEncoding));
+ if not assigned(H) then
+ begin
+ Res := S;
+ exit(-1);
+ end;
+
+ try
+ SetLength(Res, Length(S));
+ InLen := Length(S);
+ OutLen := Length(Res);
+ Src := PChar(S);
+ Dst := PChar(Res);
+
+ while InLen > 0 do
+ begin
+ iconvres := iconv(H, @Src, @InLen, @Dst, @OutLen);
+ if iconvres = size_t(-1) then
+ begin
+ lerr := cerrno;
+ if lerr = ESysEILSEQ then // unknown char, skip
+ begin
+ Dst^ := Src^;
+ Inc(Src);
+ Inc(Dst);
+ Dec(InLen);
+ Dec(OutLen);
+ end
+ else
+ if lerr = ESysE2BIG then
+ begin
+ Offset := Dst - PChar(Res);
+ SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
+ Dst := PChar(Res) + Offset;
+ OutLen := Length(Res) - Offset;
+ end
+ else
+ exit(-1)
+ end;
+ end;
+
+ // iconv has a buffer that needs flushing, specially if the last char is not #0
+ iconv(H, nil, nil, @Dst, @Outlen);
+
+ // trim output buffer
+ SetLength(Res, Length(Res) - Outlen);
+ finally
+ iconv_close(H);
+ end;
+
+ Result := 0;
+end;