diff --git a/setup/build_environment.py b/setup/build_environment.py index b44c57f069..136976b251 100644 --- a/setup/build_environment.py +++ b/setup/build_environment.py @@ -34,6 +34,7 @@ if iswindows: MT = os.path.join(os.path.dirname(p), 'bin', 'mt.exe') MT = os.path.join(SDK, 'bin', 'mt.exe') os.environ['QMAKESPEC'] = 'win32-msvc' + ICU = r'Q:\icu' QMAKE = '/Volumes/sw/qt/bin/qmake' if isosx else 'qmake' if find_executable('qmake-qt4'): @@ -97,8 +98,9 @@ if iswindows: prefix = r'C:\cygwin\home\kovid\sw' sw_inc_dir = os.path.join(prefix, 'include') sw_lib_dir = os.path.join(prefix, 'lib') - icu_inc_dirs = [sw_inc_dir] - icu_lib_dirs = [sw_lib_dir] + icu_inc_dirs = [os.path.join(ICU, 'source', 'common'), os.path.join(ICU, + 'source', 'i18n')] + icu_lib_dirs = [os.path.join(ICU, 'source', 'lib')] sqlite_inc_dirs = [sw_inc_dir] fc_inc = os.path.join(sw_inc_dir, 'fontconfig') fc_lib = sw_lib_dir diff --git a/setup/installer/linux/freeze2.py b/setup/installer/linux/freeze2.py index 4435653516..4fa7e4fc47 100644 --- a/setup/installer/linux/freeze2.py +++ b/setup/installer/linux/freeze2.py @@ -54,10 +54,10 @@ binary_includes = [ '/lib/libreadline.so.6', '/usr/lib/libchm.so.0', '/usr/lib/liblcms2.so.2', - '/usr/lib/libicudata.so.46', - '/usr/lib/libicui18n.so.46', - '/usr/lib/libicuuc.so.46', - '/usr/lib/libicuio.so.46', + '/usr/lib/libicudata.so.49', + '/usr/lib/libicui18n.so.49', + '/usr/lib/libicuuc.so.49', + '/usr/lib/libicuio.so.49', ] binary_includes += [os.path.join(QTDIR, 'lib%s.so.4'%x) for x in QTDLLS] diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py index 7904ddce6b..48dd2479c2 100644 --- a/setup/installer/windows/freeze.py +++ b/setup/installer/windows/freeze.py @@ -13,6 +13,7 @@ from setup import (Command, modules, functions, basenames, __version__, from setup.build_environment import msvc, MT, RC from setup.installer.windows.wix import WixMixIn +ICU_DIR = r'Q:\icu' OPENSSL_DIR = r'Q:\openssl' QT_DIR = 'Q:\\Qt\\4.8.2' QT_DLLS = ['Core', 'Gui', 'Network', 'Svg', 'WebKit', 'Xml', 'XmlPatterns'] @@ -147,6 +148,8 @@ class Win32Freeze(Command, WixMixIn): ignore=shutil.ignore_patterns('msvc*.dll', 'Microsoft.*')) for x in glob.glob(self.j(OPENSSL_DIR, 'bin', '*.dll')): shutil.copy2(x, self.dll_dir) + for x in glob.glob(self.j(ICU_DIR, 'source', 'lib', '*.dll')): + shutil.copy2(x, self.dll_dir) for x in QT_DLLS: x += '4.dll' if not x.startswith('phonon'): x = 'Qt'+x diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst index f987f83a3b..7ff1593988 100644 --- a/setup/installer/windows/notes.rst +++ b/setup/installer/windows/notes.rst @@ -131,11 +131,22 @@ calibre-debug -c "import _imaging, _imagingmath, _imagingft, _imagingcms" ICU ------- -Download the win32 msvc9 binary from http://www.icu-project.org/download/4.4.html +Download the win32 source .zip from http://www.icu-project.org/download -Note that 4.4 is the last version of ICU that can be compiled (is precompiled) with msvc9 +Extract to q:\icu -Put the dlls into sw/bin and the unicode dir into sw/include and the contents of lib int sw/lib +Add Q:\icu\bin to PATH and reboot + +In a Visual Studio Command Prompt +cd to \source +Run set PATH=%PATH%;c:\cygwin\bin +Run dos2unix on configure and runConfigureICU + +Run bash ./runConfigureICU Cygwin/MSVC + +Run make (note that you must have GNU make installed in cygwin) + +Optionally run make test Libunrar ---------- diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index 822b309619..11eed2408e 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -208,7 +208,7 @@ class ANDROID(USBMS): 'XT910', 'BOOK_A10', 'USB_2.0_DRIVER', 'I9100T', 'P999DW', 'KTABLET_PC', 'INGENIC', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'GT-S5830L_CARD', 'UNIVERSE', 'XT875', 'PRO', '.KOBO_VOX', - 'THINKPAD_TABLET'] + 'THINKPAD_TABLET', 'SGH-T989'] WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897', 'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD', 'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD', @@ -217,7 +217,7 @@ class ANDROID(USBMS): 'A1-07___C0541A4F', 'XT912', 'MB855', 'XT910', 'BOOK_A10_CARD', 'USB_2.0_DRIVER', 'I9100T', 'P999DW_SD_CARD', 'KTABLET_PC', 'FILE-CD_GADGET', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'XT875', - 'UMS_COMPOSITE', 'PRO', '.KOBO_VOX'] + 'UMS_COMPOSITE', 'PRO', '.KOBO_VOX', 'SGH-T989_CARD'] OSX_MAIN_MEM = 'Android Device Main Memory' diff --git a/src/calibre/utils/icu.c b/src/calibre/utils/icu.c index f4d820bff4..8372669258 100644 --- a/src/calibre/utils/icu.c +++ b/src/calibre/utils/icu.c @@ -281,6 +281,7 @@ icu_Collator_span_contractions(icu_Collator *self, PyObject *args, PyObject *kwa size_t slen = 0; wchar_t *buf; UChar *s; + int32_t ret; if (!PyArg_ParseTuple(args, "Ui", &str, &span_type)) return NULL; @@ -295,11 +296,12 @@ icu_Collator_span_contractions(icu_Collator *self, PyObject *args, PyObject *kwa buf = (wchar_t*)calloc(slen*4 + 2, sizeof(wchar_t)); s = (UChar*)calloc(slen*4 + 2, sizeof(UChar)); if (buf == NULL || s == NULL) return PyErr_NoMemory(); - slen = PyUnicode_AsWideChar((PyUnicodeObject*)str, buf, slen); + PyUnicode_AsWideChar((PyUnicodeObject*)str, buf, slen); u_strFromWCS(s, slen*4+1, NULL, buf, slen, &status); - free(buf); free(s); - return Py_BuildValue("i", uset_span(self->contractions, s, slen, span_type)); + ret = uset_span(self->contractions, s, slen, span_type); + free(s); free(buf); + return Py_BuildValue("i", ret); } // }}} diff --git a/src/calibre/utils/icu.py b/src/calibre/utils/icu.py index d9ae3c602c..c4778fcb24 100644 --- a/src/calibre/utils/icu.py +++ b/src/calibre/utils/icu.py @@ -90,7 +90,7 @@ def icu_case_sensitive_sort_key(collator, obj): def icu_strcmp(collator, a, b): return collator.strcmp(lower(a), lower(b)) -def py_strcmp(a, b, strength=None): +def py_strcmp(a, b): return cmp(a.lower(), b.lower()) def icu_case_sensitive_strcmp(collator, a, b): @@ -276,23 +276,21 @@ pêché''' german = create(german) c = _icu.Collator('de') - print 'Sorted german:: (%s)'%c.actual_locale gs = list(sorted(german, key=c.sort_key)) for x in gs: print '\t', x.encode('utf-8') if gs != create(german_good): - print 'German failed' + print 'German sorting failed' return print french = create(french) c = _icu.Collator('fr') - print 'Sorted french:: (%s)'%c.actual_locale fs = list(sorted(french, key=c.sort_key)) for x in fs: print '\t', x.encode('utf-8') if fs != create(french_good): - print 'French failed (note that French fails with icu < 4.6 i.e. on windows and OS X)' - # return + print 'French sorting failed (note that French fails with icu < 4.6)' + return test_strcmp(german + french) print '\nTesting case transforms in current locale' @@ -305,16 +303,20 @@ pêché''' print print '\nTesting primary collation' - for k, v in {u'pèché': u'peche', u'flüße':u'flusse'}.iteritems(): + for k, v in {u'pèché': u'peche', u'flüße':u'flusse', + u'Štepánek':u'Štepanek'}.iteritems(): if primary_strcmp(k, v) != 0: print 'primary_strcmp() failed with %s != %s'%(k, v) + return if primary_find(v, u' '+k)[0] != 1: print 'primary_find() failed with %s not in %s'%(v, k) + return global _primary_collator _primary_collator = _icu.Collator('es') if primary_strcmp(u'peña', u'pena') == 0: print 'Primary collation in Spanish locale failed' + return # }}}