Mercurial > projects > dwt2
view com.ibm.icu/src/com/ibm/icu/mangoicu/ICU.d @ 120:536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
===D2===
* added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements
used these templates to work with strict type storage rules of dmd-2.053
* com.ibm.icu now also compilable with D2, but not tested yet
* small fixes
Snippet288 - shared data is in TLS
===Phobos===
* fixed critical bugs in Phobos implemention
completely incorrect segfault prone fromStringz (Linux's port ruthless killer)
terrible, incorrect StringBuffer realization (StyledText killer)
* fixed small bugs as well
Snippet72 - misprint in the snippet
* implemented missed functionality for Phobos
ByteArrayOutputStream implemented (image loading available)
formatting correctly works for all DWT's cases
As a result, folowing snippets now works with Phobos (Snippet### - what is fixed):
Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting
Snippet48, 282 - crash on image loading
Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText
Snippet244 - hang-up
===Tango===
* few changes for the latest Tango trunc-r5661
* few small performance improvments
===General===
* implMissing-s for only one version changed to implMissingInTango/InPhobos
* incorrect calls to Format in toString-s fixed
* fixed loading \uXXXX characters in ResourceBundle
* added good UTF-8 support for StyledText, TextLayout (Win32) and friends
UTF functions revised and tested. It is now in java.nonstandard.*Utf modules
StyledText and TextLayout (Win32) modules revised for UTF-8 support
* removed small diferences in most identical files in *.swt.* folders
*.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32
now 179 of 576 (~31%) files in *.swt.* folders are fully identical
* Win32: snippets now have right subsystem, pretty icons and native system style controls
* small fixes in snippets
Snippet44 - it's not Snippet44
Snippet212 - functions work with different images and offsets arrays
Win32: Snippet282 - crash on close if the button has an image
Snippet293 - setGrayed is commented
and others
Win32: As a result, folowing snippets now works
Snippet68 - color doesn't change
Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above)
Snippet193 - no tabel headers
author | Denis Shelomovskij <verylonglogin.reg@gmail.com> |
---|---|
date | Sat, 09 Jul 2011 15:50:20 +0300 |
parents | ebefa5c2eab4 |
children |
line wrap: on
line source
/******************************************************************************* @file ICU.d Copyright (c) 2004 Kris Bell This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for damages of any kind arising from the use of this software. Permission is hereby granted to anyone to use this software for any purpose, including commercial applications, and to alter it and/or redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment within documentation of said product would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any distribution of the source. 4. Derivative works are permitted, but they must carry this notice in full and credit the original source. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @version Initial version; October 2004 Updated to ICU v3.2; March 2005 @author Kris John Reimer Anders F Bjorklund (Darwin patches) *******************************************************************************/ module com.ibm.icu.mangoicu.ICU; import java.lang.util; /******************************************************************************* Library version identifiers *******************************************************************************/ version (ICU30) { private static const char[] ICULib = "30"; private static const char[] ICUSig = "_3_0\0"; } version (ICU32) { private static const char[] ICULib = "32"; private static const char[] ICUSig = "_3_2\0"; } version (ICU34) { private static const char[] ICULib = "34"; private static const char[] ICUSig = "_3_4\0"; } version (ICU36) { private static const char[] ICULib = "36"; private static const char[] ICUSig = "_3_6\0"; } else { private static const char[] ICULib = "38"; private static const char[] ICUSig = "_3_8\0"; } /******************************************************************************* *******************************************************************************/ private static extern (C) uint strlen (char *s); private static extern (C) uint wcslen (wchar *s); /******************************************************************************* Some low-level routines to help bind the ICU C-API to D. *******************************************************************************/ package static String genICUNative(String t, funcs...)() { static assert((t == "in" || t == "uc") && !(funcs.length & 1)); String gsh = " ", sh = ""; version(D_Version2) { gsh = " __gshared "; sh = "shared "; } String res = "private: static"~gsh~"void* library; static"~gsh~"extern(C) {\n"; foreach(int i, name; funcs) static if(i & 1) res ~= funcs[i-1] ~ " " ~ name ~ ";\n"; res ~= "} static"~gsh~"FunctionLoader.Bind[] targets = [\n"; foreach(int i, name; funcs) static if(i & 1) res ~= "{cast(void**) &" ~ name ~ ", `" ~ name ~ "`},\n"; res ~= "]; "~sh~"static this() { library = FunctionLoader.bind(ICU.icu" ~ t ~ ", targets); } "~sh~"static ~this() { FunctionLoader.unbind(library); }"; return res; } protected class ICU { /*********************************************************************** The library names to load within the target environment ***********************************************************************/ version (Win32) { package static char[] icuuc = "icuuc"~ICULib~".dll"; package static char[] icuin = "icuin"~ICULib~".dll"; } else version (linux) { package static char[] icuuc = "libicuuc.so."~ICULib; package static char[] icuin = "libicui18n.so."~ICULib; } else version (darwin) { package static char[] icuuc = "libicuuc.dylib."~ICULib; package static char[] icuin = "libicui18n.dylib."~ICULib; } else { static assert (false); } /*********************************************************************** Use this for the primary argument-type to most ICU functions ***********************************************************************/ protected typedef void* Handle; /*********************************************************************** Parse-error filled in by several functions ***********************************************************************/ public struct ParseError { int line, offset; wchar[16] preContext, postContext; } /*********************************************************************** The binary form of a version on ICU APIs is an array of four bytes ***********************************************************************/ public struct Version { ubyte[4] info; } /*********************************************************************** ICU error codes (the ones which are referenced) ***********************************************************************/ package enum UErrorCode:int { OK, BufferOverflow=15 } /*********************************************************************** ***********************************************************************/ package static final bool isError (UErrorCode e) { return e > 0; } /*********************************************************************** ***********************************************************************/ package static final void exception (in char[] msg) { throw new ICUException (cast(String)msg); } /*********************************************************************** ***********************************************************************/ package static final void testError (UErrorCode e, in char[] msg) { if (e > 0) exception (msg); } /*********************************************************************** ***********************************************************************/ package static final char* toString (in char[] string) { static char[] empty; if (! string.length) return (string.ptr) ? empty.ptr : null; // if (* (&string[0] + string.length)) { // Need to make a copy char[] copy = new char [string.length + 1]; copy [0..string.length] = string; copy [string.length] = 0; return copy.ptr; } //return cast(char*)string.ptr; } /*********************************************************************** ***********************************************************************/ package static final wchar* toString (in wchar[] string) { static wchar[] empty; if (! string.length) return (string.ptr) ? empty.ptr : null; // if (* (&string[0] + string.length)) { // Need to make a copy wchar[] copy = new wchar [string.length + 1]; copy [0..string.length] = string; copy [string.length] = 0; return copy.ptr; } //return cast(wchar*)string.ptr; } /*********************************************************************** ***********************************************************************/ protected static final uint length (char* s) { return strlen (s); } /*********************************************************************** ***********************************************************************/ protected static final uint length (wchar* s) { return wcslen (s); } /*********************************************************************** ***********************************************************************/ protected static final char[] toArray (char* s) { if (s) return s[0..strlen (s)]; return null; } /*********************************************************************** ***********************************************************************/ protected static final wchar[] toArray (wchar* s) { if (s) return s[0..wcslen (s)]; return null; } } /******************************************************************************* *******************************************************************************/ class ICUException : Exception { /*********************************************************************** Construct exception with the provided text string ***********************************************************************/ this (String msg) { super (msg); } } /******************************************************************************* *******************************************************************************/ typedef void* UParseError; /******************************************************************************* Function address loader for Win32 *******************************************************************************/ version (Win32) { typedef void* HANDLE; extern (Windows) HANDLE LoadLibraryA (char*); extern (Windows) HANDLE GetProcAddress (HANDLE, char*); extern (Windows) void FreeLibrary (HANDLE); /*********************************************************************** ***********************************************************************/ package static class FunctionLoader { /*************************************************************** ***************************************************************/ protected struct Bind { void** fnc; const String name; } /*************************************************************** ***************************************************************/ static final void* bind (char[] library, ref Bind[] targets) { HANDLE lib = LoadLibraryA (ICU.toString(library)); foreach (Bind b; targets) { auto name = b.name ~ ICUSig; *b.fnc = GetProcAddress (lib, cast(char*)name.ptr); if (*b.fnc) {}// printf ("bound '%.*s'\n", name); else throw new Exception ( cast(String)("required " ~ name ~ " in library " ~ library)); } return lib; } /*************************************************************** ***************************************************************/ static final void unbind (void* library) { version (CorrectedTeardown) FreeLibrary (cast(HANDLE) library); } } } /******************************************************************************* 2004-11-26: Added Linux shared library support -- John Reimer *******************************************************************************/ else version (linux) { //Tell build to link with dl library version(build) { pragma(link, "dl"); } // from include/bits/dlfcn.h on Linux const int RTLD_LAZY = 0x00001; // Lazy function call binding const int RTLD_NOW = 0x00002; // Immediate function call binding const int RTLD_NOLOAD = 0x00004; // no object load const int RTLD_DEEPBIND = 0x00008; const int RTLD_GLOBAL = 0x00100; // make object available to whole program extern(C) { void* dlopen(char* filename, int flag); char* dlerror(); void* dlsym(void* handle, char* symbol); int dlclose(void* handle); } class FunctionLoader { /*************************************************************** ***************************************************************/ protected struct Bind { void** fnc; const String name; } /*************************************************************** ***************************************************************/ static final void* bind (char[] library, ref Bind[] targets) { static char[] errorInfo; // printf("the library is %s\n", ICU.toString(library)); void* lib = dlopen(ICU.toString(library), RTLD_NOW); // clear the error buffer dlerror(); foreach (Bind b; targets) { char[] name = cast(char[])(b.name ~ ICUSig); *b.fnc = dlsym (lib, name.ptr); if (*b.fnc) {}// printf ("bound '%.*s'\n", name); else { // errorInfo = ICU.toArray(dlerror()); // printf("%s", dlerror()); throw new Exception (cast(String)("required " ~ name ~ " in library " ~ library)); } } return lib; } /*************************************************************** ***************************************************************/ static final void unbind (void* library) { version (CorrectedTeardown) { if (! dlclose (library)) throw new Exception ("close library failed\n"); } } } } /******************************************************************************* 2004-12-20: Added Darwin shared library support -- afb *******************************************************************************/ else version (darwin) { // #include <mach-o/loader.h> struct mach_header { uint magic; /* mach magic number identifier */ uint cputype; /* cpu specifier */ uint cpusubtype; /* machine specifier */ uint filetype; /* type of file */ uint ncmds; /* number of load commands */ uint sizeofcmds; /* the size of all the load commands */ uint flags; /* flags */ } /* Constant for the magic field of the mach_header */ const uint MH_MAGIC = 0xfeedface; // the mach magic number const uint MH_CIGAM = 0xcefaedfe; // x86 variant // #include <mach-o/dyld.h> typedef void *NSObjectFileImage; typedef void *NSModule; typedef void *NSSymbol; enum // DYLD_BOOL: uint { FALSE, TRUE } alias uint DYLD_BOOL; enum // NSObjectFileImageReturnCode: uint { NSObjectFileImageFailure, /* for this a message is printed on stderr */ NSObjectFileImageSuccess, NSObjectFileImageInappropriateFile, NSObjectFileImageArch, NSObjectFileImageFormat, /* for this a message is printed on stderr */ NSObjectFileImageAccess } alias uint NSObjectFileImageReturnCode; enum // NSLinkEditErrors: uint { NSLinkEditFileAccessError, NSLinkEditFileFormatError, NSLinkEditMachResourceError, NSLinkEditUnixResourceError, NSLinkEditOtherError, NSLinkEditWarningError, NSLinkEditMultiplyDefinedError, NSLinkEditUndefinedError } alias uint NSLinkEditErrors; extern(C) { NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(char *pathName, NSObjectFileImage* objectFileImage); DYLD_BOOL NSDestroyObjectFileImage(NSObjectFileImage objectFileImage); mach_header * NSAddImage(char *image_name, uint options); const uint NSADDIMAGE_OPTION_NONE = 0x0; const uint NSADDIMAGE_OPTION_RETURN_ON_ERROR = 0x1; const uint NSADDIMAGE_OPTION_WITH_SEARCHING = 0x2; const uint NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED = 0x4; const uint NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME = 0x8; NSModule NSLinkModule(NSObjectFileImage objectFileImage, char* moduleName, uint options); const uint NSLINKMODULE_OPTION_NONE = 0x0; const uint NSLINKMODULE_OPTION_BINDNOW = 0x01; const uint NSLINKMODULE_OPTION_PRIVATE = 0x02; const uint NSLINKMODULE_OPTION_RETURN_ON_ERROR = 0x04; const uint NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES = 0x08; const uint NSLINKMODULE_OPTION_TRAILING_PHYS_NAME = 0x10; DYLD_BOOL NSUnLinkModule(NSModule module_, uint options); void NSLinkEditError(NSLinkEditErrors *c, int *errorNumber, char **fileName, char **errorString); DYLD_BOOL NSIsSymbolNameDefined(char *symbolName); DYLD_BOOL NSIsSymbolNameDefinedInImage(mach_header *image, char *symbolName); NSSymbol NSLookupAndBindSymbol(char *symbolName); NSSymbol NSLookupSymbolInModule(NSModule module_, char* symbolName); NSSymbol NSLookupSymbolInImage(mach_header *image, char *symbolName, uint options); const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND = 0x0; const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW = 0x1; const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY = 0x2; const uint NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR = 0x4; void* NSAddressOfSymbol(NSSymbol symbol); char* NSNameOfSymbol(NSSymbol symbol); } class FunctionLoader { /*************************************************************** ***************************************************************/ protected struct Bind { void** fnc; const String name; } /*************************************************************** ***************************************************************/ private static NSModule open(char* filename) { NSModule mod = null; NSObjectFileImage fileImage = null; debug printf("Trying to load: %s\n", filename); NSObjectFileImageReturnCode returnCode = NSCreateObjectFileImageFromFile(filename, &fileImage); if(returnCode == NSObjectFileImageSuccess) { mod = NSLinkModule(fileImage,filename, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(fileImage); } else if(returnCode == NSObjectFileImageInappropriateFile) { NSDestroyObjectFileImage(fileImage); /* Could be a dynamic library rather than a bundle */ mod = cast(NSModule) NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); } else { debug printf("FileImage Failed: %d\n", returnCode); } return mod; } private static void* symbol(NSModule mod, char* name) { NSSymbol symbol = null; uint magic = (* cast(mach_header *) mod).magic; if ( (mod == cast(NSModule) -1) && NSIsSymbolNameDefined(name)) /* Global context, use NSLookupAndBindSymbol */ symbol = NSLookupAndBindSymbol(name); else if ( ( magic == MH_MAGIC || magic == MH_CIGAM ) && NSIsSymbolNameDefinedInImage(cast(mach_header *) mod, name)) symbol = NSLookupSymbolInImage(cast(mach_header *) mod, name, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); else symbol = NSLookupSymbolInModule(mod, name); return NSAddressOfSymbol(symbol); } static final void* bind (char[] library, ref Bind[] targets) { static char[] errorInfo; debug printf("the library is %s\n", ICU.toString(library)); void* lib = null; static char[][] usual_suspects = [ "", "/usr/local/lib/", "/usr/lib/", /* Fink */ "/sw/lib/", /* DarwinPorts */ "/opt/local/lib/" ]; foreach (char[] prefix; usual_suspects) { lib = cast(void*) open(ICU.toString(prefix ~ library)); if (lib != null) break; } if (lib == null) { throw new Exception ("could not open library " ~ library); } // clear the error buffer // error(); foreach (Bind b; targets) { // Note: all C functions have a underscore prefix in Mach-O symbols char[] name = "_" ~ b.name ~ ICUSig; *b.fnc = symbol(cast(NSModule) lib, name.ptr); if (*b.fnc != null) { debug printf ("bound '%.*s'\n", name); } else { // errorInfo = ICU.toArray(error()); throw new Exception ("required " ~ name ~ " in library " ~ library); } } return lib; } /*************************************************************** ***************************************************************/ private static bool close(NSModule mod) { uint magic = (* cast(mach_header *) mod).magic; if ( magic == MH_MAGIC || magic == MH_CIGAM ) { // Can not unlink dynamic libraries on Darwin return true; } return (NSUnLinkModule(mod, 0) == TRUE); } static final void unbind (void* library) { version (CorrectedTeardown) { if (! close(cast(NSModule) library)) throw new Exception ("close library failed\n"); } } } } /******************************************************************************* unknown platform *******************************************************************************/ else static assert(0); // need an implementation of FunctionLoader for this OS