--- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9-gnome-support.postinst +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9-gnome-support.postinst @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +GRE_VERSION=`/usr/bin/xulrunner-1.9 --gre-version` + +if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then + if test -e /usr/lib/xulrunner-$GRE_VERSION/.autoreg; then + touch /usr/lib/xulrunner-$GRE_VERSION/.autoreg + fi +fi + +#DEBHELPER# --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9-venkman.install +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9-venkman.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/xulrunner-1.9*/extensions/venkman@mozilla.org usr/lib/xulrunner-addons/extensions --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.prerm.in +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.prerm.in @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +XUL_VERSION=@XULBRANCH@ + +if [ "$1" = "remove" ] || [ "$1" = upgrade ]; then + /usr/sbin/update-alternatives --remove xulrunner /usr/bin/xulrunner-$XUL_VERSION + if [ "$(update-alternatives --list xulrunner | wc -l)" = "0" ]; then + /usr/sbin/update-alternatives --remove-all xulrunner + fi +fi + +#DEBHELPER# --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/changelog +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/changelog @@ -0,0 +1,1038 @@ +xulrunner-1.9 (1.9.0.9+nobinonly-0ubuntu0.9.04.1) jaunty-security; urgency=low + + * security/stability v1.9.0.9 (FIREFOX_3_0_9_RELEASE) + - see USN-764-1 + + -- Alexander Sack Tue, 21 Apr 2009 13:55:36 +0200 + +xulrunner-1.9 (1.9.0.8+nobinonly-0ubuntu2) jaunty; urgency=low + + * zero change rebuild to fix damage by python transition; see + LP: #351988 and LP: #350594 + + -- Alexander Sack Tue, 31 Mar 2009 02:30:14 +0200 + +xulrunner-1.9 (1.9.0.8+nobinonly-0ubuntu1) jaunty; urgency=low + + * security/stability v1.9.0.8 (FIREFOX_3_0_8_RELEASE) + - see USN-745-1 + + -- Alexander Sack Fri, 27 Mar 2009 11:01:58 +0100 + +xulrunner-1.9 (1.9.0.7+nobinonly-0ubuntu1) jaunty; urgency=low + + * security/stability v1.9.0.7 (FIREFOX_3_0_7_RELEASE) + - USN-728-1 + * bump required soft-depends on nspr to >= 4.7.3 + - update debian/rules + + -- Alexander Sack Thu, 05 Mar 2009 17:19:38 +0100 + +xulrunner-1.9 (1.9.0.6+nobinonly-0ubuntu1) jaunty; urgency=low + + [ Alexander Sack ] + * new security/stability update v1.9.0.6 (FIREFOX_3_0_6_RELEASE) + - see USN-717-1 + * adjust patches to changed code base + - update debian/patches/dom_inspector_support_for_prism.patch + + [ Fabien Tassin ] + * Fix preinst script to better handle the /etc/gre.d clean-up + - update debian/xulrunner-1.9.preinst.in + * Fix permissions in the -dev package (LP: #303940) + - update debian/rules + + -- Alexander Sack Thu, 05 Feb 2009 09:12:37 +0100 + +xulrunner-1.9 (1.9.0.5+nobinonly-0ubuntu1) jaunty; urgency=low + + * new security/stability upstream release v1.9.0.5 (FIREFOX_3_0_5_RELEASE) + - see USN-690-1 + * submit patches upstreamed: + - bzXXX_plugin_for_mimetype_pref.patch => bz449188_att350098_plugin_for_mimetype_pref.patch + - update debian/patches/series + * adjust XULFastLoad cache in response to interleaving landing of bmo + #453545 and #462806 + - update debian/patches/bz368428_attachment_308130.patch + + -- Alexander Sack Tue, 16 Dec 2008 18:40:18 +0100 + +xulrunner-1.9 (1.9.0.4+nobinonly-0ubuntu1) jaunty; urgency=low + + * new stability/security update FIREFOX_3_0_4_RELEASE (v1.9.0.4) + - see USN-667-1 + + [ Alexander Sack ] + * adjust patches + - update debian/patches/bz368428_attachment_308130.patch + * (hackily) fix build on armel by disabling -Werror in network/cookie/src; + - add debian/patches/ARMEL_Wno_error_in_network_cookie_src.patch + - update debian/patches/series + + [ Fabien Tassin ] + * Improve convergence with the 1.9.1 branch by removing more + hardcoded 1.9 + - rename debian/xulrunner-1.9.postinst => debian/xulrunner-1.9.postinst.in + - rename debian/xulrunner-1.9.prerm => debian/xulrunner-1.9.prerm.in + - update debian/rules + * Drop obsolete /etc/gre.d files generated by this package + - add debian/xulrunner-1.9.preinst.in + - update debian/rules + + -- Alexander Sack Sun, 16 Nov 2008 17:05:19 +0100 + +xulrunner-1.9 (1.9.0.3+nobinonly-0ubuntu1) intrepid; urgency=low + + * Rename upstream tarball: 1.9.0.3 - no change upload + + -- Fabien Tassin Mon, 13 Oct 2008 16:10:34 +0200 + +xulrunner-1.9 (1.9.0.3+build1+nobinonly-0ubuntu2) intrepid; urgency=low + + regression fix release (v1.9.0.3 build1) + - see USN-645-3 + + * fix LP: #270429 - [MASTER] passwords lost from 3.0.1 to 3.0.2; we drop + the prepatch shipped in previous package as this was applied upstream now. + - delete debian/patches/bz454708_att340035.patch + - update debian/patches/series + + -- Alexander Sack Thu, 25 Sep 2008 17:05:45 +0200 + +xulrunner-1.9 (1.9.0.2+build6+nobinonly-0ubuntu2) intrepid; urgency=low + + * fix LP: #270429 - [MASTER] passwords lost from 3.0.1 to 3.0.2; we prepatch + the upstream fix for bz454708 + - add debian/patches/bz454708_att340035.patch + - update debian/patches/series + + -- Alexander Sack Wed, 24 Sep 2008 19:33:05 +0200 + +xulrunner-1.9 (1.9.0.2+build6+nobinonly-0ubuntu1) intrepid; urgency=low + + Security/Stability update (v1.9.0.2 build6) + - see USN-645-1 + + [ Alexander Sack ] + * preferred plugins are now matched by pref filename it is just a substring + of the plugins fullname/fullpath. Otherwise the plugin alternative config + dialog cannot use the filename it gets from navigator.plugins[x].filename + when plugin.expose_full_path is false. + - update debian/patches/bzXXX_plugin_for_mimetype_pref.patch + * fix LP: #269580 - ubufox fails to restart firefox on major version + upgrades; new patch that makes toolkit/xre/ LaunchChild also try + /usr/bin/`basename $0` before using $0 to launch the child process + - add debian/patches/system_path_launch_child.patch + - update debian/patches/series + + [ Fabien Tassin ] + * Fix broken symlink for system-grepref.js in /etc/xulrunner-$(DEB_MOZ_VERSION) + - update debian/rules + * Improve way to fix permissions for images, text and source files + - update debian/rules + * Use new style/look for "about:" pages + - add debian/patches/bz372826_att337031_about_style.patch + - update debian/patches/series + + -- Fabien Tassin Tue, 23 Sep 2008 17:38:00 +0200 + +xulrunner-1.9 (1.9.0.2+build3+nobinonly-0ubuntu1) intrepid; urgency=low + + [ Sasa Bodiroza ] + * In debian/rules: + - Set 644 chmod to png files (LP: #252793) [Patch by Paolo Naldini] + + [ Fabien Tassin ] + * improve create-build-system.sh to detect build-tree directory + when embedded tarball is used. Fix un-escaped variables. + Create build-system.tar.gz in the debian directory to prevent + cdbs to check and unpack it during the build + - update debian/create-build-system.sh + * Fix variables when an embedded tarball is used + - update debian/rules + * Fix buffer overflow in realpath() at runtime and drop -U_FORTIFY_SOURCE + from CPPFLAGS (LP: #263014) + - add debian/patches/bz412610_att335369_realpath_overflow.patch + - update debian/patches/series + + [ Alexander Sack ] + * introduce preferred plugins by mime-type experimental feature; + you can now set a pref to explicitly select a plugin to serve a particilar + mime-type; patch contains further documentation. + - add debian/patches/bzXXX_plugin_for_mimetype_pref.patch + - update debian/patches/series + * drop patches applied upstream + - drop bz120380_att326044.patch (fixed by bz442629) + - update debian/patches/series + + -- Fabien Tassin Tue, 2 Sep 2008 11:54:00 +0200 + +xulrunner-1.9 (1.9.0.1+build1+nobinonly-0ubuntu1) intrepid; urgency=low + + * LP: #247494 - new upstream stability/security release (v1.9.0.1 build1) + - see USN-626-1 + + [ Fabien Tassin ] + * Add a build-system for xulrunner application inside the SDK. + mozilla-devscripts is able to make use of this + - add debian/create-build-system.sh + - update debian/rules + * Rename the ld.so.conf.d file to xulrunner-1.9.conf as it seems + extension matters + - update debian/rules + - update debian/xulrunner-1.9.postinst + * Get DEB_MOZ_VERSION and DEB_MOZ_VERSION from changelog and make more use + of variables to make the merge with the 1.9.1 branch easier + - update debian/rules + - update debian/xulrunner-1.9.postinst + - update debian/xulrunner-1.9.postrm + * Make EM_TRANSLATION_VERSION follow upstream version now that strings are + hard frozen and bump EM_TRANSLATION_MAX_VERSION to 1.9.0.* + - update debian/rules + + [ Alexander Sack ] + * borrow lockPref patch from debian xulrunner (Debbugs: #469020) + - add debian/patches/bzXXX_deb469020_lockPref_everywhere.patch + - update debian/patches/series + * Debian compatibility patch that is supposed to make xulrunner also + consider /usr/lib/mozilla/plugins/ in sid as of xulrunner 1.9~rc2-4 + - add debian/patches/bzXXX_sysplugin_support.patch + - update debian/patches/series + * prepatch fix for bmo: #120380 - 'needsterminal flag in mailcap + must be respected' + - add debian/patches/bz120380_att326044.patch + - update debian/patches/series + * add xre part missed by debian for sysplugin support + - add debian/patches/bzXXX_sysplugin_support_xre_part.patch + - update debian/patches/series + * drop patches applied upstream + - delete debian/patches/bz428848_att319775_fix_venkman_chrome_access.patch + - update debian/patches/series + * housekeeping for debian/patches directory; remove obsolete patches from + debian/patches/ and drop commented patches from series + - delete debian/patches/bz384304_fix_recursive_symlinks.patch + - delete debian/patches/bzr423334_att310581_leak_initparser.patch + - debian/patches/drop_bz418016.patch + - update debian/patches/series + * (disabled in intrepid) fix "jemalloc not enabled in --with-xul-sdk= builds": we + fix this by building libjemalloc as a static lib and linking xulrunner-bin and + xulrunner-stub against it. + - add debian/patches/jemalloc_in_xul.patch + - add debian/patches/jemalloc_static.patch + - update debian/patches/series + - update debian/rules + - update debian/xulrunner-1.9.postinst + * link nss/nspr include directories to xulrunner-1.9 sdk in order to + allow upstream extensions to be built against ubuntu xulrunner. + - add debian/xulrunner-1.9-dev.links + * add empty xulrunner-dev package to ease sync/merge tasks for ubuntu + by providing the package name used by debian. + - update debian/control + * fix makefile style variable eval in xulrunner-1.9 prerm script and use + proper sh'ish style + - update debian/xulrunner-1.9.prerm + * add code/debug-support to disable -Bsymbolic-functions linkage - but keep + it commented by default + - update debian/rules + * hold back upgrade until firefox 3.0.1 is available; for that, we add a + Breaks: firefox-3.0 (<< 3.0.1) to xulrunner-1.9 binary package + - update debian/control + * fix LP: #247132 - The Prism Refractor Extension (v0.2) causes file + downloads to kill firefox 3; we fix this by introducing a NULL check + in our bz368428 "XUL FastLoad cache corruption" patch + - update debian/patches/bz368428_attachment_308130.patch + + -- Alexander Sack Fri, 18 Jul 2008 17:36:30 +0200 + +xulrunner-1.9 (1.9+nobinonly-0ubuntu2) intrepid; urgency=low + + * New upstream release 1.9 RC2 (LP: #237690) + + [ Alexander Sack ] + * Fix LP: #236266 - "Build Failure on HPPA architecture" by applying patch + from bugzilla https://bugzilla.mozilla.org/show_bug.cgi?id=436133 + - add debian/patches/bz436133_att322801.patch + - update debian/patches/series + * drop image scaling patches - previously applied and finally superseeded + upstream to fix Vista bug https://bugzilla.mozilla.org/show_bug.cgi?id=434157 + - delete debian/patches/bz394103_dont_scale_images.patch + - delete debian/patches/bz394103_scale_images_for_192+dpi.patch + - update debian/patches/series + * update patch for Bug 368428 – "XUL FastLoad cache corruption when + application running"; fix deadlock by using "antiLockZipGrip". + (LP: #236984) + - update debian/patches/bz368428_attachment_308130.patch + + [ Fabien Tassin ] + * drop synchronous = NORMAL patch, now applied upstream + - delete debian/patches/bz421482_att320806_synchronous_NORMAL_for_storage_connections.patch + - update debian/patches/series + * Fix regression with venkman accessing chrome by applying patch + from bugzilla https://bugzilla.mozilla.org/show_bug.cgi?id=428848 + - add debian/patches/bz428848_att319775_fix_venkman_chrome_access.patch + - update debian/patches/series + * Touch .autoreg in postinst with the exact GRE version as the glob is + causing troubles when multiple xulrunner are installed + - update debian/xulrunner-1.9.postinst + - update debian/xulrunner-1.9-gnome-support.postinst + * Don't install a libsqlite3.so.0 symlink if we are using system sqlite + - update debian/rules + + -- Fabien Tassin Tue, 10 Jun 2008 12:51:56 +0200 + +xulrunner-1.9 (1.9~rc1+nobinonly-0ubuntu2) intrepid; urgency=low + + * Fix FTBFS with hunspell 1.2 by splitting extensions/spellcheck/hunspell/src + to separate the hunspell library from the XPCOM glue (LP: #233922) + - add debian/patches/bz429747_att317495+move_hunspell_1.2.patch + - update debian/patches/series + * Drop irc (chatzilla) from DEB_MOZ_EXTENSIONS, we never packaged it + from there anyway + - update debian/rules + * cherry-pick 1.9b5 to 1.9rc1 upgrade Breaks: yelp (<< 2.22.1-0ubuntu2.8.04.1), + midbrowser (<< 0.3.0rc1), devhelp (<< 0.19-1ubuntu1.8.04.1) + - update debian/control + + -- Fabien Tassin Mon, 26 May 2008 14:47:22 +0200 + +xulrunner-1.9 (1.9~rc1+nobinonly-0ubuntu1) intrepid; urgency=low + + * new upstream release: xulrunner-1.9 RC1 (LP: #233922) + + [ Fabien Tassin ] + * Bump EM_TRANSLATION_VERSION and EM_TRANSLATION_{MIN,MAX}_VERSION to 1.9 + and clean-up the code to avoid unnecessary complexity + - update debian/rules + * Drop patch applied upstream + - drop debian/patches/bz423060_att312807_fix_rss_subscription.patch + - drop debian/patches/bz425814_att315081.patch + - drop debian/patches/inspector_maxversion_bump.patch + - update debian/patches/series + * Update diverges patches + - update debian/patches/bz394103_dont_scale_images.patch + - update debian/patches/bzXXX_gre_extension_plugin_support.patch + - update debian/patches/dom_inspector_support_for_prism.patch + * Build with system bzip2 + - update debian/rules + * Workaround multiple crashes in Intrepid (at least 3 in realpath()) caused + by Intrepid shipping gcc 4.3 with -D_FORTIFY_SOURCE=2 by default. + Set CPPFLAGS to -U_FORTIFY_SOURCE + - update debian/rules + * Drop LDFLAGS workaround now that jemalloc is no longer a static lib. + We still ship jemalloc as a shared lib + - udate debian/rules + * Set synchronous = NORMAL by default for storage to avoid excessive fsync. + It could be changed using the toolkit.storage.synchronous preference using + values of 0 (OFF), 1 (NORMAL), and 2 (FULL) + - add debian/patches/bz421482_att320806_synchronous_NORMAL_for_storage_connections.patch + - update debian/patches/series + + [ Alexander Sack ] + * remove cherry-pick for LP: #215728 - "excess disk IO when updating the + url-classifier" - applied upstream + - drop debian/patches/bz430530_attachment_318939.patch + - update debian/patches/series + * and cut out the "ship urlclassifier. settings in toolkit" part of the + patch to a separate one, targetted for upstream + - add debian/patches/bzXXX_urlclassifier_prefs_in_toolkit.patch + - update debian/patches/series + * prepatch from bugzilla fix for "Bug 368428 – XUL FastLoad cache corruption + when application running while upgrading" + - add debian/patches/bz368428_attachment_308130.patch + - update debian/patches/series + * 1.9b5 to 1.9rc1 upgrade Breaks: epiphany-gecko (<< 2.22.1.1-0ubuntu1.8.04.1) + - update debian/control + + -- Fabien Tassin Wed, 21 May 2008 14:38:00 +0200 + +xulrunner-1.9 (1.9~b5+nobinonly-0ubuntu4) intrepid; urgency=low + + * fix LP: #215728 - "excess disk IO when updating the url-classifier"; we + increase cache size of sqlite database and better align page size. + Cherry-picking and backporting upstream fix from bmo#430530; + other changes vs. upstream: we move default pref for cache size from + browser/ to toolkit/ + - add debian/patches/bz430530_attachment_318939.patch + - update debian/patches/series + * don't use gcc-4.2/g++-4.2 and dont depend on that package accordingly + - update debian/rules + - update debian/control + + -- Alexander Sack Sat, 03 May 2008 01:08:17 +0200 + +xulrunner-1.9 (1.9~b5+nobinonly-0ubuntu3) hardy; urgency=low + + * j2re1.4 is the package that ships the plugin, not the mozilla-plugin + package. fixing conflicts for LP: #214468. + - update debian/control + + -- Alexander Sack Tue, 15 Apr 2008 15:16:07 +0200 + +xulrunner-1.9 (1.9~b5+nobinonly-0ubuntu2) hardy; urgency=low + + * fix "firefox-3.0 gets removed on dist-upgrade when firefox-3.0 build is + not available on mirror". We deal with this situation by dropping the + Break: field from xulrunner-1.9 and adding upper bounds on xulrunner-1.9 + to firefox-3.0 binary. + - update debian/control + + * improve translation support by shipping a crafted install.rdf. We ship a + template install.rdf.in in debian/translation-support and replace the + em:{version,maxVersion,minVersion} during build. For now those versions + are maintained manually because we need maintainer attention on upgrades + considering the upstream string freeze. To increase failsafeness, we fail + the build if the version appears to be out of sync with the upstream + version in the post-install target. The install.rdf is finally added to + the zip file in the binary-post-install rule used to produce the + en-US.xpi. + - add debian/translation-support/install.rdf.in + - update debian/rules + + * fix "USE_SYSTEM_NSS checks nspr version, not nss" + - update debian/rules + + * fix "firefox resets user prefs if the user sets a preference that is equal + to the default shipped by firefox/xulrunner that was overloaded with an + extension default (aka ubufox). (LP: #203306). Patch ported from ffox 2 + package. + - add debian/patches/bzXXX-dont-reset-user-prefs-on-upgrade.patch + - update debian/patches/series + + * fix "broken wizard binding with javascript policies in place" - + For particular, this fixes "plugin installer wizard broken with adblock or + noscript installed" (LP: #215672). Patch taken from bugzilla 425814 + - add debian/patches/bz425814_att315081.patch + - update debian/patches/series + + * conflict with removed from archive package j2re1.4-mozilla-plugin as it + causes crashes in latest gecko code (LP: #214468) + - update debian/control + + -- Alexander Sack Tue, 15 Apr 2008 11:59:05 +0200 + +xulrunner-1.9 (1.9~b5+nobinonly-0ubuntu1) hardy; urgency=low + + [ Fabien Tassin ] + * Drop patch applied upstream + - drop debian/patches/bz333308_attXXXX_make_clean_cleaner.patch + - update debian/patches/series + * Set LDFLAGS so dpkg-buildpackage doesn't use -Wl,-Bsymbolic-functions + - update debian/rules + * Add support for a defaults/syspref directory containing system wide + preferences that will not be silently overwritten at each upgrade + (LP: #207281, #203538). + It works for both libxul apps such as firefox 3 and xulrunner + applications such as prism + - add debian/patches/add_syspref_dir.patch + - update debian/patches/series + * Fix broken RSS subscription + - add debian/patches/bz423060_att312807_fix_rss_subscription.patch + - update debian/patches/series + * Bump depends to libnspr4-dev >= 4.7.1~beta2 and libnss3-dev >= 3.12.0~beta3 + - update update debian/control + * Hook up mozilla-devscript's compare module to binary-post-install + - update debian/rules + + [ Alexander Sack ] + * switch to in-source jpeg to fix rendering issues at zoom levels + (LP: #182038); this measure should give us some performance + improvements. + - update debian/rules + * make pref extensions read defaults/autoconfig from NS_GRE_DIR instead + of NS_APP_DEFAULTS_50_DIR. If it turns out to be a bad decision, we should + reconsider this patch. + - add debian/patches/bzXXX_autoconfig_in_gre.patch + - update debian/patches/series + * install system-greprefs in /etc/xulrunner-1.9/ and create the proper + link in $pkglibdir/greprefs to it (LP: #139543) + - add debian/system-greprefs.js + - update debian/rules + * ship versioned link libsqlite3.so.0 => libsqlite3.so in $pkglibdir to + allow liferea workaround for LP: #203413 - "Liferea creates many corrupt + copies of places.sqlite in" by setting LD_LIBRARY_PATH properly + - update debian/rules + * ship .autoreg file in pkglibdir to allow autoreg touches by + plugins/extensions et al. + - update debian/rules + * touch .autoreg in xulrunner-1.9.postinst and + xulrunner-1.9-gnome-support.postinst + - update debian/xulrunner-1.9.postinst + - add debian/xulrunner-1.9-gnome-support.postinst + * hook in lp-export-xpi.mk from mozilla-devscript to export en-US + translation templates to debian/lp-export-xpis/; in turn, make + mozilla-devscripts a hard build-depends + - update debian/rules + - update debian/control + * consider NS_GRE_DIR/.autoreg to trigger component registry upgrades. + - add debian/patches/bzXXX_gre_autoreg.patch + - update debian/control/series + * Fix "Dom Inspector not compatible" by bumping maxVersion field in + extension install.rdf + - add debian/patches/inspector_maxversion_bump.patch + - update debian/patches/series + * Fix xulrunner side for bug "firefox needs restart after plugin install to + detect and activate them"; we scan for new plugins in GRE at startup runtime + - update debian/patches/bzXXX_gre_extension_plugin_support.patch + + -- Fabien Tassin Fri, 04 Apr 2008 23:11:10 +0200 + +xulrunner-1.9 (1.9~b4+nobinonly-0ubuntu1) hardy; urgency=low + + * new upstream release 1.9~b4 fixes: + - LP: #194486 - "printing in Firefox 3 Beta 3 is broken" + - LP: #192505 - "Where's my home button?" + - LP: #44062 - "Firefox allows cookies to be set for second-level + domain hierarchies" + - LP: #181575 - "pressing Enter in URL bar selects mouse hover target + in substring-search pop-down" + + [ Fabien Tassin ] + * Drop patches applied upstream + - drop debian/patches/bz344818_cairo_xrender.patch + - drop debian/patches/bzXXX_fix_pyxpcom_build_failure.patch + * Update diverged patch: + - update debian/patches/dom_inspector_support_for_prism.patch + * Add support for system hunspell + - update debian/rules + * Add optional support for system sqlite3 (we need >= 3.5 not in hardy) + - update debian/rules + * Update clean rule to make it simpler and more friendly with + mozilla-devscripts + - update debian/rules + * Drop DEB_AUTO_UPDATE_DEBIAN_CONTROL cdbs variable completely. It was + wrongly set to zero + - update debian/rules + * Update clean rule now that Mozilla bug 333308 has landed. + To prevent a bug in cdbs where patches are unapplied before distclean + is performed, set DEB_MAKE_CLEAN_TARGET to $(NULL) and add call + distclean ourselves before cdbs files are included + - update debian/rules + * There're still some leftovers after distclean despite latest + Mozilla bug 333308 patch. Fix it once again and report it upstream + - add debian/patches/bz333308_attXXXX_make_clean_cleaner.patch + - update debian/patches/series + * Drop obsolete comment for extensions + - update debian/rules + * Stop build-tree/mozilla/README to be shipped as a doc by setting + cdbs DEB_INSTALL_DOCS_ALL to $(NULL) + - update debian/rules + * Drop obsolete TODO file + - drop debian/TODO + + [ Alexander Sack ] + * fix "remember password" dialog for embedders that don't provide + a branding chrome + - add debian/patches/bzXXX_attXXX_fix_remember_password_for_embedders_without_branding.patch + - update debian/patches/series + * fix LP: #175904 "Firefox 3.0 makes everything annoyingly huge" by not + scaling images based on dpi. + - add debian/patches/bz394103_dont_scale_images.patch + - update debian/patches/series + * add alternative patch for LP: #175904 "Firefox 3.0 makes everything + annoyingly huge" by scaling images for 192dpi, 288dpi, etc. instead + of 142dpi, 238dpi and so on. (this patch is not applied atm and is + included for testing purpose) + - add debian/patches/bz394103_scale_images_for_192+dpi.patch + * add libsqlite3-dev to Build-Depends in order to effectively enable + optional system sqlite feature on buildd's with sqlite > 3.5 + - update debian/control + * bump build requirements on nspr and nss to >= 4.7.0~1.9b4 and + >= 3.12.0~1.9b4 respectively + - update debian/control + + -- Alexander Sack Tue, 11 Mar 2008 02:06:46 +0100 + +xulrunner-1.9 (1.9~b3+nobinonly-0ubuntu3) hardy; urgency=low + + * add two patches for mozilla bug 394103 "All elements are HUGE" and enable + bz394103_dont_scale_images.patch for now (LP: #178558) + - add debian/patches/bz394103_dont_scale_images.patch + - add debian/patches/bz394103_scale_images_for_192+dpi.patch + - update debian/patches/series + + -- Alexander Sack Mon, 25 Feb 2008 11:45:00 +0100 + +xulrunner-1.9 (1.9~b3+nobinonly-0ubuntu2) hardy; urgency=low + + * add Breaks: firefox-3.0 (<< 3.0~b3) to fix transition breakage + - update debian/control + + -- Alexander Sack Thu, 14 Feb 2008 16:51:05 +0100 + +xulrunner-1.9 (1.9~b3+nobinonly-0ubuntu1) hardy; urgency=low + + * release FIREFOX_3_0b3_RELEASE + + [ Alexander Sack ] + * submit patch that ships xpcshell to bugzilla + - rename debian/patches/ship_xpcshell.patch => + debian/patches/bz410617_att295212_ship_xpcshell.patch + - update debian/patches/series + * fix tooltip in epiphany: previously displayed out of screen bounds + (LP: #37507) + - add debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch + - update debian/patches/series + * use default upstream gcc tweaks for improved performance - especially of the + javascript engine + - update debian/rules + * update global extension/plugin patch to apply cleanly against latest code + - update debian/patches/bzXXX_gre_extension_plugin_support.patch + * fix pyxpcom build failure introduced by recent commit + - add debian/patches/bzXXX_fix_pyxpcom_build_failure.patch + - update debian/patches/series + * add distro independent global install locations for extensions, + /usr/lib/mozilla/extensions and /usr/share/mozilla/extensions + - update debian/xulrunner-1.9.dirs + * support embedded tarball layout when either there is a *.tar.bz2 in orig tarball + or if DEBIAN_MOZCLIENT_EMBEDDED is not unset (you will need this to produce embedded + tarballs during |get-orig-source| + - update debian/rules + * bump minimum libnss3-dev build requirements to >= 3.12.0~1.9b3 + - update debian/control + * bump minimum libnspr4-dev build requirements to >= 4.7.0~1.9b3 + - update debian/control + + [ Fabien Tassin ] + * Drop patches applied upstream + - drop debian/patches/bz410617_att295212_ship_xpcshell.patch + - drop debian/patches/bz404634_att294921.patch + - drop debian/patches/bz386610_python2.5_ftbfs_amd64.patch + - drop debian/patches/bz373918_att295042.patch + - drop debian/patches/bz408062_unstable_pc.patch + - drop debian/patches/bz384304_fix_recursive_symlinks.patch + - update debian/patches/series + * Refresh diverged patches: + - update debian/patches/bzXXX_pc_honour_system_nspr_nss.patch + - update debian/patches/rename_venkman_addon.patch + - update debian/patches/bz344818_cairo_xrender.patch + * Install links for all .so libs in the -dev package + - update debian/patches/dont_install_so_in_dev.patch + * Bump gtk requirement to 2.12 as per Mozilla bug 412432 + - update debian/control + * Add #DEBHELPER# token to postinst/prerm scripts + - update debian/xulrunner-1.9.{postinst,prerm} + * Install previously missed libdbusservice.so + - update debian/xulrunner-1.9.install + * Update venkman patch to also rename locales + - update debian/patches/rename_venkman_addon.patch + * Bump requirement for system cairo to >= 1.5.8 as we now need + the newly added cairo_path_extents() + - update debian/rules + * Include mozilla-devscripts file using -include so ifneq could be omitted + - update debian/rules + * Fix missing .so symlinks regression + - update debian/patches/dont_install_so_in_dev.patch + + -- Alexander Sack Wed, 13 Feb 2008 11:47:21 +0100 + +xulrunner-1.9 (1.9~b3~cvs20080101t1000+nobinonly-0ubuntu1) hardy; urgency=low + + * happy new year release for hardy (1.9b3 pre, CVS 20080101t1000) features: + - use system-cairo (LP: #152210, LP: #164640) + - use system-nspr/nss (LP: #177280) + - proper pkg-config files for -unstable and system-nspr/nss (see below) + - backed-out microb changes (back to square zero) + - fix various embedding issues (see below) + + [ Fabien Tassin ] + * Disable bz404634_att290373.patch and bz373196_att281782.patch until trunk + is back in shape after the MicroB mass back out (See MozBug #408238) + - update debian/patches/series + * new upstream snapshot (1.9b3 pre, CVS 20071228t0918) + * Drop patch committed upstream: + - drop debian/patches/bz287150_att291740_hppa_fix.patch + - update debian/patches/series + * Add support for mozilla-devscripts + - update debian/control + - update debian/rules + + [ Alexander Sack ] + * drop patches for mozilla bug #404634 completely to prepare landing of + improved patch: + - drop debian/patches/bz404634_att290305.patch + - drop debian/patches/bz404634_att290373.patch + - update debian/patches/series + * land improved patch for mozilla bug #404634 that properly disables + url-classifier if no profile is setup and makes nsUrlClassifierDBService + fall-back to NS_APP_USER_PROFILE_50_DIR if NS_APP_USER_PROFILE_LOCAL_50_DIR + is not provided by embedding app. + - add debian/patches/bz404634_att294921.patch + - update debian/patches/series + * remove bz373196_att281782.patch completely from tree as it tackled a MICROB + regression, which should now be fixed. + * add %FULL_NSPR_CFLAGS% to libxul-embedding* Cflags .pc files to fix + builds of embedders that link against system-nspr enabled xul + - update debian/patches/bzXXX_pc_honour_system_nspr_nss.patch + * do not export zlib headers with bogus symbols during make install if + system zlib is used. This breaks embedders and happens if MOZ_INSTALLER + is enabled. + - add debian/patches/bzXXX_no_zlib_export_if_native.patch + - update debian/patches/series + * drop mozilla-devscripts from build-depends as its not needed for the + actual package build process. Take care that debian/rules disables the + mozilla-devscripts include if it doesn't exist + - update debian/control + - update debian/rules + * add gtkmozembed_internal.h symbols to glue (mozilla bug 373918): + - add debian/patches/bz373918_att295042.patch + - update debian/patches/series + * add support for GRE extensions and plugins. We now search in PROFILE, APP + and GRE dir. + - add debian/patches/bzXXX_gre_extension_plugin_support.patch + - update debian/patches/series + * explicitly create addon directories /usr/lib/xulrunner-addons/{plugins,extensions} + - update debian/xulrunner-1.9.dirs + * drop hard-coded --with-system-nspr and --with-system-nss from CONFIGURE + flags + - update debian/rules + * don't enforce lower bound of system cairo and system nss versions + - update debian/control + + -- Alexander Sack Wed, 02 Jan 2008 14:55:34 +0100 + +xulrunner-1.9 (1.9~b2+nobinonly-0ubuntu1) hardy; urgency=low + + [ Fabien Tassin ] + * new upstream snapshot (1.9b2) from tag FIREFOX_3_0b2_RELEASE + * Update diverged patch: + - update debian/patches/bz399589_fix_missing_symbol_with_new_nss.patch + * Fix FTBFS on Hardy when using system nss. See MozBug #403994. + - add debian/patches/bz403994_dont_install_nss_includes_with_system_nss.patch + - update debian/patches/series + * Drop patches for bugs which recently landed + - drop debian/patches/bz405424_att290202.patch + - drop debian/patches/fix_ppc_ftbfs.patch + - update debian/patches/series + * Update rules for system cairo >= 1.5.4. It's still conditioned + by the presence or not of libcairo 1.5.* in hardy, also conditioning + lcd sub-pixel rendering + - update debian/rules + - add debian/patches/bz344818_cairo_xrender.patch + - update debian/patches/series + * add libpixman-1-dev to build-deps, needed by cairo + - update debian/control + * Update Standards-Version to 3.7.3 + - update debian/control + * Re-enable DEB_AUTO_UPDATE_AUTOCONF=2.13 and depends on autoconf2.13 + (will be dropped for final release) + - update debian/control + - update debian/rules + * Fold Build-Depends line making changes easier to track in diffs + and update versions based on http://wiki.mozilla.org/Linux/Runtime_Requirements + - update debian/control + * Add --enable-startup-notification and libstartup-notification0-dev to build-deps + - update debian/rules + - update debian/control + * Rewrite detection code for system nss and nspr, to ease backports to gutsy + - update debian/rules + * Fix FTBFS on hppa (See MozBug #287150) + - add debian/patches/bz287150_att291740_hppa_fix.patch + - update debian/patches/series + + [ Alexander Sack ] + * force system cairo by adding versioned build-depends >= 1.5.4 + - update debian/control + * provide libxul-unstable.pc and libxul-embedding-unstable.pc + - add debian/patches/bz408062_unstable_pc.patch + - update debian/patches/series + * fix missing icons if no gnome-support package is installed: move + libimgicon.so component from gnome-support package to plain xulrunner-1.9 + - update debian/xulrunner-1.9.install + - update debian/xulrunner-1.9-gnome-support.install + * fix mozilla-nspr.pc for --with-system-nspr builds: mozilla-nspr.pc points + to the cflags and libs of system nspr now + - add debian/patches/bzXXX_pc_honour_system_nspr_nss.patch + - update debian/patches/series + * enforce libnss3-dev version (>= 3.12.0~1.9b2) + - update debian/control + + -- Fabien Tassin Wed, 19 Dec 2007 20:23:23 +0100 + +xulrunner-1.9 (1.9~b1+nobinonly-0ubuntu2) hardy; urgency=low + + [ Alexander Sack ] + * don't ship versioned .pc files anymore: + - remove debian/patches/install_pkgconfig_files_with_version.patch + - update debian/patches/series + * in turn xulrunner-1.9-dev package needs to Conflicts: on (old) mozilla-dev + - update debian/control + + [ Fabien Tassin ] + * Add Homepage: and Vcs-Bzr: fields in control file + - update debian/control + + -- Alexander Sack Fri, 07 Dec 2007 00:11:43 +0100 + +xulrunner-1.9 (1.9~b1+nobinonly-0ubuntu1) hardy; urgency=low + + * new upstream snapshot (1.9b1 from FIREFOX_3_0b1_RELEASE) + - update debian/changelog + * Fix shell redirection in clean rule leaving orphaned processes + in buildd. (LP: #162723) + - update debian/rules + * Move extensions dir from /usr/lib/xulrunner-addons to + /usr/lib/xulrunner-addons/extensions and move plugins dir + from non-stable /usr/lib/xulrunner-1.9b1/plugins to + /usr/lib/xulrunner-addons/plugins + - update debian/rules + - update debian/xulrunner-1.9.install + - update debian/xulrunner-1.9-dom-inspector.install + - update debian/xulrunner-1.9-venkman.install + * new upstream snapshot (1.9b2pre cvs20071120t1456) + * Drop patches for MozBug #399589 and #403994 which landed: + - drop debian/patches/bz399589_fix_missing_symbol_with_new_nss.patch + - drop debian/patches/bz403994_dont_install_nss_includes_with_system_nss.patch + - update debian/patches/series + * Add libdbus-glib-1-dev >= 0.60 to build-deps. See MozBug #388743. + - update debian/control + * Add a postrm script to clean up left-overs from python/xpcom + - add debian/xulrunner-1.9.postrm.in + - update debian/rules + * Add support for Prism in the dom inspector addon + - add debian/patches/dom_inspector_support_for_prism.patch + - update debian/patches/series + + [ Alexander Sack ] + * GtkEmbed DirectoryProvider provides NS_APP_USER_PROFILE_LOCAL_50_DIR special + directory now: + - add debian/patches/bz404634_att290373.patch + - update debian/patches/series (include currently applied patch) + * GtkEmbedEventListener.cpp now deals properly with selections: + - add debian/patches/bz373196_att281782.patch + - update debian/patches/series + * Fix ia64 build failure (thanks to Raúl Porcel) + - add debian/patches/bz405424_att290202.patch + - update debian/patches/series + * Fix url-classifier for embedders that don't provide a profile path. Use + a temp file to setup the url-classifier database and remove that one when + shutting down cleanly: + - add debian/patches/bz404634_att290305.patch + - update debian/patches/series + + -- Fabien Tassin Tue, 27 Nov 2007 16:01:49 +0100 + +xulrunner-1.9 (1.9~b1~rc3+nobinonly-0ubuntu1) hardy; urgency=low + + [ Fabien Tassin ] + * new upstream snapshot (1.9a9pre cvs20071012t0843) + * Drop debian/patches/bz392722_fix_nsinstall_on_double_slash.patch + (MozBug #397296 bumped nss/nspr requirements) + - update debian/patches/series + * Fix ftbfs with new nss caused by landing of MozBug #286642. + See MozBug 399589 + - add debian/patches/bz399589_fix_missing_symbol_with_new_nss.patch + - update debian/patches/series + * Ship xpcshell as /usr/bin/xpcshell-1.9 (LP: #151400) + - update debian/rules + - add debian/patches/ship_xpcshell.patch + - update debian/patches/series + * new upstream snapshot (1.9a9pre cvs20071105t0339) + - update debian/changelogs + * Move gnome libs from xulrunner-1.9 to xulrunner-1.9-gnome-support + - update debian/control + - update debian/xulrunner-1.9.install + - add debian/xulrunner-1.9-gnome-support.install + * new upstream snapshot (1.9b1 rc3 from FIREFOX_3_0b1_RC3) + - update debian/changelogs + * Fix broken --with-default-mozilla-five-home value + - update debian/rules + + [ Alexander Sack ] + * fix alternative migration bug that appears to happen on upstream version + upgrades: uninstall xulrunner alternative during "remove" and "upgrade" in + xulrunner-1.9.prerm + - update debian/xulrunner-1.9.prerm + + -- Fabien Tassin Wed, 14 Nov 2007 15:09:56 +0100 + +xulrunner-1.9 (1.9~a9~cvs20071003t0648-0ubuntu1~mt2) gutsy; urgency=low + + RELEASE: 1.9~a9~cvs20071003t0648-0ubuntu1~mt2 to gutsy/PPA + + * Add /usr/bin/xulrunner-1.9 and make the alternative point to it so + xul apps that need xul 1.9 can use it. subst is no longer needed for + postinst/prerm scripts. + - rename and update: + - debian/xulrunner-1.9.postinst.in => debian/xulrunner-1.9.postinst + - debian/xulrunner-1.9.prerm.in => debian/xulrunner-1.9.prerm + - update debian/rules + + -- Fabien Tassin Mon, 08 Oct 2007 16:44:01 +0200 + +xulrunner-1.9 (1.9~a9~cvs20071003t0648-0ubuntu1~mt1) gutsy; urgency=low + + RELEASE: 1.9~a9~cvs20071003t0648-0ubuntu1~mt1 to gutsy/PPA + + [ Fabien Tassin ] + * Add --disable-mochitest to debian/rules + * Protect tests targets by ifdefs so --disable-tests does the proper thing. + This is usefull for the stripped tarball. + - add debian/patches/protect_tests_by_ifdefs.patch + - update debian/patches/series + * Remove strict version check for extensions + - update debian/control + + [ Alexander Sack ] + * unify test for dev-package in var DEV_PACKAGE_INDICATION and determine + whether to point libnssckbi.so to system nss using this test. + * drop versions from build-depends and depends on libnspr4-dev, libnss3-dev. + We use this to be able to use the same sources for both official uploads + (which uses in-xul nspr/nss) and dev/ppa uploads (which use system + nspr/nss). + + -- Fabien Tassin Sun, 07 Oct 2007 20:52:39 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu2) gutsy; urgency=low + + * debian/rules don't install link to system libnssckbi.so in order to use + xulrunner provided nss. (LP: #149822) + + -- Alexander Sack Sat, 06 Oct 2007 14:23:09 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu1) gutsy; urgency=low + + RELEASE: 1.9~a8 upload to gutsy. + + [ Alexander Sack ] + * debian/rules: use EXTRA_SYSTEM_CONFIGURE_FLAGS to only use system-nss/-nspr + for cvs and mt builds. + * debian/control: drop build-depends on system-nss/-nspr ... later this + should be depent on the same test as EXTRA_SYSTEM_CONFIGURE_FLAGS. + * debian/patches/install_pkgconfig_files_with_version.patch: update patch + to ship versioned pkgconfig files: mozilla-nspr-1.9.pc and + mozilla-nss-1.9.pc when xulrunner is not using system nspr/nss. + * debian/control: drop system nspr/nss depends of xulrunner-1.9-dev. + + -- Alexander Sack Fri, 05 Oct 2007 01:43:55 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu1~mt4) gutsy; urgency=low + + [Fabien Tassin ] + * Compile with gcc/g++ 4.2 for all archs. + * Fix a nasty variable bug in debian/rules not doing + the proper substitution in postinst/prerm + + -- Alexander Sack Fri, 28 Sep 2007 23:31:04 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu1~mt3) gutsy; urgency=low + + [ Fabien Tassin ] + * DEBIAN_XUL_DIR is evaluated too early, replace ':=' by '='. + update debian/rules + * update debian/patches/rename_venkman_addon.patch as + a file was missing + + -- Alexander Sack Fri, 28 Sep 2007 17:12:45 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu1~mt2) gutsy; urgency=low + + [ Fabien Tassin ] + * Install addons in /usr/lib/xulrunner-addons: + - add debian/xulrunner-1.9.dirs + - update debian/rules to install a symlink + for /usr/lib/xulrunner-1.9*/extensions + * Create a package called xulrunner-1.9-dom-inspector + - update debian/rules + - add debian/xulrunner-1.9-dom-inspector.install + * Create a package called xulrunner-1.9-venkman + - update debian/rules + - add debian/debian/xulrunner-1.9-venkman.install + - add debian/patches/rename_venkman_addon.patch + - update debian/patches/series + * Install /usr/bin/xulrunner as an alternative + - add debian/xulrunner-1.9.postinst.in + - add debian/xulrunner-1.9.prerm.in + - update debian/rules + - update debian/xulrunner-1.9.install + * Add debian/patches/bz384304_fix_recursive_symlinks.patch + and update debian/patches/series + * Add Conflicts xulrunner (<< 1.8.1.4-2ubuntu4) so that + we can coexist with xulrunner 1.8 using alternatives + + -- Alexander Sack Tue, 25 Sep 2007 23:59:53 +0200 + +xulrunner-1.9 (1.9~a8-0ubuntu1~mt1) gutsy; urgency=low + + Upstream Release: 1.9~a8 aka MOZILLA_1_9a8_RELEASE + + [ Fabien Tassin ] + * Add --disable-install-strip to debian/rules (introduced + by Mozilla bug #391325) + * Don't install .so libs in -dev but link them instead + Add debian/patches/dont_install_so_in_dev.patch + * Make xulrunner-1.9-dev depend on lib{nss3,nspr4}-dev + * Don't hardcode xul version in debian/xulrunner-1.9.links + but link in debian/rules instead + + [ Alexander Sack ] + * debian/rules: redirect output of finds in clean target to /dev/null + + -- Alexander Sack Tue, 25 Sep 2007 01:46:53 +0200 + +xulrunner-1.9 (1.9~a8~cvs20070913t1423-0ubuntu1~mt2) gutsy; urgency=low + + [ Fabien Tassin ] + * Remove Build-Depends-Indep as java is not needed + * Add --enable-safe-browsing to debian rules as it's good for us + and it brings the missing --enable-url-classifier + * Make the installer complain about missing files on stdout + instead of stderr so logs are easier to read. + Add debian/patches/installer_use_stdout_for_missing_files.patch + and update debian/patches/series + + -- Alexander Sack Mon, 17 Sep 2007 21:33:45 +0200 + +xulrunner-1.9 (1.9~a8~cvs20070913t1423-0ubuntu1~mt1) gutsy; urgency=low + + [ Fabien Tassin ] + * Add debian/patches/fix_ppc_ftbfs.patch to fix FTBFS on powerpcc: + now look for Linuxpowerpc instead of Linuxppc + (contributed by Luke Yelavich ) + * Add --enable-extensions to build xml-rpc, venkman, inspector, irc, gnomevfs, + cview, tasks, reporter and python/xpcom + * Add --enable-webservices + * Drop --disable-debug (it's the default) + * Add a clean rule to take care of some leftovers + * Add debian/xulrunner-1.9.links to link /usr/lib/nss/libnssckbi.so in + /usr/lib/xulrunner-1.9a8pre/libnssckbi.so in order to provide to all xul + applications CA certificates. + * update debian/patches/bz392722_fix_nsinstall_on_double_slash.patch + update from firefox-trunk to reflect upstream partial commit. + + [ Alexander Sack ] + * debian/patches/bz386610_python2.5_ftbfs_amd64.patch,series: add patch from + bugzilla 386610 that fixes ftbfs on amd64 with python2.5. + + -- Alexander Sack Sat, 08 Sep 2007 15:03:13 +0200 + +xulrunner-1.9 (1.9~a8~cvs20070829-0ubuntu1~mt1) gutsy; urgency=low + + [ Fabien Tassin ] + * new upstream snapshot (1.9a8pre cvs20070829) + * Add debian/copyright + * Update debian/changelog to use a proper versionning scheme. + * Make xulrunner-1.9-dev depend on xulrunner-1.9 (update debian/control) + * Update Maintainer in debian/control to Mozilla team. + * Update debian/control to fix Build-Depends: drop dpatch, add quilt, cdbs, + zip. + * Update debian/rules to stop running autoconf. + * Add debian/patches/bz392722_fix_nsinstall_on_double_slash.patch fixing + nsinstall (patch reused from firefox-trunk) + * Add debian/patches/install_pkgconfig_files_with_version.patch so we + can install multiple xulrunner-dev and still use pkg-config + * Add debian/patches/series + * Update debian/control to create a -dev package + * Add debian/xulrunner-1.9.install and debian/xulrunner-1.9-dev.install + to move files to -dev package + + -- Fabien Tassin Wed, 29 Aug 2007 20:53:27 +0200 + +xulrunner-1.9 (1.9~a8~cvs20070824-0ubuntu1) gutsy; urgency=low + + [ Fabien Tassin ] + * new upstream snapshot (1.9a8pre cvs20070824) + * initial packaging inspired from firefox-trunk and reusing + package descriptions from previous xulrunner package. + Create xulrunner-1.9 and xulrunner-1.9-dev. + + -- Fabien Tassin Fri, 24 Aug 2007 22:01:38 +0000 --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.postinst.in +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.postinst.in @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +XUL_VERSION=@XULBRANCH@ +GRE_VERSION=`/usr/bin/xulrunner-$XUL_VERSION --gre-version` + +if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then + /usr/sbin/update-alternatives --install /usr/bin/xulrunner \ + xulrunner /usr/bin/xulrunner-$XUL_VERSION 50 + if test -e /usr/lib/xulrunner-$GRE_VERSION/.autoreg; then + touch /usr/lib/xulrunner-$GRE_VERSION/.autoreg + fi + + # Remove possible left-over + if [ -f /etc/ld.so.conf.d/xulrunner-$XUL_VERSION ] ; then + rm -f /etc/ld.so.conf.d/xulrunner-$XUL_VERSION + fi + + ldconfig +fi + +#DEBHELPER# --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/copyright +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/copyright @@ -0,0 +1,651 @@ +This package was debianized by Fabien Tassin on 2007-08-25 + +The following file has been previously maintained by Mike Hommey +and updated by Fabien Tassin as of xulrunner 1.9a8pre. + +The package was downloaded from http://ftp.mozilla.org/pub/mozilla.org/xulrunner/ + +EDIT: downloaded from CVS (until 1.9 is released) using the following commands: + cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/client.mk + make -f mozilla/client.mk checkout MOZ_CO_PROJECT=xulrunner + +The source tarball is an aggregate of several different works in which the +main one, developed by the Mozilla Project, is xulrunner. + +The contents of the debian directory are licensed like the bulk of +xulrunner, tri-licensed under the GPL/LGPL/MPL. + +Other works include gzip, bzip2, sqlite, libjpeg, libpng, cairo, and others. +Please see the sections following the copyright statements for xulrunner for +these. + +If this file is incomplete, which I'm pretty sure is the case, because it's +difficult not to forget anything in this huge amount of data, please file +a bug or contact me. + +=== xulrunner + +Overall, the xulrunner project is licensed under the terms of the Mozilla +Public License version 1.1 or, at your option, under the terms of the GNU +General Public License version 2 or subsequent, or the terms of the GNU +Lesser General Public License version 2.1 or subsequent. + +On Debian systems, the complete text of the GNU General Public +License can be found in the file `/usr/share/common-licenses/GPL' ; +the complete text of the GNU Lesser General Public License can be +found in the file `/usr/share/common-licenses/LGPL'. + +The complete text of the Mozilla Public License can be found in the MPL file +in the same directory as this file. + +Some of the files are also licensed (single, dual or tri) under the terms of +the Netscape Public License (NPL) which can be found as amendments to the +MPL at the end of the file. Please refer to http://www.mozilla.org/MPL/relicensing-faq.html + +While the Mozilla Project is undergoing a global relicensing so that the +aim is to have a full tree with these tri-license terms, there are at the +moment quite some exceptions as following: + +(Note that I sometimes assumed files not explicitely licensed to be licensed +under the same terms as the files around them and that a lot of the +information has been extracted automatically, thus maybe leaving some doubt. +Again, if you find "bugs", please contact me by email or via the BTS.) + +The following files are not tri-licenced MPL/GPL/LGPL: + +- GPL only: + dom/tests/mochitest/ajax/jquery/dist/jquery.js + dom/tests/mochitest/ajax/jquery/src/jquery/jquery.js + +- MPL and GPL: + embedding/browser/activex/src/install/README.txt + +- MPL and LGPL: + gfx/cairo/cairo/* + +- GPL and LGP: + extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp + extensions/pref/system-pref/src/gconf/nsSystemPrefService.h + extensions/pref/system-pref/src/nsSystemPref.cpp + extensions/pref/system-pref/src/nsSystemPref.h + extensions/pref/system-pref/src/nsSystemPrefFactory.cpp + extensions/pref/system-pref/src/nsSystemPrefLog.h + netwerk/base/public/nsIIOService2.idl + netwerk/base/public/nsINetworkLinkService.idl + netwerk/streamconv/converters/mozTXTToHTMLConv.cpp + netwerk/streamconv/converters/mozTXTToHTMLConv.h + netwerk/streamconv/public/mozITXTToHTMLConv.idl + toolkit/system/dbus/nsDBusModule.cpp + toolkit/system/dbus/nsDBusService.cpp + toolkit/system/dbus/nsDBusService.h + toolkit/system/dbus/nsNetworkManagerListener.cpp + toolkit/system/dbus/nsNetworkManagerListener.h + +- NPL only (thus MPL): (EDIT: to investigate) + intl/uconv/ucvibm/864i.uf + intl/uconv/ucvibm/cp850.uf + intl/uconv/ucvibm/cp852.uf + intl/uconv/ucvibm/cp855.uf + intl/uconv/ucvibm/cp857.uf + intl/uconv/ucvibm/cp862.uf + intl/uconv/ucvibm/cp864.uf + intl/uconv/ucvmath/mathematica1.uf + intl/uconv/ucvmath/mathematica2.uf + intl/uconv/ucvmath/mathematica3.uf + intl/uconv/ucvmath/mathematica4.uf + intl/uconv/ucvmath/mathematica5.uf + intl/uconv/ucvmath/mtextra.uf + intl/uconv/ucvmath/texcmex-t1.uf + intl/uconv/ucvmath/texcmex-ttf.uf + intl/uconv/ucvmath/texcmmi-t1.uf + intl/uconv/ucvmath/texcmmi-ttf.uf + intl/uconv/ucvmath/texcmr-ttf.uf + intl/uconv/ucvmath/texcmsy-t1.uf + +- Public Domain: + aclocal.m4 + build/autoconf/freetype2.m4 + build/autoconf/gtk.m4 + build/autoconf/nspr.m4 + db/mork/src/morkDeque.cpp + db/mork/src/morkDeque.h + +The file db/mork/src/morkQuickSort.cpp is licensed under the following terms: + + Copyright (c) 1992, 1993 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +The following files come from X11R5, without any clear licensing terms: + + build/autoconf/install-sh + directory/c-sdk/config/autoconf/install-sh + nsprpub/build/autoconf/install-sh + +The embedding/qa/mozembed/public/nsIQABrowserUIGlue.idl file and the files +under the embedding/tests directory are licensed under the following terms: + + Copyright (c) 2002 Netscape Communications Corporation and + other contributors + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this Mozilla sample software and associated documentation files + (the "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +=== sqlite + +The db/sqlite3 directory contains a copy of sqlite with the following +licensing terms: + + The author disclaims copyright to this source code. In place of + a legal notice, here is a blessing: + + May you do good and not evil. + May you find forgiveness for yourself and forgive others. + May you share freely, never taking more than you give. + +=== dbm + +The dbm directory, except the files listed under the xulrunner section, is +licensed under the following terms: + + Copyright (c) 1991, 1993, 1994 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +=== myspell + +The extensions/spellcheck/myspell directory is licensed under the following +terms: + + Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada + And Contributors. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. All modifications to the source code must be clearly marked as + such. Binary redistributions based on modified source code + must be clearly marked as modified versions in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +=== boehm + +The gc/boehm directory, except the files listed under the xulrunner section, +is licensed under the following terms: + + Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers + Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. + Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. + + THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + + Permission is hereby granted to use or copy this program + for any purpose, provided the above notices are retained on all copies. + Permission to modify the code and to distribute modified code is granted, + provided the above notices are retained, and a notice that the code was + modified is included with the above copyright notice. + +=== cairo + +The gfx/cairo/cairo directory is licensed under the following terms: + + Copyright (c) 2003 University of Southern California + Copyright (c) 1999 Tom Tromey + Copyright (c) 2002, 2003 University of Southern California + Copyright (c) 2004 Calum Robinson + Copyright (c) 2004 David Reveman + Copyright (c) 2000, 2002, 2004 Keith Packard + Copyright (c) 2004, 2005 Red Hat, Inc + + Cairo is free software and is available to be redistributed and/or + modified under the terms of either the GNU Lesser General Public + License (LGPL) version 2.1 or the Mozilla Public License (MPL) version + 1.1. + +=== libpixman + +The gfx/cairo/libpixman directory is licensed under the following terms: +(from gfx/cairo/libpixman/COPYING) + + libpixregion + + Copyright 1987, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + + + Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Digital not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + + ---------------------------------------------------------------------- + libic + + Copyright © 2001 Keith Packard + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of Keith Packard not be used in + advertising or publicity pertaining to distribution of the software without + specific, written prior permission. Keith Packard makes no + representations about the suitability of this software for any purpose. It + is provided "as is" without express or implied warranty. + + KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + ---------------------------------------------------------------------- + slim + + slim is Copyright © 2003 Richard Henderson + + Permission to use, copy, modify, distribute, and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Richard Henderson not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. Richard Henderson + makes no representations about the suitability of this software for + any purpose. It is provided "as is" without express or implied + warranty. + + RICHARD HENDERSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + EVENT SHALL RICHARD HENDERSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + +=== libjpeg + +The jpeg directory, except the files under the xulrunner section, are licensed +under the following terms: + + The authors make NO WARRANTY or representation, either express or implied, + with respect to this software, its quality, accuracy, merchantability, or + fitness for a particular purpose. This software is provided "AS IS", and you, + its user, assume the entire risk as to its quality and accuracy. + + This software is copyright (C) 1991-1998, Thomas G. Lane. + All Rights Reserved except as specified below. + + Permission is hereby granted to use, copy, modify, and distribute this + software (or portions thereof) for any purpose, without fee, subject to these + conditions: + (1) If any part of the source code for this software is distributed, then this + README file must be included, with this copyright and no-warranty notice + unaltered; and any additions, deletions, or changes to the original files + must be clearly indicated in accompanying documentation. + (2) If only executable code is distributed, then the accompanying + documentation must state that "this software is based in part on the work of + the Independent JPEG Group". + (3) Permission for use of this software is granted only if the user accepts + full responsibility for any undesirable consequences; the authors accept + NO LIABILITY for damages of any kind. + + These conditions apply to any software derived from or based on the IJG code, + not just to the unmodified library. If you use our work, you ought to + acknowledge us. + + Permission is NOT granted for the use of any IJG author's name or company name + in advertising or publicity relating to this software or products derived from + it. This software may be referred to only as "the Independent JPEG Group's + software". + + We specifically permit and encourage the use of this software as the basis of + commercial products, provided that all warranty or liability claims are + assumed by the product vendor. + +=== bzip2 + +The modules/libbz2/src directory is licensed under the following terms: +(from modules/libbz2/src/LICENSE) + + This program, "bzip2", the associated library "libbzip2", and all + documentation, are copyright (C) 1996-2005 Julian R Seward. All + rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. 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 in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Julian Seward, Cambridge, UK. + jseward@acm.org + bzip2/libbzip2 version 1.0.3 of 15 February 2005 + +=== libpng + +The directory modules/libimg/png is licensed under the following terms: +(from modules/libimg/png/LICENSE) + + This copy of the libpng notices is provided for your convenience. In case of + any discrepancy between this copy and the notices in the file png.h that is + included in the libpng distribution, the latter shall prevail. + + COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + + If you modify libpng you may insert additional notices immediately following + this sentence. + + libpng version 1.2.6, September 12, 2004, is + Copyright (c) 2004 Glenn Randers-Pehrson, and is + distributed according to the same disclaimer and license as libpng-1.2.5 + with the following individual added to the list of Contributing Authors + + Cosmin Truta + + libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are + Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + distributed according to the same disclaimer and license as libpng-1.0.6 + with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + + and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + + libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are + distributed according to the same disclaimer and license as libpng-0.96, + with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + + libpng versions 0.89, June 1996, through 0.96, May 1997, are + Copyright (c) 1996, 1997 Andreas Dilger + Distributed according to the same disclaimer and license as libpng-0.88, + with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + + libpng versions 0.5, May 1995, through 0.88, January 1996, are + Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + + For the purposes of this copyright and license, "Contributing Authors" + is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + + The PNG Reference Library is supplied "AS IS". The Contributing Authors + and Group 42, Inc. disclaim all warranties, expressed or implied, + including, without limitation, the warranties of merchantability and of + fitness for any purpose. The Contributing Authors and Group 42, Inc. + assume no liability for direct, indirect, incidental, special, exemplary, + or consequential damages, which may result from the use of the PNG + Reference Library, even if advised of the possibility of such damage. + + Permission is hereby granted to use, copy, modify, and distribute this + source code, or portions hereof, for any purpose, without fee, subject + to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + The Contributing Authors and Group 42, Inc. specifically permit, without + fee, and encourage the use of this source code as a component to + supporting the PNG file format in commercial products. If you use this + source code in a product, acknowledgment is not required but would be + appreciated. + + + A "png_get_copyright" function is available, for convenient use in "about" + boxes and the like: + + printf("%s",png_get_copyright(NULL)); + + Also, the PNG logo (in PNG format, of course) is supplied in the + files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + + Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a + certification mark of the Open Source Initiative. + + Glenn Randers-Pehrson + glennrp@users.sourceforge.net + September 12, 2004 + +=== zlib + +The directories modules/zlib/src and security/nss/cmd/zlib are licensed under +the following terms: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and 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 in the product documentation 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 source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + If you use the zlib library in a product, we would appreciate *not* + receiving lengthy legal documents to sign. The sources are provided + for free but without warranty of any kind. The library has been + entirely written by Jean-loup Gailly and Mark Adler; it does not + include third-party code. + + If you redistribute modified sources, we would appreciate that you include + in the file ChangeLog history information documenting your changes. Please + read the FAQ for more information on the distribution of modified source + versions. + +=== expat + +The directory parser/expat is licensed under the following terms: +(from parser/expat/COPYING) + + Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + and Clark Cooper + Copyright (c) 2001, 2002 Expat maintainers. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.install +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.install @@ -0,0 +1,11 @@ +debian/tmp/etc/gre.d/1.9*.system.conf +debian/tmp/usr/lib/xulrunner-1.9*/[A-Zdabdf-oq-z]* +debian/tmp/usr/lib/xulrunner-1.9*/platform.ini +debian/tmp/usr/lib/xulrunner-1.9*/plugins usr/lib/xulrunner-addons +debian/tmp/usr/lib/xulrunner-1.9*/python +debian/tmp/usr/lib/xulrunner-1.9*/chrome +debian/tmp/usr/lib/xulrunner-1.9*/components/[A-Za-km-z]* +debian/tmp/usr/lib/xulrunner-1.9*/components/l[a-hj-z]* +debian/tmp/usr/lib/xulrunner-1.9*/components/libpyloader.so +debian/tmp/usr/lib/xulrunner-1.9*/components/libimgicon.so +debian/tmp/usr/lib/xulrunner-1.9*/components/libdbusservice.so --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9-dom-inspector.install +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9-dom-inspector.install @@ -0,0 +1,2 @@ +debian/tmp/usr/lib/xulrunner-1.9*/extensions/inspector@mozilla.org/[cdi]* usr/lib/xulrunner-addons/extensions/inspector@mozilla.org +debian/tmp/usr/lib/xulrunner-1.9*/extensions/inspector@mozilla.org/platform/Linux usr/lib/xulrunner-addons/extensions/inspector@mozilla.org/platform --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.postrm.in +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.postrm.in @@ -0,0 +1,19 @@ +#! /bin/sh + +set -e + +case "$1" in + remove|abort-install|purge|upgrade|failed-upgrade|abort-upgrade|disappear) + rm -f @XULDIR@/python/xpcom/__init__.pyo + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/MPL +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/MPL @@ -0,0 +1,567 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + ---------------------------------------------------------------------- + + AMENDMENTS + + The Netscape Public License Version 1.1 ("NPL") consists of the + Mozilla Public License Version 1.1 with the following Amendments, + including Exhibit A-Netscape Public License. Files identified with + "Exhibit A-Netscape Public License" are governed by the Netscape + Public License Version 1.1. + + Additional Terms applicable to the Netscape Public License. + I. Effect. + These additional terms described in this Netscape Public + License -- Amendments shall apply to the Mozilla Communicator + client code and to all Covered Code under this License. + + II. "Netscape's Branded Code" means Covered Code that Netscape + distributes and/or permits others to distribute under one or more + trademark(s) which are controlled by Netscape but which are not + licensed for use under this License. + + III. Netscape and logo. + This License does not grant any rights to use the trademarks + "Netscape", the "Netscape N and horizon" logo or the "Netscape + lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", + "Smart Browsing" even if such marks are included in the Original + Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + Prior to licensing the Original Code under this License, Netscape + has licensed third party code for use in Netscape's Branded Code. + To the extent that Netscape is limited contractually from making + such third party code available under this License, Netscape may + choose to reintegrate such code into Covered Code without being + required to distribute such code in Source Code form, even if + such code would otherwise be considered "Modifications" under + this License. + + V. Use of Modifications and Covered Code by Initial Developer. + V.1. In General. + The obligations of Section 3 apply to Netscape, except to + the extent specified in this Amendment, Section V.2 and V.3. + + V.2. Other Products. + Netscape may include Covered Code in products other than the + Netscape's Branded Code which are released by Netscape + during the two (2) years following the release date of the + Original Code, without such additional products becoming + subject to the terms of this License, and may license such + additional products on different terms from those contained + in this License. + + V.3. Alternative Licensing. + Netscape may license the Source Code of Netscape's Branded + Code, including Modifications incorporated therein, without + such Netscape Branded Code becoming subject to the terms of + this License, and may license such Netscape Branded Code on + different terms from those contained in this License. + + VI. Litigation. + Notwithstanding the limitations of Section 11 above, the + provisions regarding litigation in Section 11(a), (b) and (c) of + the License shall apply to all disputes relating to this License. + + EXHIBIT A-Netscape Public License. + + "The contents of this file are subject to the Netscape Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/NPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is Mozilla Communicator client code, released + March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1998-1999 Netscape Communications Corporation. All + Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the "[___] License"), in which case + the provisions of [______] License are applicable instead of + those above. If you wish to allow use of your version of this + file only under the terms of the [____] License and not to allow + others to use your version of this file under the NPL, indicate + your decision by deleting the provisions above and replace them + with the notice and other provisions required by the [___] + License. If you do not delete the provisions above, a recipient + may use your version of this file under either the NPL or the + [___] License." --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/create-build-system.sh +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/create-build-system.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +# Copyright (c) 2008 Fabien Tassin +# Description: Create a build-system for xulrunner applications +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# 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. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +############################################################################ + +DIRS="config build toolkit/mozapps/installer" +FILES="configure.in aclocal.m4 allmakefiles.sh toolkit/xre/make-platformini.py nsprpub/config/make-system-wrappers.pl" + +NAME="build-system" + +SRCDIR=mozilla +if [ ! -d $SRCDIR ] ; then + if [ -d build-tree/mozilla ] ; then + SRCDIR=build-tree/mozilla + else + echo "Error: can't find mozilla dir" + exit 1 + fi +fi + +rm -rf $NAME debian/$NAME.tar.gz +mkdir -p $NAME +tar -C $SRCDIR -cf - $DIRS $FILES | tar -C $NAME -xf - +cat - > $NAME/Makefile.in <. +# Portions created by the Initial Developer are Copyright (C) 2007 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Fabien Tassin +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = . +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include \$(DEPTH)/config/autoconf.mk + +include \$(topsrcdir)/config/config.mk + +default alldep all:: + \$(RM) -rf _tests + +TIERS += base + +# +# tier "base" - basic setup +# +tier_base_dirs = \\ + config \\ + build \\ + \$(NULL) + +include \$(topsrcdir)/\$(MOZ_BUILD_APP)/build.mk + +GARBAGE_DIRS += dist _javagen _profile _tests staticlib +DIST_GARBAGE = config.cache config.log config.status config-defs.h \\ + dependencies.beos config/autoconf.mk config/myrules.mk config/myconfig.mk \\ + unallmakefiles mozilla-config.h \\ + netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \\ + \$(topsrcdir)/.mozconfig.mk \$(topsrcdir)/.mozconfig.out + +# Build pseudo-external modules first when export is explicitly called +export:: + \$(MAKE) -C config export + \$(MAKE) tier_nspr + +include \$(topsrcdir)/config/rules.mk + +distclean:: + cat unallmakefiles | \$(XARGS) rm -f + rm -f unallmakefiles \$(DIST_GARBAGE) +EOF + +tar -C $NAME -zcvf debian/$NAME.tar.gz . +rm -rf $NAME --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.preinst.in +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.preinst.in @@ -0,0 +1,39 @@ +#!/bin/sh +set -e + +XUL_VERSION=@XULBRANCH@ +GRE_VERSION=@XULVER@ +OLD_GRE=`echo $2 | sed -e 's/\+.*//' -e 's/~\([^~]*\).*/\1pre/'` + +# Remove a no-longer used conffile +rm_conffile() { + PKGNAME="$1" + CONFFILE="$2" + if [ -e "$CONFFILE" ]; then + md5sum="`md5sum \"$CONFFILE\" | sed -e \"s/ .*//\"`" + old_md5sum="`dpkg-query -W -f='${Conffiles}' $PKGNAME | sed -n -e \"\\\\' $CONFFILE '{s/ obsolete$//;s/.* //p}\"`" + if [ "$md5sum" != "$old_md5sum" ]; then + echo "Obsolete conffile $CONFFILE has been modified by you." + echo "Saving as $CONFFILE.dpkg-bak ..." + mv -f "$CONFFILE" "$CONFFILE".dpkg-bak + else + echo "Removing obsolete conffile $CONFFILE ..." + rm -f "$CONFFILE" + fi + fi +} + +if [ "$1" = "upgrade" ]; then + # Remove all files already obsolete, unless this is one we want to install (downgrade) + for obsolete in `dpkg-query -W -f='${Conffiles}' xulrunner-$XUL_VERSION | grep 'obsolete$' | awk '{ print $1 }'` ; do + if [ "$obsolete" != "/etc/gre.d/$GRE_VERSION.system.conf" ] ; then + rm_conffile xulrunner-$XUL_VERSION "$obsolete" + fi + done + # Remove the previous GRE file, if we just bumped it + if [ "$OLD_GRE" != "$GRE_VERSION" ] ; then + rm_conffile xulrunner-$XUL_VERSION "/etc/gre.d/$OLD_GRE.system.conf" + fi +fi + +#DEBHELPER# --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/system-greprefs.js +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/system-greprefs.js @@ -0,0 +1,6 @@ +// +// insert your system greprefs here +// + +// pref("general.config.filename", "defaults/syspref/system.cfg"); + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9-dev.install +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9-dev.install @@ -0,0 +1,6 @@ +debian/tmp/usr/include/xulrunner-1.9*/ +debian/tmp/usr/share/idl/xulrunner-1.9*/ +debian/tmp/usr/lib/xulrunner-devel-1.9*/ + +debian/tmp/usr/lib/pkgconfig/* /usr/lib/pkgconfig/ + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9.dirs +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9.dirs @@ -0,0 +1,7 @@ +# ubuntu global extension and plugin directories +usr/lib/xulrunner-addons/extensions +usr/lib/xulrunner-addons/plugins + +# distro independent extensions directories for third party installer +usr/lib/mozilla/extensions +usr/share/mozilla/extensions --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/compat +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/compat @@ -0,0 +1 @@ +5 --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/control +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/control @@ -0,0 +1,111 @@ +Source: xulrunner-1.9 +Section: devel +Priority: optional +Maintainer: Ubuntu Mozilla Team +Homepage: http://developer.mozilla.org/en/docs/XULRunner +Vcs-Bzr: https://code.launchpad.net/~mozillateam/xulrunner/xulrunner-1.9.dev +Build-Depends: cdbs, debhelper (>= 5.0.37.2), dpkg-dev (>= 1.13.19), quilt, + autoconf2.13, autotools-dev, + libx11-dev (>= 2:1.0), libxt-dev, + libidl-dev, + libgtk2.0-dev (>= 2.12), libglib2.0-dev (>= 2.12), + libstartup-notification0-dev, + libgnomevfs2-dev (>= 1:2.16), libgnome2-dev (>= 2.16), libgnomeui-dev (>= 2.16), + libdbus-1-dev (>= 1.0.0), libdbus-glib-1-dev (>= 0.60), + libhal-dev (>= 0.5.8), + libcairo2-dev, + libpixman-1-dev, + libpng12-dev (>= 1.2.0), + libjpeg62-dev (>= 6b), + zlib1g-dev (>= 1:1.2.3), libbz2-dev, zip, + libreadline5-dev | libreadline-dev, + libkrb5-dev, + python-dev, python-support (>= 0.3), + binutils (>= 2.17-1) [mips mipsel], + libhunspell-dev (>= 1.1.5-2), + libnspr4-dev (>= 4.7.1~beta2), libnss3-dev (>= 3.12.0~beta3), + libsqlite3-dev, + mozilla-devscripts (>= 0.06~) +Standards-Version: 3.7.3 + +Package: xulrunner-1.9 +Section: devel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: j2re1.4 +Breaks: epiphany-gecko (<< 2.22.1.1-0ubuntu1.8.04.1), + yelp (<< 2.22.1-0ubuntu2.8.04.1), + midbrowser (<< 0.3.0rc1), + devhelp (<< 0.19-1ubuntu1.8.04.1), + firefox-3.0 (<< 3.0.1) +Description: XUL + XPCOM application runner + XULRunner is a single "gecko runtime" that can be used to bootstrap + multiple XUL + XPCOM applications that are as rich as Firefox and + Thunderbird. + . + XUL is Mozilla's XML based User Interface language that lets you build + feature-rich cross platform applications. These applications are easily + customized with alternative text, graphics and layout so that they can be + readily branded or localized for various markets. Web developers already + familiar with Dynamic HTML (DHTML) will learn XUL quickly and can start + building applications right away. + . + XPCOM is a cross platform component model. It has multiple language + bindings and IDL descriptions so programmers can plug their custom + functionality into the framework and connect it with other components. + +Package: xulrunner-1.9-dev +Section: devel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, xulrunner-1.9 (>= ${source:Upstream-Version}), libnspr4-dev, libnss3-dev +Conflicts: libxul-dev, mozilla-dev +Description: XUL + XPCOM development files + This package contains the development headers, idl files and static libraries + needed to develop applications using Mozilla XUL Engine + +Package: xulrunner-dev +Section: devel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, xulrunner-1.9-dev (>= ${source:Upstream-Version}) +Description: Debian compatibility package for XUL + XPCOM development files + This (empty) package exists merely to ease the life on sync's and merges in + ubuntu by providing the package name used by debian. + +Package: xulrunner-1.9-gnome-support +Section: devel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, xulrunner-1.9 (= ${binary:Version}) +Description: Support for Gnome in xulrunner-1.9 applications + This is an extension to xulrunner-1.9 that allows XUL applications to use + protocol handlers from Gnome-VFS, such as smb or sftp, and other Gnome + integration features. + +Package: xulrunner-1.9-dom-inspector +Architecture: all +Depends: xulrunner-1.9 +Conflicts: firefox-3.0-dom-inspector (<< 3.0~alpha8-0) +Replaces: firefox-3.0-dom-inspector +Description: tool for inspecting the DOM of pages in Mozilla Firefox + This is a tool that allows you to inspect the DOM for web pages in + Firefox. This is of great use to people who are doing Mozilla chrome + development or web page development. + . + This extension is provided by XULRunner for use by any XUL application. + +Package: xulrunner-1.9-venkman +Architecture: all +Depends: xulrunner-1.9 +Conflicts: firefox-3.0-venkman (<< 3.0~alpha8-0) +Replaces: firefox-3.0-venkman +Description: Venkman is Mozilla-based JavaScript debugger + Venkman is both a graphic and a console JavaScript debugger for Firefox + and Mozilla-based products. Features such as breakpoint management, call stack + inspection, and variable/object inspection are available from the user + interface and from console commands, letting you work in the way you are most + accustomed to. The interactive console also allows for execution of arbitrary + JavaScript code. + Venkman's keyboard shortcuts are the same as leading visual debugging + environments, and gdb users should be familiar with Venkman's /break, /step, + /next, /finish, /frame, and /where commands. + . + This extension is provided by XULRunner for use by any XUL application. --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/docs +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/docs @@ -0,0 +1 @@ +debian/MPL --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/xulrunner-1.9-gnome-support.install +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/xulrunner-1.9-gnome-support.install @@ -0,0 +1,2 @@ +debian/tmp/usr/lib/xulrunner-1.9*/components/libmozgnome.so +debian/tmp/usr/lib/xulrunner-1.9*/components/libnkgnomevfs.so --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/rules +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/rules @@ -0,0 +1,194 @@ +#!/usr/bin/make -f + +MOZ_CVS_ROOT := :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) + +DEB_MOZ_APPLICATION := $(shell dpkg-parsechangelog | sed -n 's/^Source: *\(.*\)$$/\1/ p') +DEB_MOZ_VERSION := $(shell echo $(DEB_MOZ_APPLICATION) | sed -e 's/.*-//') + +DEBIAN_VERSION := $(shell dpkg-parsechangelog | sed -n 's/^Version: *\(.*\)$$/\1/ p') +DEBIAN_REV_CODE := $(shell echo $(DEBIAN_VERSION) | sed 's/^.*-\([0-9]*\)[^-]*$$/0\1/ ; s/^.*\(..\)$$/\1/') +DEBIAN_XUL_VER = $(shell tail -1 mozilla/config/milestone.txt) +DEBIAN_XUL_DIR = /usr/lib/xulrunner-$(DEBIAN_XUL_VER) +DEB_SRCDIR := mozilla + +# minVersion and maxVersion used in install.rdf +EM_TRANSLATION_VERSION = $(DEBIAN_XUL_VER) +EM_TRANSLATION_MIN_VERSION = 1.9 +EM_TRANSLATION_MAX_VERSION = 1.9.0.* + +EXTRA_SYSTEM_CONFIGURE_FLAGS = $(NULL) + +USE_SYSTEM_CAIRO := $(shell pkg-config --exists 'cairo >= 1.5.8'; a=$$?; if test $$a != 1; then echo 1; fi) +# for old cairo versions we cannot use system cairo +ifeq (1,$(USE_SYSTEM_CAIRO)) + EXTRA_SYSTEM_CONFIGURE_FLAGS += --enable-system-cairo +else + EXTRA_SYSTEM_CONFIGURE_FLAGS += --disable-system-cairo +endif + +USE_SYSTEM_SQLITE := $(shell pkg-config --exists 'sqlite3 >= 3.5'; a=$$?; if test $$a != 1; then echo 1; fi) +ifeq (1,$(USE_SYSTEM_SQLITE)) + EXTRA_SYSTEM_CONFIGURE_FLAGS += --enable-system-sqlite +else + EXTRA_SYSTEM_CONFIGURE_FLAGS += --disable-system-sqlite +endif + +# gutsy doesn't have the right system-nss/nspr +USE_SYSTEM_NSPR := $(shell pkg-config --exists 'nspr >= 4.7.3'; a=$$?; if test $$a != 1; then echo 1; fi) +ifeq (1,$(USE_SYSTEM_NSPR)) + EXTRA_SYSTEM_CONFIGURE_FLAGS += --with-system-nspr +endif + +USE_SYSTEM_NSS := $(shell pkg-config --exists 'nss >= 3.12'; a=$$?; if test $$a != 1; then echo 1; fi) +ifeq (1,$(USE_SYSTEM_NSS)) + EXTRA_SYSTEM_CONFIGURE_FLAGS += --with-system-nss +endif + +# translation flags + +MOZ_TRANSLATION_AUTO_XPI_OUTDIR := debian/lp-export-xpis/ +MOZ_TRANSLATION_AUTO_XPI_SEARCHDIRS := debian/$(DEB_MOZ_APPLICATION) +MOZ_TRANSLATION_AUTO_XPI_LOCALE := en-US + +# enable below to disable symbolic-functions linkage +# LDFLAGS=$(shell echo $$LDFLAGS | sed -e 's/-Wl,-Bsymbolic-functions//') +# export LDFLAGS + +DEB_AUTO_UPDATE_AUTOCONF=2.13 + +# workaround cdbs wrongly unapplying patches before cleaning up +clean:: + [ ! -f $(DEB_SRCDIR)/Makefile ] || $(MAKE) -C $(DEB_SRCDIR) distclean + +ifneq (,$(wildcard *.tar.bz2)$(DEBIAN_MOZCLIENT_EMBEDDED)) + DEB_TAR_SRCDIR := mozilla + MOZCLIENT_EMBEDDED = 1 + DEBIAN_XUL_VER = $(shell tail -1 build-tree/mozilla/config/milestone.txt) + include /usr/share/cdbs/1/rules/tarball.mk +endif +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/patchsys-quilt.mk +include /usr/share/cdbs/1/class/autotools.mk +include /usr/share/mozilla-devscripts/$(DEB_MOZ_APPLICATION).mk +include /usr/share/mozilla-devscripts/lp-locale-export.mk + +DEB_MAKE_CLEAN_TARGET = $(NULL) +# We don't want build-tree/mozilla/README to be shipped as a doc +DEB_INSTALL_DOCS_ALL := $(NULL) +MOZ_APPLICATION = xulrunner + +# List all extensions we want +DEB_MOZ_EXTENSIONS=xml-rpc,venkman,inspector,gnomevfs,cview,tasks,reporter,python/xpcom + +CFLAGS = -g +CXXFLAGS = -g + +DEB_CONFIGURE_USER_FLAGS= \ + $(EXTRA_SYSTEM_CONFIGURE_FLAGS) \ + --enable-application=$(MOZ_APPLICATION) \ + --enable-extensions=$(DEB_MOZ_EXTENSIONS) \ + --enable-webservices \ + --enable-safe-browsing \ + --with-default-mozilla-five-home=$(DEBIAN_XUL_DIR) \ + --enable-startup-notification \ + --with-user-appdir=.mozilla \ + --without-system-jpeg \ + --with-system-zlib=/usr \ + --with-system-bz2=/usr \ + --enable-system-hunspell \ + --disable-javaxpcom \ + --disable-crashreporter \ + --disable-elf-dynstr-gc \ + --disable-installer \ + --disable-strip \ + --disable-strip-libs \ + --disable-install-strip \ + --disable-tests \ + --disable-mochitest \ + --disable-updater \ + --enable-optimize \ + --with-distribution-id=com.ubuntu \ + $(NULL) + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + DEB_CONFIGURE_USER_FLAGS += \ + --disable-optimize \ + $(NULL) +endif + +NOT_EXECUTABLE = \ + *.xml \ + *.js \ + *.png \ + *.xpm \ + *.h \ + *.idl \ + *.txt \ + LICENSE \ + $(NULL) + +ifeq (1,$(USE_SYSTEM_NSS)) +binary-install/$(DEB_MOZ_APPLICATION):: + dh_link usr/lib/nss/libnssckbi.so $(DEBIAN_XUL_DIR)/libnssckbi.so +endif + +binary-install/$(DEB_MOZ_APPLICATION):: + touch debian/xulrunner-$(DEB_MOZ_VERSION)/$(DEBIAN_XUL_DIR)/.autoreg + dh_link usr/lib/xulrunner-addons/extensions $(DEBIAN_XUL_DIR)/extensions + dh_link usr/lib/xulrunner-addons/plugins $(DEBIAN_XUL_DIR)/plugins + dh_link $(DEBIAN_XUL_DIR)/xulrunner /usr/bin/$(DEB_MOZ_APPLICATION) + dh_link $(DEBIAN_XUL_DIR)/xpcshell /usr/bin/xpcshell-$(DEB_MOZ_VERSION) +ifneq (1,$(USE_SYSTEM_SQLITE)) + dh_link $(DEBIAN_XUL_DIR)/libsqlite3.so $(DEBIAN_XUL_DIR)/libsqlite3.so.0 +endif + dh_install debian/system-greprefs.js /etc/xulrunner-$(DEB_MOZ_VERSION)/ + dh_link /etc/xulrunner-$(DEB_MOZ_VERSION)/system-greprefs.js $(DEBIAN_XUL_DIR)/greprefs/system-greprefs.js + +LOCALE_VERSION = $(shell echo $(DEBIAN_VERSION) | sed -e 's/~cvs.*/pre/' | tr -d '~') + +binary-post-install/$(DEB_MOZ_APPLICATION):: auto-locale-xpi.mk/translate fix-permissions compare + dh_install -p$(DEB_MOZ_APPLICATION)-dev debian/build-system.tar.gz /usr/lib/xulrunner-devel-$(DEBIAN_XUL_VER)/sdk/ + sed \ + -e 's/@EM_VERSION@/$(EM_TRANSLATION_VERSION)/' \ + -e 's/@EM_TOOLKIT_MIN_VERSION@/$(EM_TRANSLATION_MIN_VERSION)/' \ + -e 's/@EM_TOOLKIT_MAX_VERSION@/$(EM_TRANSLATION_MAX_VERSION)/' \ + < debian/translation-support/install.rdf.in > debian/install.rdf + cd debian && zip lp-export-xpis/en-US.xpi install.rdf +ifeq (,$(findstring $(EM_TRANSLATION_VERSION), $(LOCALE_VERSION))) + $(error EM_TRANSLATION_VERSION=$(EM_TRANSLATION_VERSION) LOCALE_VERSION=$(LOCALE_VERSION). You need to explicitly adjust the translation version and min/max bounds.) +endif + +FIND_EXP = $(foreach ext,$(NOT_EXECUTABLE),-name '$(ext)' -o) +FIND_NOT_EXECUTABLE = $(wordlist 1, $(shell expr $(words $(FIND_EXP)) - 1), $(FIND_EXP)) + +subst_files = \ + debian/$(DEB_MOZ_APPLICATION).preinst \ + debian/$(DEB_MOZ_APPLICATION).postinst \ + debian/$(DEB_MOZ_APPLICATION).prerm \ + debian/$(DEB_MOZ_APPLICATION).postrm \ + $(NULL) + +post-patches:: $(subst_files) + # Create a build-system for xulrunner applications + sh debian/create-build-system.sh + +fix-permissions: + # Fix permissions + cd debian/tmp ; \ + find . -type f \( $(FIND_NOT_EXECUTABLE) \) -perm -u=x -exec chmod -c 644 {} \; + +%: %.in + sed -e 's,@XULDIR@,$(DEBIAN_XUL_DIR),g' \ + -e 's,@XULVER@,$(DEBIAN_XUL_VER),g' \ + -e 's,@XULBRANCH@,$(DEB_MOZ_VERSION),g' \ + < $< > $@ + +clean:: + rm -f $(subst_files) debian/install.rdf + rm -f debian/build-system.tar.gz --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_sysplugin_support_xre_part.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_sysplugin_support_xre_part.patch @@ -0,0 +1,127 @@ +--- + toolkit/xre/nsXREDirProvider.cpp | 27 +++++++++++++++++++++++++++ + toolkit/xre/nsXREDirProvider.h | 1 + + 2 files changed, 28 insertions(+) + +Index: mozilla/toolkit/xre/nsXREDirProvider.cpp +=================================================================== +--- mozilla.orig/toolkit/xre/nsXREDirProvider.cpp ++++ mozilla/toolkit/xre/nsXREDirProvider.cpp +@@ -41,17 +41,19 @@ + + #include "nsAppRunner.h" + #include "nsXREDirProvider.h" + + #include "jsapi.h" + + #include "nsIJSContextStack.h" + #include "nsIDirectoryEnumerator.h" ++#include "nsIFile.h" + #include "nsILocalFile.h" ++#include "nsIProperties.h" + #include "nsIObserverService.h" + #include "nsIProfileChangeStatus.h" + #include "nsISimpleEnumerator.h" + #include "nsIToolkitChromeRegistry.h" + + #include "nsAppDirectoryServiceDefs.h" + #include "nsDirectoryServiceDefs.h" + #include "nsDirectoryServiceUtils.h" +@@ -96,16 +98,18 @@ + #else + #define APP_REGISTRY_NAME "appreg" + #endif + + #define PREF_OVERRIDE_DIRNAME "preferences" + + nsXREDirProvider* gDirServiceProvider = nsnull; + ++#define NS_SYSTEM_PLUGINS_DIR "SysPlugins" ++ + nsXREDirProvider::nsXREDirProvider() : + mProfileNotified(PR_FALSE), + mExtensionsLoaded(PR_FALSE) + { + gDirServiceProvider = this; + } + + nsXREDirProvider::~nsXREDirProvider() +@@ -119,16 +123,34 @@ + nsIDirectoryServiceProvider* aAppProvider) + { + NS_ENSURE_ARG(aGREDir); + + mAppProvider = aAppProvider; + mXULAppDir = aXULAppDir; + mGREDir = aGREDir; + ++ nsresult rv; ++ nsCOMPtr directoryService = ++ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); ++ ++ ++ if (NS_FAILED(rv)) { ++ mSysPluginDir = nsnull; ++ return NS_OK; ++ } ++ ++ rv = directoryService->Get( NS_SYSTEM_PLUGINS_DIR, ++ NS_GET_IID(nsIFile), ++ getter_AddRefs(mSysPluginDir)); ++ ++ if (NS_FAILED(rv)) { ++ mSysPluginDir = nsnull; ++ } ++ + return NS_OK; + } + + nsresult + nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir) + { + NS_ASSERTION(aDir && aLocalDir, "We don't support no-profile apps yet!"); + +@@ -753,16 +775,21 @@ + } + else if (!strcmp(aProperty, NS_APP_PLUGINS_DIR_LIST)) { + static const char *const kAppendPlugins[] = { "plugins", nsnull }; + nsCOMArray directories; + + // The root dirserviceprovider does quite a bit for us: we're mainly + // interested in gre, xulapp, and extension-provided plugins. + LoadBundleDirectories(); ++ ++ PRBool exists; ++ if (mSysPluginDir && NS_SUCCEEDED(mSysPluginDir->Exists(&exists)) && exists) ++ directories.AppendObject(mSysPluginDir); ++ + LoadAppDirIntoArray(mGREDir, + kAppendPlugins, + directories); + LoadDirsIntoArray(mAppBundleDirectories, + kAppendPlugins, + directories); + LoadDirsIntoArray(mExtensionDirectories, + kAppendPlugins, +Index: mozilla/toolkit/xre/nsXREDirProvider.h +=================================================================== +--- mozilla.orig/toolkit/xre/nsXREDirProvider.h ++++ mozilla/toolkit/xre/nsXREDirProvider.h +@@ -138,16 +138,17 @@ + // extensions, and themes + void LoadBundleDirectories(); + void LoadAppBundleDirs(); + + void Append(nsIFile* aDirectory); + + nsCOMPtr mAppProvider; + nsCOMPtr mGREDir; ++ nsCOMPtr mSysPluginDir; + nsCOMPtr mXULAppDir; + nsCOMPtr mProfileDir; + nsCOMPtr mProfileLocalDir; + PRPackedBool mProfileNotified; + PRPackedBool mExtensionsLoaded; + nsCOMArray mAppBundleDirectories; + nsCOMArray mExtensionDirectories; + nsCOMArray mThemeDirectories; --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX-dont-reset-user-prefs-on-upgrade.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX-dont-reset-user-prefs-on-upgrade.patch @@ -0,0 +1,102 @@ + +This bug is due to the fact, applications are restarted before extension +defaults are loaded. + +To reproduce, choose any preference and set the values like: +system default: + pref("prefkey",systemvalue); +extension default: + pref("prefkey", extensiondefault); +user pref: + user_pref("prefkey", systemvalue); + +Next, trigger application behaviour similar to upgrade by removing compreg.dat +from profile and start the application. + +Result: +User sees extensiondefault after upgrade, because the user_pref has been +eliminated ... which is definitly not what the user expects because he explicitly +had *systemvalue* set before the upgrade. + +Evaluation: +The bug happens because restart is performed *before* extension defaults have been +loaded and the prefapi.cpp always eliminate user preference if the user preference +is equal to the actual default (which happens to be extensiondefault normally - so +no reset, but is systemvalue during restart). + +Fix: +1. savePrefs should not try to be smart ... this patch removes the heuristic that guesses +whether a setting can be eliminated or not; it should be sufficient to only eliminate +prefs in hashPrefs. + +2. This patch prevents hashPrefs from eliminating the user pref in case we are in +*startup* ... unfortunately no such state info exists, which lets us guess that +we are in startup for the previously not dealt case: !set_default && +!pref_ValueChanged(pref->defaultPref, value, type) && !PREF_HAS_USER_VALUE(pref). + +If is the case we explicitly remember that this setting is a user-pref ... +even though it might be temporarily equal to the default pref. + +--- + modules/libpref/src/prefapi.cpp | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +Index: mozilla/modules/libpref/src/prefapi.cpp +=================================================================== +--- mozilla.orig/modules/libpref/src/prefapi.cpp 2006-07-14 02:58:20.000000000 +0200 ++++ mozilla/modules/libpref/src/prefapi.cpp 2007-07-20 13:07:53.000000000 +0200 +@@ -319,23 +319,20 @@ + if (!pref) + return PL_DHASH_NEXT; + + nsCAutoString prefValue; + + // where we're getting our pref from + PrefValue* sourcePref; + +- if (PREF_HAS_USER_VALUE(pref) && +- pref_ValueChanged(pref->defaultPref, +- pref->userPref, +- (PrefType) PREF_TYPE(pref))) +- sourcePref = &pref->userPref; +- else if (PREF_IS_LOCKED(pref)) ++ if (PREF_IS_LOCKED(pref)) + sourcePref = &pref->defaultPref; ++ else if (PREF_HAS_USER_VALUE(pref)) ++ sourcePref = &pref->userPref; + else + // do not save default prefs that haven't changed + return PL_DHASH_NEXT; + + #if MOZ_PROFILESHARING + if ((argData->saveTypes == SAVE_SHARED && + !gSharedPrefHandler->IsPrefShared(pref->key)) || + (argData->saveTypes == SAVE_NONSHARED && +@@ -732,16 +729,27 @@ + Otherwise, set the user value only if it has changed */ + if ( !pref_ValueChanged(pref->defaultPref, value, type) ) + { + if (PREF_HAS_USER_VALUE(pref)) + { + pref->flags &= ~PREF_USERSET; + if (!PREF_IS_LOCKED(pref)) + valueChanged = PR_TRUE; ++ } else { ++ // this is tricky: we have !set_default ... ++ // thus we are setting a user pref; however the user ++ // pref set is same as *current default*; this normally ++ // means to un-set ... however since we have ++ // !PREF_HAS_USER_VALUE(pref) this can only be during ++ // startup ++ pref_SetValue(&pref->userPref, value, type); ++ pref->flags |= PREF_USERSET; ++ if (!PREF_IS_LOCKED(pref)) ++ valueChanged = PR_TRUE; + } + } + else if ( !PREF_HAS_USER_VALUE(pref) || + pref_ValueChanged(pref->userPref, value, type) ) + { + pref_SetValue(&pref->userPref, value, type); + pref->flags |= PREF_USERSET; + if (!PREF_IS_LOCKED(pref)) --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch @@ -0,0 +1,137 @@ +Index: embedding/browser/gtk/src/EmbedWindow.cpp +=================================================================== +RCS file: /cvsroot/mozilla/embedding/browser/gtk/src/EmbedWindow.cpp,v +retrieving revision 1.43 +diff -u -p -8 -r1.43 EmbedWindow.cpp +--- a/embedding/browser/gtk/src/EmbedWindow.cpp 11 Jan 2008 22:16:15 -0000 1.43 ++++ b/embedding/browser/gtk/src/EmbedWindow.cpp 16 Jan 2008 00:08:24 -0000 +@@ -379,72 +379,95 @@ tooltips_paint_window(GtkWidget *window) + + return FALSE; + } + + NS_IMETHODIMP + EmbedWindow::OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, + const PRUnichar *aTipText) + { +- nsAutoString tipText ( aTipText ); +- +- const char* tipString = ToNewUTF8String(tipText); ++ NS_ENSURE_STATE(mOwner && mOwner->mOwningWidget && ++ GTK_WIDGET_REALIZED(mOwner->mOwningWidget)); + + if (sTipWindow) + gtk_widget_destroy(sTipWindow); + +- // get the root origin for this content window +- nsCOMPtr mainWidget; +- mBaseWindow->GetMainWidget(getter_AddRefs(mainWidget)); +- GdkWindow *window; +- window = static_cast(mainWidget->GetNativeData(NS_NATIVE_WINDOW)); +- gint root_x, root_y; +- gdk_window_get_origin(window, &root_x, &root_y); +- +- // XXX work around until I can get pink to figure out why +- // tooltips vanish if they show up right at the origin of the +- // cursor. +- root_y += 10; + + sTipWindow = gtk_window_new(GTK_WINDOW_POPUP); ++ GtkWindow *tipWinAsWindow = GTK_WINDOW(sTipWindow); ++ + gtk_widget_set_app_paintable(sTipWindow, TRUE); +- gtk_window_set_resizable(GTK_WINDOW(sTipWindow), TRUE); ++ gtk_window_set_resizable(tipWinAsWindow, FALSE); + // needed to get colors + fonts etc correctly + gtk_widget_set_name(sTipWindow, "gtk-tooltips"); ++ gtk_container_set_border_width(GTK_CONTAINER(sTipWindow), 4); + + // set up the popup window as a transient of the widget. +- GtkWidget *toplevel_window; +- toplevel_window = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); +- if (!GTK_WINDOW(toplevel_window)) { ++ GtkWidget *widget = (GtkWidget *) mOwner->mOwningWidget; ++ GtkWidget *toplevel = gtk_widget_get_toplevel(widget); ++ if (!GTK_IS_WINDOW(toplevel) || !GTK_WIDGET_TOPLEVEL(toplevel)) { + NS_ERROR("no gtk window in hierarchy!\n"); + return NS_ERROR_FAILURE; + } +- gtk_window_set_transient_for(GTK_WINDOW(sTipWindow), +- GTK_WINDOW(toplevel_window)); ++ gtk_window_set_transient_for(tipWinAsWindow, GTK_WINDOW(toplevel)); + +- // realize the widget +- gtk_widget_realize(sTipWindow); +- +- g_signal_connect(G_OBJECT(sTipWindow), "expose_event", +- G_CALLBACK(tooltips_paint_window), NULL); ++ g_signal_connect (sTipWindow, "expose-event", ++ G_CALLBACK(tooltips_paint_window), NULL); + + // set up the label for the tooltip +- GtkWidget *label = gtk_label_new(tipString); ++ GtkWidget *label = gtk_label_new(NS_ConvertUTF16toUTF8(aTipText).get()); + // wrap automatically + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); ++ gtk_misc_set_alignment (GTK_MISC(label), 0.5, 0.5); + gtk_container_add(GTK_CONTAINER(sTipWindow), label); +- gtk_container_set_border_width(GTK_CONTAINER(sTipWindow), 4); +- // set the coords for the widget +- gtk_widget_set_uposition(sTipWindow, aXCoords + root_x, +- aYCoords + root_y); ++ gtk_widget_show(label); ++ ++ GdkScreen *screen = gtk_widget_get_screen(widget); ++ gtk_window_set_screen (tipWinAsWindow, screen); ++ ++ gint monitor_num = gdk_screen_get_monitor_at_window(screen, widget->window); ++ if (monitor_num < 0) ++ monitor_num = 0; ++ ++ GdkRectangle monitor; ++ gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor); ++ ++ gtk_widget_ensure_style(sTipWindow); ++ ++ GtkRequisition req; ++ gtk_widget_size_request(sTipWindow, &req); ++ ++ gint x, y; ++ gdk_window_get_origin(widget->window, &x, &y); ++ ++ x += aXCoords; ++ y += aYCoords; ++ ++ // Ideally we'd query the cursor size and hotspot, ++ // but there appears to be no way to do that */ ++ int xoffset = 8, yoffset = 8; ++ ++ if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) { ++ x -= req.width + xoffset; ++ } else { ++ x += xoffset; ++ } + +- // and show it. +- gtk_widget_show_all(sTipWindow); ++ if (x + req.width > monitor.x + monitor.width) ++ x = monitor.x + monitor.width - req.width; ++ else if (x < monitor.x) ++ x = monitor.x; ++ ++ if (y + req.height + yoffset <= monitor.y + monitor.height) ++ y += yoffset; ++ else ++ y -= req.height + yoffset; + +- nsMemory::Free( (void*)tipString ); ++ gtk_window_move(tipWinAsWindow, x, y); ++ gtk_widget_show(sTipWindow); + + return NS_OK; + } + + NS_IMETHODIMP + EmbedWindow::OnHideTooltip(void) + { + if (sTipWindow) --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_pc_honour_system_nspr_nss.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_pc_honour_system_nspr_nss.patch @@ -0,0 +1,114 @@ +--- + xulrunner/installer/Makefile.in | 17 ++++++++++++++--- + xulrunner/installer/libxul-embedding-unstable.pc.in | 2 +- + xulrunner/installer/libxul-embedding.pc.in | 2 +- + xulrunner/installer/mozilla-nss.pc.in | 6 +++--- + 4 files changed, 19 insertions(+), 8 deletions(-) + +Index: mozilla/xulrunner/installer/Makefile.in +=================================================================== +--- mozilla.orig/xulrunner/installer/Makefile.in ++++ mozilla/xulrunner/installer/Makefile.in +@@ -90,40 +90,51 @@ + mozilla-plugin.pc \ + mozilla-gtkmozembed.pc \ + mozilla-gtkmozembed-embedding.pc \ + $(NULL) + + ifdef MOZ_NATIVE_NSPR + NSPR_NAME=nspr + NSPR_VERSION=$(shell $(NSPR_CONFIG) --version) ++FULL_NSPR_CFLAGS=$(shell $(NSPR_CONFIG) --cflags) ++FULL_NSPR_LIBS=$(shell $(NSPR_CONFIG) --libs) + else +-pkg_config_files += mozilla-nspr.pc + NSPR_NAME=mozilla-nspr + FULL_NSPR_CFLAGS=-I\$${includedir}/stable + FULL_NSPR_LIBS=$(subst $(prefix),\$${sdkdir},$(shell $(DEPTH)/nsprpub/config/nspr-config --libs)) + NSPR_VERSION=$(shell $(DEPTH)/nsprpub/config/nspr-config --version) + endif ++pkg_config_files += mozilla-nspr.pc + + $(warning FULL_NSPR_CFLAGS=$(FULL_NSPR_CFLAGS)) + +-ifndef MOZ_NATIVE_NSS +-pkg_config_files += mozilla-nss.pc ++ifdef MOZ_NATIVE_NSS ++NSPR_VERSION=$(shell $(NSS_CONFIG) --version) ++FULL_NSS_CFLAGS=$(shell $(NSS_CONFIG) --cflags) ++FULL_NSS_LIBS=$(shell $(NSS_CONFIG) --libs) ++else ++NSS_VERSION=$(shell $(DEPTH)/nsprpub/config/nss-config --version) ++FULL_NSS_CFLAGS=-I\$${includedir}/stable ++FULL_NSS_LIBS=$(subst $(prefix),\$${sdkdir},$(shell $(DEPTH)/nsprpub/config/nss-config --libs)) + endif ++pkg_config_files += mozilla-nss.pc + + %.pc: $(srcdir)/%.pc.in Makefile.in Makefile $(DEPTH)/config/autoconf.mk + cat $< | sed \ + -e "s|%prefix%|$(prefix)|" \ + -e "s|%includedir%|$(includedir)|" \ + -e "s|%idldir%|$(idldir)|" \ + -e "s|%sdkdir%|$(sdkdir)|" \ + -e "s|%MOZ_APP_NAME%|$(MOZ_APP_NAME)|" \ + -e "s|%MOZILLA_VERSION%|$(MOZ_APP_VERSION)|" \ + -e "s|%FULL_NSPR_LIBS%|$(FULL_NSPR_LIBS)|" \ + -e "s|%FULL_NSPR_CFLAGS%|$(FULL_NSPR_CFLAGS)|" \ ++ -e "s|%FULL_NSS_LIBS%|$(FULL_NSS_LIBS)|" \ ++ -e "s|%FULL_NSS_CFLAGS%|$(FULL_NSS_CFLAGS)|" \ + -e "s|%NSPR_NAME%|$(NSPR_NAME)|" \ + -e "s|%NSPR_VERSION%|$(NSPR_VERSION)|" > $@ + chmod 644 $@ + + install:: $(pkg_config_files) + @echo pkg_config_file: $(pkg_config_files) + $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(libdir)/pkgconfig + +Index: mozilla/xulrunner/installer/libxul-embedding-unstable.pc.in +=================================================================== +--- mozilla.orig/xulrunner/installer/libxul-embedding-unstable.pc.in ++++ mozilla/xulrunner/installer/libxul-embedding-unstable.pc.in +@@ -3,9 +3,9 @@ + includedir=%includedir% + idldir=%idldir% + includetype=unstable + + Name: libxul-embedding-unstable + Description: Static library for version-independent embedding of the Mozilla runtime (unstable API) + Version: %MOZILLA_VERSION% + Libs: -L${sdkdir}/lib -lxpcomglue +-Cflags: -DXPCOM_GLUE -I${includedir}/${includetype} -fshort-wchar ++Cflags: -DXPCOM_GLUE -I${includedir}/${includetype} -fshort-wchar %FULL_NSPR_CFLAGS% +Index: mozilla/xulrunner/installer/libxul-embedding.pc.in +=================================================================== +--- mozilla.orig/xulrunner/installer/libxul-embedding.pc.in ++++ mozilla/xulrunner/installer/libxul-embedding.pc.in +@@ -7,9 +7,9 @@ + # Note: the default pkg-config cflags will only list include directories + # that contain stable (frozen or safe for linking) header files. To include + # nonfrozen headers, run pkg-config with --define-variable=includetype=unstable + + Name: libxul-embedding + Description: Static library for version-independent embedding of the Mozilla runtime + Version: %MOZILLA_VERSION% + Libs: -L${sdkdir}/lib -lxpcomglue +-Cflags: -DXPCOM_GLUE -I${includedir}/${includetype} -fshort-wchar ++Cflags: -DXPCOM_GLUE -I${includedir}/${includetype} -fshort-wchar %FULL_NSPR_CFLAGS% +Index: mozilla/xulrunner/installer/mozilla-nss.pc.in +=================================================================== +--- mozilla.orig/xulrunner/installer/mozilla-nss.pc.in ++++ mozilla/xulrunner/installer/mozilla-nss.pc.in +@@ -1,10 +1,10 @@ + prefix=%prefix% + sdkdir=%sdkdir% + includedir=%includedir% + + Name: NSS + Description: Mozilla Network Security Services +-Version: %MOZILLA_VERSION% ++Version: %NSS_VERSION% + Requires: %NSPR_NAME% >= %NSPR_VERSION% +-Libs: -L${sdkdir}/lib -lnss3 -lnssutil3 -lsmime3 -lssl3 -lsoftokn3 +-Cflags: -I${includedir}/stable ++Libs: %FULL_NSS_LIBS% ++Cflags: %FULL_NSS_CFLAGS% --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz429747_att317495+move_hunspell_1.2.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz429747_att317495+move_hunspell_1.2.patch @@ -0,0 +1,35178 @@ +--- + extensions/spellcheck/hunspell/Makefile.in | 8 + extensions/spellcheck/hunspell/hunspell/Makefile.in | 66 + extensions/spellcheck/hunspell/hunspell/README.hunspell | 59 + extensions/spellcheck/hunspell/hunspell/affentry.cpp | 924 ++ + extensions/spellcheck/hunspell/hunspell/affentry.hxx | 187 + extensions/spellcheck/hunspell/hunspell/affixmgr.cpp | 4155 ++++++++++++ + extensions/spellcheck/hunspell/hunspell/affixmgr.hxx | 272 + extensions/spellcheck/hunspell/hunspell/atypes.hxx | 154 + extensions/spellcheck/hunspell/hunspell/baseaffix.hxx | 87 + extensions/spellcheck/hunspell/hunspell/csutil.cpp | 5400 ++++++++++++++++ + extensions/spellcheck/hunspell/hunspell/csutil.hxx | 233 + extensions/spellcheck/hunspell/hunspell/hashmgr.cpp | 941 ++ + extensions/spellcheck/hunspell/hunspell/hashmgr.hxx | 129 + extensions/spellcheck/hunspell/hunspell/htypes.hxx | 85 + extensions/spellcheck/hunspell/hunspell/hunspell.cpp | 1807 +++++ + extensions/spellcheck/hunspell/hunspell/hunspell.h | 89 + extensions/spellcheck/hunspell/hunspell/hunspell.hxx | 195 + extensions/spellcheck/hunspell/hunspell/langnum.hxx | 94 + extensions/spellcheck/hunspell/hunspell/phonet.cpp | 310 + extensions/spellcheck/hunspell/hunspell/phonet.hxx | 66 + extensions/spellcheck/hunspell/hunspell/suggestmgr.cpp | 2036 ++++++ + extensions/spellcheck/hunspell/hunspell/suggestmgr.hxx | 160 + extensions/spellcheck/hunspell/src/Makefile.in | 13 + extensions/spellcheck/hunspell/src/README.hunspell | 59 + extensions/spellcheck/hunspell/src/affentry.cpp | 924 -- + extensions/spellcheck/hunspell/src/affentry.hxx | 187 + extensions/spellcheck/hunspell/src/affixmgr.cpp | 4155 ------------ + extensions/spellcheck/hunspell/src/affixmgr.hxx | 272 + extensions/spellcheck/hunspell/src/atypes.hxx | 154 + extensions/spellcheck/hunspell/src/baseaffix.hxx | 87 + extensions/spellcheck/hunspell/src/csutil.cpp | 5400 ---------------- + extensions/spellcheck/hunspell/src/csutil.hxx | 233 + extensions/spellcheck/hunspell/src/hashmgr.cpp | 941 -- + extensions/spellcheck/hunspell/src/hashmgr.hxx | 129 + extensions/spellcheck/hunspell/src/htypes.hxx | 85 + extensions/spellcheck/hunspell/src/hunspell.cpp | 1807 ----- + extensions/spellcheck/hunspell/src/hunspell.h | 89 + extensions/spellcheck/hunspell/src/hunspell.hxx | 195 + extensions/spellcheck/hunspell/src/langnum.hxx | 94 + extensions/spellcheck/hunspell/src/phonet.cpp | 310 + extensions/spellcheck/hunspell/src/phonet.hxx | 66 + extensions/spellcheck/hunspell/src/suggestmgr.cpp | 2036 ------ + extensions/spellcheck/hunspell/src/suggestmgr.hxx | 160 + extensions/spellcheck/src/Makefile.in | 6 + 44 files changed, 17464 insertions(+), 17395 deletions(-) + +Index: mozilla/extensions/spellcheck/hunspell/Makefile.in +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/Makefile.in ++++ mozilla/extensions/spellcheck/hunspell/Makefile.in +@@ -36,12 +36,18 @@ + DEPTH = ../../.. + topsrcdir = @top_srcdir@ + srcdir = @srcdir@ + VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + + MODULE = hunspell +-DIRS = src ++ ++ifndef MOZ_NATIVE_HUNSPELL ++DIRS += hunspell ++endif ++ ++DIRS += src ++ + + include $(topsrcdir)/config/rules.mk + +Index: mozilla/extensions/spellcheck/hunspell/hunspell/README.hunspell +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/README.hunspell +@@ -0,0 +1,59 @@ ++******* BEGIN LICENSE BLOCK ******* ++* Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++* ++* The contents of this file are subject to the Mozilla Public License Version ++* 1.1 (the "License"); you may not use this file except in compliance with ++* the License. You may obtain a copy of the License at ++* http://www.mozilla.org/MPL/ ++* ++* Software distributed under the License is distributed on an "AS IS" basis, ++* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++* for the specific language governing rights and limitations under the ++* License. ++* ++* The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++* and László Németh (Hunspell). Portions created by the Initial Developers ++* are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++* ++* Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++* David Einstein (deinst@world.std.com) ++* László Németh (nemethl@gyorsposta.hu) ++* Ryan VanderMeulen (ryanvm@gmail.com) ++* ++* Alternatively, the contents of this file may be used under the terms of ++* either the GNU General Public License Version 2 or later (the "GPL"), or ++* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++* in which case the provisions of the GPL or the LGPL are applicable instead ++* of those above. If you wish to allow use of your version of this file only ++* under the terms of either the GPL or the LGPL, and not to allow others to ++* use your version of this file under the terms of the MPL, indicate your ++* decision by deleting the provisions above and replace them with the notice ++* and other provisions required by the GPL or the LGPL. If you do not delete ++* the provisions above, a recipient may use your version of this file under ++* the terms of any one of the MPL, the GPL or the LGPL. ++* ++******* END LICENSE BLOCK ******* ++ ++Hunspell Version: 1.1.12 ++ ++Hunspell Author: László Németh ++MySpell Author: Kevin Hendricks & David Einstein ++ ++Hunspell is a spell checker and morphological analyser library. Hunspell ++is based on OpenOffice.org's Myspell. Documentation, tests, and examples ++are available at http://hunspell.sourceforge.net. ++ ++A special thanks and credit goes to Geoff Kuenning, the creator of Ispell. ++MySpell's affix algorithms were based on those of Ispell, which should be ++noted is copyright Geoff Kuenning et al and now available under a BSD-style ++license. For more information on Ispell and affix compression in general, ++please see: http://lasr.cs.ucla.edu/geoff/ispell.html (Ispell homepage) ++ ++An almost complete rewrite of MySpell for use by the Mozilla project was ++developed by David Einstein. David was a significant help in improving MySpell. ++ ++Special thanks also goes to László Németh, who is the author of the Hungarian ++dictionary and who developed and contributed the code to support compound words ++in MySpell and fixed numerous problems with the encoding case conversion tables ++along with rewriting MySpell as Hunspell and ensuring compatibility with the ++Mozilla codebase. +Index: mozilla/extensions/spellcheck/hunspell/hunspell/affentry.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/affentry.cpp +@@ -0,0 +1,924 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "affentry.hxx" ++#include "csutil.hxx" ++ ++#ifndef MOZILLA_CLIENT ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++ ++PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp) ++{ ++ // register affix manager ++ pmyMgr = pmgr; ++ ++ // set up its intial values ++ ++ aflag = dp->aflag; // flag ++ strip = dp->strip; // string to strip ++ appnd = dp->appnd; // string to append ++ stripl = dp->stripl; // length of strip string ++ appndl = dp->appndl; // length of append string ++ numconds = dp->numconds; // number of conditions to match ++ opts = dp->opts; // cross product flag ++ // then copy over all of the conditions ++ memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0])); ++ next = NULL; ++ nextne = NULL; ++ nexteq = NULL; ++#ifdef HUNSPELL_EXPERIMENTAL ++ morphcode = dp->morphcode; ++#endif ++ contclass = dp->contclass; ++ contclasslen = dp->contclasslen; ++} ++ ++ ++PfxEntry::~PfxEntry() ++{ ++ aflag = 0; ++ if (appnd) free(appnd); ++ if (strip) free(strip); ++ pmyMgr = NULL; ++ appnd = NULL; ++ strip = NULL; ++ if (opts & aeUTF8) { ++ for (int i = 0; i < numconds; i++) { ++ if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]); ++ } ++ } ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (morphcode && !(opts & aeALIASM)) free(morphcode); ++#endif ++ if (contclass && !(opts & aeALIASF)) free(contclass); ++} ++ ++// add prefix to this word assuming conditions hold ++char * PfxEntry::add(const char * word, int len) ++{ ++ char tword[MAXWORDUTF8LEN + 4]; ++ ++ if ((len > stripl) && (len >= numconds) && test_condition(word) && ++ (!stripl || (strncmp(word, strip, stripl) == 0)) && ++ ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) { ++ /* we have a match so add prefix */ ++ char * pp = tword; ++ if (appndl) { ++ strcpy(tword,appnd); ++ pp += appndl; ++ } ++ strcpy(pp, (word + stripl)); ++ return mystrdup(tword); ++ } ++ return NULL; ++} ++ ++ ++inline int PfxEntry::test_condition(const char * st) ++{ ++ int cond; ++ unsigned char * cp = (unsigned char *)st; ++ if (!(opts & aeUTF8)) { // 256-character codepage ++ for (cond = 0; cond < numconds; cond++) { ++ if ((conds.base[*cp++] & (1 << cond)) == 0) return 0; ++ } ++ } else { // UTF-8 encoding ++ unsigned short wc; ++ for (cond = 0; cond < numconds; cond++) { ++ // a simple 7-bit ASCII character in UTF-8 ++ if ((*cp >> 7) == 0) { ++ // also check limit (end of word) ++ if ((!*cp) || ((conds.utf8.ascii[*cp++] & (1 << cond)) == 0)) return 0; ++ // UTF-8 multibyte character ++ } else { ++ // not dot wildcard in rule ++ if (!conds.utf8.all[cond]) { ++ if (conds.utf8.neg[cond]) { ++ u8_u16((w_char *) &wc, 1, (char *) cp); ++ if (conds.utf8.wchars[cond] && ++ flag_bsearch((unsigned short *)conds.utf8.wchars[cond], ++ wc, (short) conds.utf8.wlen[cond])) return 0; ++ } else { ++ if (!conds.utf8.wchars[cond]) return 0; ++ u8_u16((w_char *) &wc, 1, (char *) cp); ++ if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond], ++ wc, (short)conds.utf8.wlen[cond])) return 0; ++ } ++ } ++ // jump to next UTF-8 character ++ for(cp++; (*cp & 0xc0) == 0x80; cp++); ++ } ++ } ++ } ++ return 1; ++} ++ ++ ++// check if this prefix entry matches ++struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ struct hentry * he; // hash entry of root word or NULL ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ ++ // on entry prefix is 0 length or already matches the beginning of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing prefix and adding ++ // back any characters that would have been stripped ++ ++ if (stripl) strcpy (tmpword, strip); ++ strcpy ((tmpword + stripl), (word + appndl)); ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then check if resulting ++ // root word in the dictionary ++ ++ if (test_condition(tmpword)) { ++ tmpl += stripl; ++ if ((he = pmyMgr->lookup(tmpword)) != NULL) { ++ do { ++ if (TESTAFF(he->astr, aflag, he->alen) && ++ // forbid single prefixes with pseudoroot flag ++ ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) && ++ // needflag ++ ((!needflag) || TESTAFF(he->astr, needflag, he->alen) || ++ (contclass && TESTAFF(contclass, needflag, contclasslen)))) ++ return he; ++ he = he->next_homonym; // check homonyms ++ } while (he); ++ } ++ ++ // prefix matched but no root word was found ++ // if aeXPRODUCT is allowed, try again but now ++ // ross checked combined with a suffix ++ ++ //if ((opts & aeXPRODUCT) && in_compound) { ++ if ((opts & aeXPRODUCT)) { ++ he = pmyMgr->suffix_check(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, NULL, ++ 0, NULL, FLAG_NULL, needflag, in_compound); ++ if (he) return he; ++ } ++ } ++ } ++ return NULL; ++} ++ ++// check if this prefix entry matches ++struct hentry * PfxEntry::check_twosfx(const char * word, int len, ++ char in_compound, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ struct hentry * he; // hash entry of root word or NULL ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ ++ // on entry prefix is 0 length or already matches the beginning of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing prefix and adding ++ // back any characters that would have been stripped ++ ++ if (stripl) strcpy (tmpword, strip); ++ strcpy ((tmpword + stripl), (word + appndl)); ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then check if resulting ++ // root word in the dictionary ++ ++ if (test_condition(tmpword)) { ++ tmpl += stripl; ++ ++ // prefix matched but no root word was found ++ // if aeXPRODUCT is allowed, try again but now ++ // cross checked combined with a suffix ++ ++ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { ++ he = pmyMgr->suffix_check_twosfx(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, needflag); ++ if (he) return he; ++ } ++ } ++ } ++ return NULL; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// check if this prefix entry matches ++char * PfxEntry::check_twosfx_morph(const char * word, int len, ++ char in_compound, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ ++ // on entry prefix is 0 length or already matches the beginning of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing prefix and adding ++ // back any characters that would have been stripped ++ ++ if (stripl) strcpy (tmpword, strip); ++ strcpy ((tmpword + stripl), (word + appndl)); ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then check if resulting ++ // root word in the dictionary ++ ++ if (test_condition(tmpword)) { ++ tmpl += stripl; ++ ++ // prefix matched but no root word was found ++ // if aeXPRODUCT is allowed, try again but now ++ // ross checked combined with a suffix ++ ++ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { ++ return pmyMgr->suffix_check_twosfx_morph(tmpword, tmpl, ++ aeXPRODUCT, (AffEntry *)this, needflag); ++ } ++ } ++ } ++ return NULL; ++} ++ ++// check if this prefix entry matches ++char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ struct hentry * he; // hash entry of root word or NULL ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ char result[MAXLNLEN]; ++ char * st; ++ ++ *result = '\0'; ++ ++ // on entry prefix is 0 length or already matches the beginning of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing prefix and adding ++ // back any characters that would have been stripped ++ ++ if (stripl) strcpy (tmpword, strip); ++ strcpy ((tmpword + stripl), (word + appndl)); ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then check if resulting ++ // root word in the dictionary ++ ++ if (test_condition(tmpword)) { ++ tmpl += stripl; ++ if ((he = pmyMgr->lookup(tmpword)) != NULL) { ++ do { ++ if (TESTAFF(he->astr, aflag, he->alen) && ++ // forbid single prefixes with pseudoroot flag ++ ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) && ++ // needflag ++ ((!needflag) || TESTAFF(he->astr, needflag, he->alen) || ++ (contclass && TESTAFF(contclass, needflag, contclasslen)))) { ++ if (morphcode) strcat(result, morphcode); else strcat(result,getKey()); ++ if (he->description) { ++ if ((*(he->description)=='[')||(*(he->description)=='<')) strcat(result,he->word); ++ strcat(result,he->description); ++ } ++ strcat(result, "\n"); ++ } ++ he = he->next_homonym; ++ } while (he); ++ } ++ ++ // prefix matched but no root word was found ++ // if aeXPRODUCT is allowed, try again but now ++ // ross checked combined with a suffix ++ ++ if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { ++ st = pmyMgr->suffix_check_morph(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, ++ FLAG_NULL, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ } ++ } ++ } ++ ++ if (*result) return mystrdup(result); ++ return NULL; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp) ++{ ++ // register affix manager ++ pmyMgr = pmgr; ++ ++ // set up its intial values ++ aflag = dp->aflag; // char flag ++ strip = dp->strip; // string to strip ++ appnd = dp->appnd; // string to append ++ stripl = dp->stripl; // length of strip string ++ appndl = dp->appndl; // length of append string ++ numconds = dp->numconds; // number of conditions to match ++ opts = dp->opts; // cross product flag ++ ++ // then copy over all of the conditions ++ memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0])); ++ ++ rappnd = myrevstrdup(appnd); ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++ morphcode = dp->morphcode; ++#endif ++ contclass = dp->contclass; ++ contclasslen = dp->contclasslen; ++} ++ ++ ++SfxEntry::~SfxEntry() ++{ ++ aflag = 0; ++ if (appnd) free(appnd); ++ if (rappnd) free(rappnd); ++ if (strip) free(strip); ++ pmyMgr = NULL; ++ appnd = NULL; ++ strip = NULL; ++ if (opts & aeUTF8) { ++ for (int i = 0; i < numconds; i++) { ++ if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]); ++ } ++ } ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (morphcode && !(opts & aeALIASM)) free(morphcode); ++#endif ++ if (contclass && !(opts & aeALIASF)) free(contclass); ++} ++ ++// add suffix to this word assuming conditions hold ++char * SfxEntry::add(const char * word, int len) ++{ ++ char tword[MAXWORDUTF8LEN + 4]; ++ ++ /* make sure all conditions match */ ++ if ((len > stripl) && (len >= numconds) && test_condition(word + len, word) && ++ (!stripl || (strcmp(word + len - stripl, strip) == 0)) && ++ ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) { ++ /* we have a match so add suffix */ ++ strcpy(tword,word); ++ if (appndl) { ++ strcpy(tword + len - stripl, appnd); ++ } else { ++ *(tword + len - stripl) = '\0'; ++ } ++ return mystrdup(tword); ++ } ++ return NULL; ++} ++ ++ ++inline int SfxEntry::test_condition(const char * st, const char * beg) ++{ ++ int cond; ++ unsigned char * cp = (unsigned char *) st; ++ if (!(opts & aeUTF8)) { // 256-character codepage ++ // Domolki affix algorithm ++ for (cond = numconds; --cond >= 0; ) { ++ if ((conds.base[*--cp] & (1 << cond)) == 0) return 0; ++ } ++ } else { // UTF-8 encoding ++ unsigned short wc; ++ for (cond = numconds; --cond >= 0; ) { ++ // go to next character position and check limit ++ if ((char *) --cp < beg) return 0; ++ // a simple 7-bit ASCII character in UTF-8 ++ if ((*cp >> 7) == 0) { ++ if ((conds.utf8.ascii[*cp] & (1 << cond)) == 0) return 0; ++ // UTF-8 multibyte character ++ } else { ++ // go to first character of UTF-8 multibyte character ++ for (; (*cp & 0xc0) == 0x80; cp--); ++ // not dot wildcard in rule ++ if (!conds.utf8.all[cond]) { ++ if (conds.utf8.neg[cond]) { ++ u8_u16((w_char *) &wc, 1, (char *) cp); ++ if (conds.utf8.wchars[cond] && ++ flag_bsearch((unsigned short *)conds.utf8.wchars[cond], ++ wc, (short) conds.utf8.wlen[cond])) return 0; ++ } else { ++ if (!conds.utf8.wchars[cond]) return 0; ++ u8_u16((w_char *) &wc, 1, (char *) cp); ++ if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond], ++ wc, (short)conds.utf8.wlen[cond])) return 0; ++ } ++ } ++ } ++ } ++ } ++ return 1; ++} ++ ++ ++ ++// see if this suffix is present in the word ++struct hentry * SfxEntry::checkword(const char * word, int len, int optflags, ++ AffEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag, ++ const FLAG badflag) ++{ ++ int tmpl; // length of tmpword ++ struct hentry * he; // hash entry pointer ++ unsigned char * cp; ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ ++ // if this suffix is being cross checked with a prefix ++ // but it does not support cross products skip it ++ ++ if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0)) ++ return NULL; ++ ++ // upon entry suffix is 0 length or already matches the end of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ // the second condition is not enough for UTF-8 strings ++ // it checked in test_condition() ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing suffix and adding ++ // back any characters that would have been stripped or ++ // or null terminating the shorter string ++ ++ strcpy (tmpword, word); ++ cp = (unsigned char *)(tmpword + tmpl); ++ if (stripl) { ++ strcpy ((char *)cp, strip); ++ tmpl += stripl; ++ cp = (unsigned char *)(tmpword + tmpl); ++ } else *cp = '\0'; ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being // tested ++ ++ // if all conditions are met then check if resulting ++ // root word in the dictionary ++ ++ if (test_condition((char *) cp, (char *) tmpword)) { ++ ++#ifdef SZOSZABLYA_POSSIBLE_ROOTS ++ fprintf(stdout,"%s %s %c\n", word, tmpword, aflag); ++#endif ++ if ((he = pmyMgr->lookup(tmpword)) != NULL) { ++ do { ++ // check conditional suffix (enabled by prefix) ++ if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && ++ TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && ++ (((optflags & aeXPRODUCT) == 0) || ++ TESTAFF(he->astr, ep->getFlag(), he->alen) || ++ // enabled by prefix ++ ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) ++ ) && ++ // handle cont. class ++ ((!cclass) || ++ ((contclass) && TESTAFF(contclass, cclass, contclasslen)) ++ ) && ++ // check only in compound homonyms (bad flags) ++ (!badflag || !TESTAFF(he->astr, badflag, he->alen) ++ ) && ++ // handle required flag ++ ((!needflag) || ++ (TESTAFF(he->astr, needflag, he->alen) || ++ ((contclass) && TESTAFF(contclass, needflag, contclasslen))) ++ ) ++ ) return he; ++ he = he->next_homonym; // check homonyms ++ } while (he); ++ ++ // obsolote stemming code (used only by the ++ // experimental SuffixMgr:suggest_pos_stems) ++ // store resulting root in wlst ++ } else if (wlst && (*ns < maxSug)) { ++ int cwrd = 1; ++ for (int k=0; k < *ns; k++) ++ if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0; ++ if (cwrd) { ++ wlst[*ns] = mystrdup(tmpword); ++ if (wlst[*ns] == NULL) { ++ for (int j=0; j<*ns; j++) free(wlst[j]); ++ *ns = -1; ++ return NULL; ++ } ++ (*ns)++; ++ } ++ } ++ } ++ } ++ return NULL; ++} ++ ++// see if two-level suffix is present in the word ++struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags, ++ AffEntry* ppfx, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ struct hentry * he; // hash entry pointer ++ unsigned char * cp; ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ ++ ++ // if this suffix is being cross checked with a prefix ++ // but it does not support cross products skip it ++ ++ if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0) ++ return NULL; ++ ++ // upon entry suffix is 0 length or already matches the end of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing suffix and adding ++ // back any characters that would have been stripped or ++ // or null terminating the shorter string ++ ++ strcpy (tmpword, word); ++ cp = (unsigned char *)(tmpword + tmpl); ++ if (stripl) { ++ strcpy ((char *)cp, strip); ++ tmpl += stripl; ++ cp = (unsigned char *)(tmpword + tmpl); ++ } else *cp = '\0'; ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then recall suffix_check ++ ++ if (test_condition((char *) cp, (char *) tmpword)) { ++ if (ppfx) { ++ // handle conditional suffix ++ if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) ++ he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag); ++ else ++ he = pmyMgr->suffix_check(tmpword, tmpl, optflags, ppfx, NULL, 0, NULL, (FLAG) aflag, needflag); ++ } else { ++ he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag); ++ } ++ if (he) return he; ++ } ++ } ++ return NULL; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// see if two-level suffix is present in the word ++char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags, ++ AffEntry* ppfx, const FLAG needflag) ++{ ++ int tmpl; // length of tmpword ++ unsigned char * cp; ++ char tmpword[MAXWORDUTF8LEN + 4]; ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ char * st; ++ ++ char result[MAXLNLEN]; ++ ++ *result = '\0'; ++ ++ // if this suffix is being cross checked with a prefix ++ // but it does not support cross products skip it ++ ++ if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0) ++ return NULL; ++ ++ // upon entry suffix is 0 length or already matches the end of the word. ++ // So if the remaining root word has positive length ++ // and if there are enough chars in root word and added back strip chars ++ // to meet the number of characters conditions, then test it ++ ++ tmpl = len - appndl; ++ ++ if ((tmpl > 0) && (tmpl + stripl >= numconds)) { ++ ++ // generate new root word by removing suffix and adding ++ // back any characters that would have been stripped or ++ // or null terminating the shorter string ++ ++ strcpy (tmpword, word); ++ cp = (unsigned char *)(tmpword + tmpl); ++ if (stripl) { ++ strcpy ((char *)cp, strip); ++ tmpl += stripl; ++ cp = (unsigned char *)(tmpword + tmpl); ++ } else *cp = '\0'; ++ ++ // now make sure all of the conditions on characters ++ // are met. Please see the appendix at the end of ++ // this file for more info on exactly what is being ++ // tested ++ ++ // if all conditions are met then recall suffix_check ++ ++ if (test_condition((char *) cp, (char *) tmpword)) { ++ if (ppfx) { ++ // handle conditional suffix ++ if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) { ++ st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag); ++ if (st) { ++ if (((PfxEntry *) ppfx)->getMorph()) { ++ strcat(result, ((PfxEntry *) ppfx)->getMorph()); ++ } ++ strcat(result,st); ++ free(st); ++ mychomp(result); ++ } ++ } else { ++ st = pmyMgr->suffix_check_morph(tmpword, tmpl, optflags, ppfx, aflag, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ mychomp(result); ++ } ++ } ++ } else { ++ st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ mychomp(result); ++ } ++ } ++ if (*result) return mystrdup(result); ++ } ++ } ++ return NULL; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++// get next homonym with same affix ++struct hentry * SfxEntry::get_next_homonym(struct hentry * he, int optflags, AffEntry* ppfx, ++ const FLAG cclass, const FLAG needflag) ++{ ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ FLAG eFlag = ep ? ep->getFlag() : FLAG_NULL; ++ ++ while (he->next_homonym) { ++ he = he->next_homonym; ++ if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && ++ ((optflags & aeXPRODUCT) == 0 || ++ TESTAFF(he->astr, eFlag, he->alen) || ++ // handle conditional suffix ++ ((contclass) && TESTAFF(contclass, eFlag, contclasslen)) ++ ) && ++ // handle cont. class ++ ((!cclass) || ++ ((contclass) && TESTAFF(contclass, cclass, contclasslen)) ++ ) && ++ // handle required flag ++ ((!needflag) || ++ (TESTAFF(he->astr, needflag, he->alen) || ++ ((contclass) && TESTAFF(contclass, needflag, contclasslen))) ++ ) ++ ) return he; ++ } ++ return NULL; ++} ++ ++ ++#if 0 ++ ++Appendix: Understanding Affix Code ++ ++ ++An affix is either a prefix or a suffix attached to root words to make ++other words. ++ ++Basically a Prefix or a Suffix is set of AffEntry objects ++which store information about the prefix or suffix along ++with supporting routines to check if a word has a particular ++prefix or suffix or a combination. ++ ++The structure affentry is defined as follows: ++ ++struct affentry ++{ ++ unsigned short aflag; // ID used to represent the affix ++ char * strip; // string to strip before adding affix ++ char * appnd; // the affix string to add ++ unsigned char stripl; // length of the strip string ++ unsigned char appndl; // length of the affix string ++ char numconds; // the number of conditions that must be met ++ char opts; // flag: aeXPRODUCT- combine both prefix and suffix ++ char conds[SETSIZE]; // array which encodes the conditions to be met ++}; ++ ++ ++Here is a suffix borrowed from the en_US.aff file. This file ++is whitespace delimited. ++ ++SFX D Y 4 ++SFX D 0 e d ++SFX D y ied [^aeiou]y ++SFX D 0 ed [^ey] ++SFX D 0 ed [aeiou]y ++ ++This information can be interpreted as follows: ++ ++In the first line has 4 fields ++ ++Field ++----- ++1 SFX - indicates this is a suffix ++2 D - is the name of the character flag which represents this suffix ++3 Y - indicates it can be combined with prefixes (cross product) ++4 4 - indicates that sequence of 4 affentry structures are needed to ++ properly store the affix information ++ ++The remaining lines describe the unique information for the 4 SfxEntry ++objects that make up this affix. Each line can be interpreted ++as follows: (note fields 1 and 2 are as a check against line 1 info) ++ ++Field ++----- ++1 SFX - indicates this is a suffix ++2 D - is the name of the character flag for this affix ++3 y - the string of chars to strip off before adding affix ++ (a 0 here indicates the NULL string) ++4 ied - the string of affix characters to add ++5 [^aeiou]y - the conditions which must be met before the affix ++ can be applied ++ ++Field 5 is interesting. Since this is a suffix, field 5 tells us that ++there are 2 conditions that must be met. The first condition is that ++the next to the last character in the word must *NOT* be any of the ++following "a", "e", "i", "o" or "u". The second condition is that ++the last character of the word must end in "y". ++ ++So how can we encode this information concisely and be able to ++test for both conditions in a fast manner? The answer is found ++but studying the wonderful ispell code of Geoff Kuenning, et.al. ++(now available under a normal BSD license). ++ ++If we set up a conds array of 256 bytes indexed (0 to 255) and access it ++using a character (cast to an unsigned char) of a string, we have 8 bits ++of information we can store about that character. Specifically we ++could use each bit to say if that character is allowed in any of the ++last (or first for prefixes) 8 characters of the word. ++ ++Basically, each character at one end of the word (up to the number ++of conditions) is used to index into the conds array and the resulting ++value found there says whether the that character is valid for a ++specific character position in the word. ++ ++For prefixes, it does this by setting bit 0 if that char is valid ++in the first position, bit 1 if valid in the second position, and so on. ++ ++If a bit is not set, then that char is not valid for that postion in the ++word. ++ ++If working with suffixes bit 0 is used for the character closest ++to the front, bit 1 for the next character towards the end, ..., ++with bit numconds-1 representing the last char at the end of the string. ++ ++Note: since entries in the conds[] are 8 bits, only 8 conditions ++(read that only 8 character positions) can be examined at one ++end of a word (the beginning for prefixes and the end for suffixes. ++ ++So to make this clearer, lets encode the conds array values for the ++first two affentries for the suffix D described earlier. ++ ++ ++ For the first affentry: ++ numconds = 1 (only examine the last character) ++ ++ conds['e'] = (1 << 0) (the word must end in an E) ++ all others are all 0 ++ ++ For the second affentry: ++ numconds = 2 (only examine the last two characters) ++ ++ conds[X] = conds[X] | (1 << 0) (aeiou are not allowed) ++ where X is all characters *but* a, e, i, o, or u ++ ++ ++ conds['y'] = (1 << 1) (the last char must be a y) ++ all other bits for all other entries in the conds array are zero ++ ++ ++#endif ++ +Index: mozilla/extensions/spellcheck/hunspell/hunspell/affentry.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/affentry.hxx +@@ -0,0 +1,187 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _AFFIX_HXX_ ++#define _AFFIX_HXX_ ++ ++#include "atypes.hxx" ++#include "baseaffix.hxx" ++#include "affixmgr.hxx" ++ ++/* A Prefix Entry */ ++ ++class PfxEntry : public AffEntry ++{ ++ AffixMgr* pmyMgr; ++ ++ PfxEntry * next; ++ PfxEntry * nexteq; ++ PfxEntry * nextne; ++ PfxEntry * flgnxt; ++ ++public: ++ ++ PfxEntry(AffixMgr* pmgr, affentry* dp ); ++ ~PfxEntry(); ++ ++ inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); } ++ struct hentry * checkword(const char * word, int len, char in_compound, ++ const FLAG needflag = FLAG_NULL); ++ ++ struct hentry * check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL); ++ ++ char * check_morph(const char * word, int len, char in_compound, ++ const FLAG needflag = FLAG_NULL); ++ ++ char * check_twosfx_morph(const char * word, int len, ++ char in_compound, const FLAG needflag = FLAG_NULL); ++ ++ inline FLAG getFlag() { return aflag; } ++ inline const char * getKey() { return appnd; } ++ char * add(const char * word, int len); ++ ++ inline short getKeyLen() { return appndl; } ++ ++ inline const char * getMorph() { return morphcode; } ++ ++ inline const unsigned short * getCont() { return contclass; } ++ inline short getContLen() { return contclasslen; } ++ ++ inline PfxEntry * getNext() { return next; } ++ inline PfxEntry * getNextNE() { return nextne; } ++ inline PfxEntry * getNextEQ() { return nexteq; } ++ inline PfxEntry * getFlgNxt() { return flgnxt; } ++ ++ inline void setNext(PfxEntry * ptr) { next = ptr; } ++ inline void setNextNE(PfxEntry * ptr) { nextne = ptr; } ++ inline void setNextEQ(PfxEntry * ptr) { nexteq = ptr; } ++ inline void setFlgNxt(PfxEntry * ptr) { flgnxt = ptr; } ++ ++ inline int test_condition(const char * st); ++}; ++ ++ ++ ++ ++/* A Suffix Entry */ ++ ++class SfxEntry : public AffEntry ++{ ++ AffixMgr* pmyMgr; ++ char * rappnd; ++ ++ SfxEntry * next; ++ SfxEntry * nexteq; ++ SfxEntry * nextne; ++ SfxEntry * flgnxt; ++ ++ SfxEntry * l_morph; ++ SfxEntry * r_morph; ++ SfxEntry * eq_morph; ++ ++public: ++ ++ SfxEntry(AffixMgr* pmgr, affentry* dp ); ++ ~SfxEntry(); ++ ++ inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); } ++ struct hentry * checkword(const char * word, int len, int optflags, ++ AffEntry* ppfx, char ** wlst, int maxSug, int * ns, ++// const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT); ++ const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0); ++ ++ struct hentry * check_twosfx(const char * word, int len, int optflags, AffEntry* ppfx, const FLAG needflag = NULL); ++ ++ char * check_twosfx_morph(const char * word, int len, int optflags, ++ AffEntry* ppfx, const FLAG needflag = FLAG_NULL); ++ struct hentry * get_next_homonym(struct hentry * he); ++ struct hentry * get_next_homonym(struct hentry * word, int optflags, AffEntry* ppfx, ++ const FLAG cclass, const FLAG needflag); ++ ++ ++ inline FLAG getFlag() { return aflag; } ++ inline const char * getKey() { return rappnd; } ++ char * add(const char * word, int len); ++ ++ ++ inline const char * getMorph() { return morphcode; } ++ ++ inline const unsigned short * getCont() { return contclass; } ++ inline short getContLen() { return contclasslen; } ++ inline const char * getAffix() { return appnd; } ++ ++ inline short getKeyLen() { return appndl; } ++ ++ inline SfxEntry * getNext() { return next; } ++ inline SfxEntry * getNextNE() { return nextne; } ++ inline SfxEntry * getNextEQ() { return nexteq; } ++ ++ inline SfxEntry * getLM() { return l_morph; } ++ inline SfxEntry * getRM() { return r_morph; } ++ inline SfxEntry * getEQM() { return eq_morph; } ++ inline SfxEntry * getFlgNxt() { return flgnxt; } ++ ++ inline void setNext(SfxEntry * ptr) { next = ptr; } ++ inline void setNextNE(SfxEntry * ptr) { nextne = ptr; } ++ inline void setNextEQ(SfxEntry * ptr) { nexteq = ptr; } ++ inline void setFlgNxt(SfxEntry * ptr) { flgnxt = ptr; } ++ ++ inline int test_condition(const char * st, const char * begin); ++}; ++ ++#endif ++ ++ +Index: mozilla/extensions/spellcheck/hunspell/hunspell/affixmgr.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/affixmgr.cpp +@@ -0,0 +1,4155 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "affixmgr.hxx" ++#include "affentry.hxx" ++#include "langnum.hxx" ++ ++#include "csutil.hxx" ++ ++#ifndef MOZILLA_CLIENT ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++AffixMgr::AffixMgr(const char * affpath, HashMgr* ptr) ++{ ++ // register hash manager and load affix data from aff file ++ pHMgr = ptr; ++ keystring = NULL; ++ trystring = NULL; ++ encoding=NULL; ++ utf8 = 0; ++ complexprefixes = 0; ++ maptable = NULL; ++ nummap = 0; ++ breaktable = NULL; ++ numbreak = 0; ++ reptable = NULL; ++ numrep = 0; ++ checkcpdtable = NULL; ++ numcheckcpd = 0; ++ defcpdtable = NULL; ++ numdefcpd = 0; ++ phone = NULL; ++ compoundflag = FLAG_NULL; // permits word in compound forms ++ compoundbegin = FLAG_NULL; // may be first word in compound forms ++ compoundmiddle = FLAG_NULL; // may be middle word in compound forms ++ compoundend = FLAG_NULL; // may be last word in compound forms ++ compoundroot = FLAG_NULL; // compound word signing flag ++ compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word ++ compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word ++ checkcompounddup = 0; // forbid double words in compounds ++ checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution) ++ checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds ++ checkcompoundtriple = 0; // forbid compounds with triple letters ++ forbiddenword = FLAG_NULL; // forbidden word signing flag ++ nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag ++ lang = NULL; // language ++ langnum = 0; // language code (see http://l10n.openoffice.org/languages.html) ++ pseudoroot = FLAG_NULL; // forbidden root, allowed only with suffixes ++ cpdwordmax = -1; // default: unlimited wordcount in compound words ++ cpdmin = -1; // undefined ++ cpdmaxsyllable = 0; // default: unlimited syllablecount in compound words ++ cpdvowels=NULL; // vowels (for calculating of Hungarian compounding limit, O(n) search! XXX) ++ cpdvowels_utf16=NULL; // vowels for UTF-8 encoding (bsearch instead of O(n) search) ++ cpdvowels_utf16_len=0; // vowels ++ pfxappnd=NULL; // previous prefix for counting the syllables of prefix BUG ++ sfxappnd=NULL; // previous suffix for counting a special syllables BUG ++ cpdsyllablenum=NULL; // syllable count incrementing flag ++ checknum=0; // checking numbers, and word with numbers ++ wordchars=NULL; // letters + spec. word characters ++ wordchars_utf16=NULL; // letters + spec. word characters ++ wordchars_utf16_len=0; // letters + spec. word characters ++ ignorechars=NULL; // letters + spec. word characters ++ ignorechars_utf16=NULL; // letters + spec. word characters ++ ignorechars_utf16_len=0; // letters + spec. word characters ++ version=NULL; // affix and dictionary file version string ++ havecontclass=0; // flags of possible continuing classes (double affix) ++ // LEMMA_PRESENT: not put root into the morphological output. Lemma presents ++ // in morhological description in dictionary file. It's often combined with PSEUDOROOT. ++ lemma_present = FLAG_NULL; ++ circumfix = FLAG_NULL; ++ onlyincompound = FLAG_NULL; ++ flag_mode = FLAG_CHAR; // default one-character flags in affix and dic file ++ maxngramsugs = -1; // undefined ++ nosplitsugs = 0; ++ sugswithdots = 0; ++ keepcase = 0; ++ checksharps = 0; ++ ++ derived = NULL; // XXX not threadsafe variable for experimental stemming ++ sfx = NULL; ++ pfx = NULL; ++ ++ for (int i=0; i < SETSIZE; i++) { ++ pStart[i] = NULL; ++ sStart[i] = NULL; ++ pFlag[i] = NULL; ++ sFlag[i] = NULL; ++ } ++ ++ for (int j=0; j < CONTSIZE; j++) { ++ contclasses[j] = 0; ++ } ++ ++ if (parse_file(affpath)) { ++ HUNSPELL_WARNING(stderr, "Failure loading aff file %s\n",affpath); ++ } ++ ++ if (cpdmin == -1) cpdmin = MINCPDLEN; ++ ++} ++ ++ ++AffixMgr::~AffixMgr() ++{ ++ ++ // pass through linked prefix entries and clean up ++ for (int i=0; i < SETSIZE ;i++) { ++ pFlag[i] = NULL; ++ PfxEntry * ptr = (PfxEntry *)pStart[i]; ++ PfxEntry * nptr = NULL; ++ while (ptr) { ++ nptr = ptr->getNext(); ++ delete(ptr); ++ ptr = nptr; ++ nptr = NULL; ++ } ++ } ++ ++ // pass through linked suffix entries and clean up ++ for (int j=0; j < SETSIZE ; j++) { ++ sFlag[j] = NULL; ++ SfxEntry * ptr = (SfxEntry *)sStart[j]; ++ SfxEntry * nptr = NULL; ++ while (ptr) { ++ nptr = ptr->getNext(); ++ delete(ptr); ++ ptr = nptr; ++ nptr = NULL; ++ } ++ sStart[j] = NULL; ++ } ++ ++ if (keystring) free(keystring); ++ keystring=NULL; ++ if (trystring) free(trystring); ++ trystring=NULL; ++ if (encoding) free(encoding); ++ encoding=NULL; ++ if (maptable) { ++ for (int j=0; j < nummap; j++) { ++ if (maptable[j].set) free(maptable[j].set); ++ if (maptable[j].set_utf16) free(maptable[j].set_utf16); ++ maptable[j].set = NULL; ++ maptable[j].len = 0; ++ } ++ free(maptable); ++ maptable = NULL; ++ } ++ nummap = 0; ++ if (breaktable) { ++ for (int j=0; j < numbreak; j++) { ++ if (breaktable[j]) free(breaktable[j]); ++ breaktable[j] = NULL; ++ } ++ free(breaktable); ++ breaktable = NULL; ++ } ++ numbreak = 0; ++ if (reptable) { ++ for (int j=0; j < numrep; j++) { ++ free(reptable[j].pattern); ++ free(reptable[j].pattern2); ++ } ++ free(reptable); ++ reptable = NULL; ++ } ++ if (phone && phone->rules) { ++ for (int j=0; j < phone->num + 1; j++) { ++ free(phone->rules[j * 2]); ++ free(phone->rules[j * 2 + 1]); ++ } ++ free(phone->rules); ++ free(phone); ++ phone = NULL; ++ } ++ ++ if (defcpdtable) { ++ for (int j=0; j < numdefcpd; j++) { ++ free(defcpdtable[j].def); ++ defcpdtable[j].def = NULL; ++ } ++ free(defcpdtable); ++ defcpdtable = NULL; ++ } ++ numrep = 0; ++ if (checkcpdtable) { ++ for (int j=0; j < numcheckcpd; j++) { ++ free(checkcpdtable[j].pattern); ++ free(checkcpdtable[j].pattern2); ++ checkcpdtable[j].pattern = NULL; ++ checkcpdtable[j].pattern2 = NULL; ++ } ++ free(checkcpdtable); ++ checkcpdtable = NULL; ++ } ++ numcheckcpd = 0; ++ FREE_FLAG(compoundflag); ++ FREE_FLAG(compoundbegin); ++ FREE_FLAG(compoundmiddle); ++ FREE_FLAG(compoundend); ++ FREE_FLAG(compoundpermitflag); ++ FREE_FLAG(compoundforbidflag); ++ FREE_FLAG(compoundroot); ++ FREE_FLAG(forbiddenword); ++ FREE_FLAG(nosuggest); ++ FREE_FLAG(pseudoroot); ++ FREE_FLAG(lemma_present); ++ FREE_FLAG(circumfix); ++ FREE_FLAG(onlyincompound); ++ ++ cpdwordmax = 0; ++ pHMgr = NULL; ++ cpdmin = 0; ++ cpdmaxsyllable = 0; ++ if (cpdvowels) free(cpdvowels); ++ if (cpdvowels_utf16) free(cpdvowels_utf16); ++ if (cpdsyllablenum) free(cpdsyllablenum); ++ free_utf_tbl(); ++ if (lang) free(lang); ++ if (wordchars) free(wordchars); ++ if (wordchars_utf16) free(wordchars_utf16); ++ if (ignorechars) free(ignorechars); ++ if (ignorechars_utf16) free(ignorechars_utf16); ++ if (version) free(version); ++ if (derived) free(derived); ++ checknum=0; ++} ++ ++ ++// read in aff file and build up prefix and suffix entry objects ++int AffixMgr::parse_file(const char * affpath) ++{ ++ ++ // io buffers ++ char line[MAXLNLEN+1]; ++ ++ // affix type ++ char ft; ++ ++ // checking flag duplication ++ char dupflags[CONTSIZE]; ++ char dupflags_ini = 1; ++ ++ // first line indicator for removing byte order mark ++ int firstline = 1; ++ ++ // open the affix file ++ FILE * afflst; ++ afflst = fopen(affpath,"r"); ++ if (!afflst) { ++ HUNSPELL_WARNING(stderr, "error: could not open affix description file %s\n",affpath); ++ return 1; ++ } ++ ++ // step one is to parse the affix file building up the internal ++ // affix data structures ++ ++ ++ // read in each line ignoring any that do not ++ // start with a known line type indicator ++ while (fgets(line,MAXLNLEN,afflst)) { ++ mychomp(line); ++ ++ /* remove byte order mark */ ++ if (firstline) { ++ firstline = 0; ++ if (strncmp(line,"\xEF\xBB\xBF",3) == 0) { ++ memmove(line, line+3, strlen(line+3)+1); ++ HUNSPELL_WARNING(stderr, "warning: affix file begins with byte order mark: possible incompatibility with old Hunspell versions\n"); ++ } ++ } ++ ++ /* parse in the keyboard string */ ++ if (strncmp(line,"KEY",3) == 0) { ++ if (parse_string(line, &keystring, "KEY")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the try string */ ++ if (strncmp(line,"TRY",3) == 0) { ++ if (parse_string(line, &trystring, "TRY")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the name of the character set used by the .dict and .aff */ ++ if (strncmp(line,"SET",3) == 0) { ++ if (parse_string(line, &encoding, "SET")) { ++ fclose(afflst); ++ return 1; ++ } ++ if (strcmp(encoding, "UTF-8") == 0) { ++ utf8 = 1; ++#ifndef OPENOFFICEORG ++#ifndef MOZILLA_CLIENT ++ if (initialize_utf_tbl()) return 1; ++#endif ++#endif ++ } ++ } ++ ++ /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left writing system */ ++ if (strncmp(line,"COMPLEXPREFIXES",15) == 0) ++ complexprefixes = 1; ++ ++ /* parse in the flag used by the controlled compound words */ ++ if (strncmp(line,"COMPOUNDFLAG",12) == 0) { ++ if (parse_flag(line, &compoundflag, "COMPOUNDFLAG")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by compound words */ ++ if (strncmp(line,"COMPOUNDBEGIN",13) == 0) { ++ if (complexprefixes) { ++ if (parse_flag(line, &compoundend, "COMPOUNDBEGIN")) { ++ fclose(afflst); ++ return 1; ++ } ++ } else { ++ if (parse_flag(line, &compoundbegin, "COMPOUNDBEGIN")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ } ++ ++ /* parse in the flag used by compound words */ ++ if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) { ++ if (parse_flag(line, &compoundmiddle, "COMPOUNDMIDDLE")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ /* parse in the flag used by compound words */ ++ if (strncmp(line,"COMPOUNDEND",11) == 0) { ++ if (complexprefixes) { ++ if (parse_flag(line, &compoundbegin, "COMPOUNDEND")) { ++ fclose(afflst); ++ return 1; ++ } ++ } else { ++ if (parse_flag(line, &compoundend, "COMPOUNDEND")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ } ++ ++ /* parse in the data used by compound_check() method */ ++ if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) { ++ if (parse_num(line, &cpdwordmax, "COMPOUNDWORDMAX")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag sign compounds in dictionary */ ++ if (strncmp(line,"COMPOUNDROOT",12) == 0) { ++ if (parse_flag(line, &compoundroot, "COMPOUNDROOT")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by compound_check() method */ ++ if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) { ++ if (parse_flag(line, &compoundpermitflag, "COMPOUNDPERMITFLAG")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by compound_check() method */ ++ if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) { ++ if (parse_flag(line, &compoundforbidflag, "COMPOUNDFORBIDFLAG")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) { ++ checkcompounddup = 1; ++ } ++ ++ if (strncmp(line,"CHECKCOMPOUNDREP",16) == 0) { ++ checkcompoundrep = 1; ++ } ++ ++ if (strncmp(line,"CHECKCOMPOUNDTRIPLE",19) == 0) { ++ checkcompoundtriple = 1; ++ } ++ ++ if (strncmp(line,"CHECKCOMPOUNDCASE",17) == 0) { ++ checkcompoundcase = 1; ++ } ++ ++ if (strncmp(line,"NOSUGGEST",9) == 0) { ++ if (parse_flag(line, &nosuggest, "NOSUGGEST")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by forbidden words */ ++ if (strncmp(line,"FORBIDDENWORD",13) == 0) { ++ if (parse_flag(line, &forbiddenword, "FORBIDDENWORD")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by forbidden words */ ++ if (strncmp(line,"LEMMA_PRESENT",13) == 0) { ++ if (parse_flag(line, &lemma_present, "LEMMA_PRESENT")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by circumfixes */ ++ if (strncmp(line,"CIRCUMFIX",9) == 0) { ++ if (parse_flag(line, &circumfix, "CIRCUMFIX")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by fogemorphemes */ ++ if (strncmp(line,"ONLYINCOMPOUND",14) == 0) { ++ if (parse_flag(line, &onlyincompound, "ONLYINCOMPOUND")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by `pseudoroots' */ ++ if (strncmp(line,"PSEUDOROOT",10) == 0) { ++ if (parse_flag(line, &pseudoroot, "PSEUDOROOT")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by `pseudoroots' */ ++ if (strncmp(line,"NEEDAFFIX",9) == 0) { ++ if (parse_flag(line, &pseudoroot, "NEEDAFFIX")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the minimal length for words in compounds */ ++ if (strncmp(line,"COMPOUNDMIN",11) == 0) { ++ if (parse_num(line, &cpdmin, "COMPOUNDMIN")) { ++ fclose(afflst); ++ return 1; ++ } ++ if (cpdmin < 1) cpdmin = 1; ++ } ++ ++ /* parse in the max. words and syllables in compounds */ ++ if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) { ++ if (parse_cpdsyllable(line)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by compound_check() method */ ++ if (strncmp(line,"SYLLABLENUM",11) == 0) { ++ if (parse_string(line, &cpdsyllablenum, "SYLLABLENUM")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the flag used by the controlled compound words */ ++ if (strncmp(line,"CHECKNUM",8) == 0) { ++ checknum=1; ++ } ++ ++ /* parse in the extra word characters */ ++ if (strncmp(line,"WORDCHARS",9) == 0) { ++ if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, "WORDCHARS", utf8)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the ignored characters (for example, Arabic optional diacretics charachters */ ++ if (strncmp(line,"IGNORE",6) == 0) { ++ if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the typical fault correcting table */ ++ if (strncmp(line,"REP",3) == 0) { ++ if (parse_reptable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the phonetic translation table */ ++ if (strncmp(line,"PHONE",5) == 0) { ++ if (parse_phonetable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the checkcompoundpattern table */ ++ if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) { ++ if (parse_checkcpdtable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the defcompound table */ ++ if (strncmp(line,"COMPOUNDRULE",12) == 0) { ++ if (parse_defcpdtable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the related character map table */ ++ if (strncmp(line,"MAP",3) == 0) { ++ if (parse_maptable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the word breakpoints table */ ++ if (strncmp(line,"BREAK",5) == 0) { ++ if (parse_breaktable(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ /* parse in the language for language specific codes */ ++ if (strncmp(line,"LANG",4) == 0) { ++ if (parse_string(line, &lang, "LANG")) { ++ fclose(afflst); ++ return 1; ++ } ++ langnum = get_lang_num(lang); ++ } ++ ++ if (strncmp(line,"VERSION",7) == 0) { ++ if (parse_string(line, &version, "VERSION")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ if (strncmp(line,"MAXNGRAMSUGS",12) == 0) { ++ if (parse_num(line, &maxngramsugs, "MAXNGRAMSUGS")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ if (strncmp(line,"NOSPLITSUGS",11) == 0) { ++ nosplitsugs=1; ++ } ++ ++ if (strncmp(line,"SUGSWITHDOTS",12) == 0) { ++ sugswithdots=1; ++ } ++ ++ /* parse in the flag used by forbidden words */ ++ if (strncmp(line,"KEEPCASE",8) == 0) { ++ if (parse_flag(line, &keepcase, "KEEPCASE")) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ if (strncmp(line,"CHECKSHARPS",11) == 0) { ++ checksharps=1; ++ } ++ ++ /* parse this affix: P - prefix, S - suffix */ ++ ft = ' '; ++ if (strncmp(line,"PFX",3) == 0) ft = complexprefixes ? 'S' : 'P'; ++ if (strncmp(line,"SFX",3) == 0) ft = complexprefixes ? 'P' : 'S'; ++ if (ft != ' ') { ++ if (dupflags_ini) { ++ for (int i = 0; i < CONTSIZE; i++) dupflags[i] = 0; ++ dupflags_ini = 0; ++ } ++ if (parse_affix(line, ft, afflst, dupflags)) { ++ fclose(afflst); ++ process_pfx_tree_to_list(); ++ process_sfx_tree_to_list(); ++ return 1; ++ } ++ } ++ ++ } ++ fclose(afflst); ++ ++ // convert affix trees to sorted list ++ process_pfx_tree_to_list(); ++ process_sfx_tree_to_list(); ++ ++ // now we can speed up performance greatly taking advantage of the ++ // relationship between the affixes and the idea of "subsets". ++ ++ // View each prefix as a potential leading subset of another and view ++ // each suffix (reversed) as a potential trailing subset of another. ++ ++ // To illustrate this relationship if we know the prefix "ab" is found in the ++ // word to examine, only prefixes that "ab" is a leading subset of need be examined. ++ // Furthermore is "ab" is not present then none of the prefixes that "ab" is ++ // is a subset need be examined. ++ // The same argument goes for suffix string that are reversed. ++ ++ // Then to top this off why not examine the first char of the word to quickly ++ // limit the set of prefixes to examine (i.e. the prefixes to examine must ++ // be leading supersets of the first character of the word (if they exist) ++ ++ // To take advantage of this "subset" relationship, we need to add two links ++ // from entry. One to take next if the current prefix is found (call it nexteq) ++ // and one to take next if the current prefix is not found (call it nextne). ++ ++ // Since we have built ordered lists, all that remains is to properly intialize ++ // the nextne and nexteq pointers that relate them ++ ++ process_pfx_order(); ++ process_sfx_order(); ++ ++ /* get encoding for CHECKCOMPOUNDCASE */ ++ char * enc = get_encoding(); ++ csconv = get_current_cs(enc); ++ free(enc); ++ enc = NULL; ++ ++ // temporary BREAK definition for German dash handling (OOo issue 64400) ++ if ((langnum == LANG_de) && (!breaktable)) { ++ breaktable = (char **) malloc(sizeof(char *)); ++ if (!breaktable) return 1; ++ breaktable[0] = mystrdup("-"); ++ numbreak = 1; ++ } ++ return 0; ++} ++ ++ ++// we want to be able to quickly access prefix information ++// both by prefix flag, and sorted by prefix string itself ++// so we need to set up two indexes ++ ++int AffixMgr::build_pfxtree(AffEntry* pfxptr) ++{ ++ PfxEntry * ptr; ++ PfxEntry * pptr; ++ PfxEntry * ep = (PfxEntry*) pfxptr; ++ ++ // get the right starting points ++ const char * key = ep->getKey(); ++ const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF); ++ ++ // first index by flag which must exist ++ ptr = (PfxEntry*)pFlag[flg]; ++ ep->setFlgNxt(ptr); ++ pFlag[flg] = (AffEntry *) ep; ++ ++ ++ // handle the special case of null affix string ++ if (strlen(key) == 0) { ++ // always inset them at head of list at element 0 ++ ptr = (PfxEntry*)pStart[0]; ++ ep->setNext(ptr); ++ pStart[0] = (AffEntry*)ep; ++ return 0; ++ } ++ ++ // now handle the normal case ++ ep->setNextEQ(NULL); ++ ep->setNextNE(NULL); ++ ++ unsigned char sp = *((const unsigned char *)key); ++ ptr = (PfxEntry*)pStart[sp]; ++ ++ // handle the first insert ++ if (!ptr) { ++ pStart[sp] = (AffEntry*)ep; ++ return 0; ++ } ++ ++ ++ // otherwise use binary tree insertion so that a sorted ++ // list can easily be generated later ++ pptr = NULL; ++ for (;;) { ++ pptr = ptr; ++ if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) { ++ ptr = ptr->getNextEQ(); ++ if (!ptr) { ++ pptr->setNextEQ(ep); ++ break; ++ } ++ } else { ++ ptr = ptr->getNextNE(); ++ if (!ptr) { ++ pptr->setNextNE(ep); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++// we want to be able to quickly access suffix information ++// both by suffix flag, and sorted by the reverse of the ++// suffix string itself; so we need to set up two indexes ++int AffixMgr::build_sfxtree(AffEntry* sfxptr) ++{ ++ SfxEntry * ptr; ++ SfxEntry * pptr; ++ SfxEntry * ep = (SfxEntry *) sfxptr; ++ ++ /* get the right starting point */ ++ const char * key = ep->getKey(); ++ const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF); ++ ++ // first index by flag which must exist ++ ptr = (SfxEntry*)sFlag[flg]; ++ ep->setFlgNxt(ptr); ++ sFlag[flg] = (AffEntry *) ep; ++ ++ // next index by affix string ++ ++ // handle the special case of null affix string ++ if (strlen(key) == 0) { ++ // always inset them at head of list at element 0 ++ ptr = (SfxEntry*)sStart[0]; ++ ep->setNext(ptr); ++ sStart[0] = (AffEntry*)ep; ++ return 0; ++ } ++ ++ // now handle the normal case ++ ep->setNextEQ(NULL); ++ ep->setNextNE(NULL); ++ ++ unsigned char sp = *((const unsigned char *)key); ++ ptr = (SfxEntry*)sStart[sp]; ++ ++ // handle the first insert ++ if (!ptr) { ++ sStart[sp] = (AffEntry*)ep; ++ return 0; ++ } ++ ++ // otherwise use binary tree insertion so that a sorted ++ // list can easily be generated later ++ pptr = NULL; ++ for (;;) { ++ pptr = ptr; ++ if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) { ++ ptr = ptr->getNextEQ(); ++ if (!ptr) { ++ pptr->setNextEQ(ep); ++ break; ++ } ++ } else { ++ ptr = ptr->getNextNE(); ++ if (!ptr) { ++ pptr->setNextNE(ep); ++ break; ++ } ++ } ++ } ++ return 0; ++} ++ ++// convert from binary tree to sorted list ++int AffixMgr::process_pfx_tree_to_list() ++{ ++ for (int i=1; i< SETSIZE; i++) { ++ pStart[i] = process_pfx_in_order(pStart[i],NULL); ++ } ++ return 0; ++} ++ ++ ++AffEntry* AffixMgr::process_pfx_in_order(AffEntry* ptr, AffEntry* nptr) ++{ ++ if (ptr) { ++ nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextNE(), nptr); ++ ((PfxEntry*) ptr)->setNext((PfxEntry*) nptr); ++ nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextEQ(), ptr); ++ } ++ return nptr; ++} ++ ++ ++// convert from binary tree to sorted list ++int AffixMgr:: process_sfx_tree_to_list() ++{ ++ for (int i=1; i< SETSIZE; i++) { ++ sStart[i] = process_sfx_in_order(sStart[i],NULL); ++ } ++ return 0; ++} ++ ++AffEntry* AffixMgr::process_sfx_in_order(AffEntry* ptr, AffEntry* nptr) ++{ ++ if (ptr) { ++ nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextNE(), nptr); ++ ((SfxEntry*) ptr)->setNext((SfxEntry*) nptr); ++ nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextEQ(), ptr); ++ } ++ return nptr; ++} ++ ++ ++// reinitialize the PfxEntry links NextEQ and NextNE to speed searching ++// using the idea of leading subsets this time ++int AffixMgr::process_pfx_order() ++{ ++ PfxEntry* ptr; ++ ++ // loop through each prefix list starting point ++ for (int i=1; i < SETSIZE; i++) { ++ ++ ptr = (PfxEntry*)pStart[i]; ++ ++ // look through the remainder of the list ++ // and find next entry with affix that ++ // the current one is not a subset of ++ // mark that as destination for NextNE ++ // use next in list that you are a subset ++ // of as NextEQ ++ ++ for (; ptr != NULL; ptr = ptr->getNext()) { ++ ++ PfxEntry * nptr = ptr->getNext(); ++ for (; nptr != NULL; nptr = nptr->getNext()) { ++ if (! isSubset( ptr->getKey() , nptr->getKey() )) break; ++ } ++ ptr->setNextNE(nptr); ++ ptr->setNextEQ(NULL); ++ if ((ptr->getNext()) && isSubset(ptr->getKey() , (ptr->getNext())->getKey())) ++ ptr->setNextEQ(ptr->getNext()); ++ } ++ ++ // now clean up by adding smart search termination strings: ++ // if you are already a superset of the previous prefix ++ // but not a subset of the next, search can end here ++ // so set NextNE properly ++ ++ ptr = (PfxEntry *) pStart[i]; ++ for (; ptr != NULL; ptr = ptr->getNext()) { ++ PfxEntry * nptr = ptr->getNext(); ++ PfxEntry * mptr = NULL; ++ for (; nptr != NULL; nptr = nptr->getNext()) { ++ if (! isSubset(ptr->getKey(),nptr->getKey())) break; ++ mptr = nptr; ++ } ++ if (mptr) mptr->setNextNE(NULL); ++ } ++ } ++ return 0; ++} ++ ++// initialize the SfxEntry links NextEQ and NextNE to speed searching ++// using the idea of leading subsets this time ++int AffixMgr::process_sfx_order() ++{ ++ SfxEntry* ptr; ++ ++ // loop through each prefix list starting point ++ for (int i=1; i < SETSIZE; i++) { ++ ++ ptr = (SfxEntry *) sStart[i]; ++ ++ // look through the remainder of the list ++ // and find next entry with affix that ++ // the current one is not a subset of ++ // mark that as destination for NextNE ++ // use next in list that you are a subset ++ // of as NextEQ ++ ++ for (; ptr != NULL; ptr = ptr->getNext()) { ++ SfxEntry * nptr = ptr->getNext(); ++ for (; nptr != NULL; nptr = nptr->getNext()) { ++ if (! isSubset(ptr->getKey(),nptr->getKey())) break; ++ } ++ ptr->setNextNE(nptr); ++ ptr->setNextEQ(NULL); ++ if ((ptr->getNext()) && isSubset(ptr->getKey(),(ptr->getNext())->getKey())) ++ ptr->setNextEQ(ptr->getNext()); ++ } ++ ++ ++ // now clean up by adding smart search termination strings: ++ // if you are already a superset of the previous suffix ++ // but not a subset of the next, search can end here ++ // so set NextNE properly ++ ++ ptr = (SfxEntry *) sStart[i]; ++ for (; ptr != NULL; ptr = ptr->getNext()) { ++ SfxEntry * nptr = ptr->getNext(); ++ SfxEntry * mptr = NULL; ++ for (; nptr != NULL; nptr = nptr->getNext()) { ++ if (! isSubset(ptr->getKey(),nptr->getKey())) break; ++ mptr = nptr; ++ } ++ if (mptr) mptr->setNextNE(NULL); ++ } ++ } ++ return 0; ++} ++ ++ ++ ++// takes aff file condition string and creates the ++// conds array - please see the appendix at the end of the ++// file affentry.cpp which describes what is going on here ++// in much more detail ++ ++int AffixMgr::encodeit(struct affentry * ptr, char * cs) ++{ ++ unsigned char c; ++ int i, j, k; ++ unsigned char mbr[MAXLNLEN]; ++ w_char wmbr[MAXLNLEN]; ++ w_char * wpos = wmbr; ++ ++ // now clear the conditions array */ ++ for (i=0;iconds.base[i] = (unsigned char) 0; ++ ++ // now parse the string to create the conds array */ ++ int nc = strlen(cs); ++ unsigned char neg = 0; // complement indicator ++ int grp = 0; // group indicator ++ unsigned char n = 0; // number of conditions ++ int ec = 0; // end condition indicator ++ int nm = 0; // number of member in group ++ ++ // if no condition just return ++ if (strcmp(cs,".")==0) { ++ ptr->numconds = 0; ++ return 0; ++ } ++ ++ i = 0; ++ while (i < nc) { ++ c = *((unsigned char *)(cs + i)); ++ ++ // start group indicator ++ if (c == '[') { ++ grp = 1; ++ c = 0; ++ } ++ ++ // complement flag ++ if ((grp == 1) && (c == '^')) { ++ neg = 1; ++ c = 0; ++ } ++ ++ // end goup indicator ++ if (c == ']') { ++ ec = 1; ++ c = 0; ++ } ++ ++ // add character of group to list ++ if ((grp == 1) && (c != 0)) { ++ *(mbr + nm) = c; ++ nm++; ++ c = 0; ++ } ++ ++ // end of condition ++ if (c != 0) { ++ ec = 1; ++ } ++ ++ if (ec) { ++ if (!utf8) { ++ if (grp == 1) { ++ if (neg == 0) { ++ // set the proper bits in the condition array vals for those chars ++ for (j=0;jconds.base[k] = ptr->conds.base[k] | ((unsigned char)1 << n); ++ } ++ } else { ++ // complement so set all of them and then unset indicated ones ++ for (j=0;jconds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n); ++ for (j=0;jconds.base[k] = ptr->conds.base[k] & ~((unsigned char)1 << n); ++ } ++ } ++ neg = 0; ++ grp = 0; ++ nm = 0; ++ } else { ++ // not a group so just set the proper bit for this char ++ // but first handle special case of . inside condition ++ if (c == '.') { ++ // wild card character so set them all ++ for (j=0;jconds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n); ++ } else { ++ ptr->conds.base[(unsigned int) c] = ptr->conds.base[(unsigned int)c] | ((unsigned char)1 << n); ++ } ++ } ++ n++; ++ ec = 0; ++ } else { // UTF-8 character set ++ if (grp == 1) { ++ ptr->conds.utf8.neg[n] = neg; ++ if (neg == 0) { ++ // set the proper bits in the condition array vals for those chars ++ for (j=0;j> 7) { ++ u8_u16(wpos, 1, (char *) mbr + j); ++ wpos++; ++ if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character ++ } else { ++ ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] | ((unsigned char)1 << n); ++ } ++ } ++ } else { // neg == 1 ++ // complement so set all of them and then unset indicated ones ++ for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n); ++ for (j=0;j> 7) { ++ u8_u16(wpos, 1, (char *) mbr + j); ++ wpos++; ++ if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character ++ } else { ++ ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] & ~((unsigned char)1 << n); ++ } ++ } ++ } ++ neg = 0; ++ grp = 0; ++ nm = 0; ++ ptr->conds.utf8.wlen[n] = wpos - wmbr; ++ if ((wpos - wmbr) != 0) { ++ ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char) * (wpos - wmbr)); ++ if (!ptr->conds.utf8.wchars[n]) return 1; ++ memcpy(ptr->conds.utf8.wchars[n], wmbr, sizeof(w_char) * (wpos - wmbr)); ++ flag_qsort((unsigned short *) ptr->conds.utf8.wchars[n], 0, ptr->conds.utf8.wlen[n]); ++ wpos = wmbr; ++ } ++ } else { // grp == 0 ++ // is UTF-8 character? ++ if (c >> 7) { ++ ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char)); ++ if (!ptr->conds.utf8.wchars[n]) return 1; ++ ptr->conds.utf8.wlen[n] = 1; ++ u8_u16(ptr->conds.utf8.wchars[n], 1, cs + i); ++ if ((c & 0xe0) == 0xe0) i+=2; else i++; // 3-byte UFT-8 character ++ } else { ++ ptr->conds.utf8.wchars[n] = NULL; ++ // not a group so just set the proper bit for this char ++ // but first handle special case of . inside condition ++ if (c == '.') { ++ ptr->conds.utf8.all[n] = 1; ++ // wild card character so set them all ++ for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n); ++ } else { ++ ptr->conds.utf8.all[n] = 0; ++ ptr->conds.utf8.ascii[(unsigned int) c] = ptr->conds.utf8.ascii[(unsigned int)c] | ((unsigned char)1 << n); ++ } ++ } ++ neg = 0; ++ } ++ n++; ++ ec = 0; ++ neg = 0; ++ } ++ } ++ ++ i++; ++ } ++ ptr->numconds = n; ++ return 0; ++} ++ ++ // return 1 if s1 is a leading subset of s2 ++/* inline int AffixMgr::isSubset(const char * s1, const char * s2) ++ { ++ while ((*s1 == *s2) && *s1) { ++ s1++; ++ s2++; ++ } ++ return (*s1 == '\0'); ++ } ++*/ ++ ++ // return 1 if s1 is a leading subset of s2 (dots are for infixes) ++inline int AffixMgr::isSubset(const char * s1, const char * s2) ++ { ++ while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0')) { ++ s1++; ++ s2++; ++ } ++ return (*s1 == '\0'); ++ } ++ ++ ++// check word for prefixes ++struct hentry * AffixMgr::prefix_check(const char * word, int len, char in_compound, ++ const FLAG needflag) ++{ ++ struct hentry * rv= NULL; ++ ++ pfx = NULL; ++ pfxappnd = NULL; ++ sfxappnd = NULL; ++ ++ // first handle the special case of 0 length prefixes ++ PfxEntry * pe = (PfxEntry *) pStart[0]; ++ while (pe) { ++ if ( ++ // fogemorpheme ++ ((in_compound != IN_CPD_NOT) || !(pe->getCont() && ++ (TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) && ++ // permit prefixes in compounds ++ ((in_compound != IN_CPD_END) || (pe->getCont() && ++ (TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen())))) ++ ) { ++ // check prefix ++ rv = pe->checkword(word, len, in_compound, needflag); ++ if (rv) { ++ pfx=(AffEntry *)pe; // BUG: pfx not stateless ++ return rv; ++ } ++ } ++ pe = pe->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)word); ++ PfxEntry * pptr = (PfxEntry *)pStart[sp]; ++ ++ while (pptr) { ++ if (isSubset(pptr->getKey(),word)) { ++ if ( ++ // fogemorpheme ++ ((in_compound != IN_CPD_NOT) || !(pptr->getCont() && ++ (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) && ++ // permit prefixes in compounds ++ ((in_compound != IN_CPD_END) || (pptr->getCont() && ++ (TESTAFF(pptr->getCont(), compoundpermitflag, pptr->getContLen())))) ++ ) { ++ // check prefix ++ rv = pptr->checkword(word, len, in_compound, needflag); ++ if (rv) { ++ pfx=(AffEntry *)pptr; // BUG: pfx not stateless ++ return rv; ++ } ++ } ++ pptr = pptr->getNextEQ(); ++ } else { ++ pptr = pptr->getNextNE(); ++ } ++ } ++ ++ return NULL; ++} ++ ++// check word for prefixes ++struct hentry * AffixMgr::prefix_check_twosfx(const char * word, int len, ++ char in_compound, const FLAG needflag) ++{ ++ struct hentry * rv= NULL; ++ ++ pfx = NULL; ++ sfxappnd = NULL; ++ ++ // first handle the special case of 0 length prefixes ++ PfxEntry * pe = (PfxEntry *) pStart[0]; ++ ++ while (pe) { ++ rv = pe->check_twosfx(word, len, in_compound, needflag); ++ if (rv) return rv; ++ pe = pe->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)word); ++ PfxEntry * pptr = (PfxEntry *)pStart[sp]; ++ ++ while (pptr) { ++ if (isSubset(pptr->getKey(),word)) { ++ rv = pptr->check_twosfx(word, len, in_compound, needflag); ++ if (rv) { ++ pfx = (AffEntry *)pptr; ++ return rv; ++ } ++ pptr = pptr->getNextEQ(); ++ } else { ++ pptr = pptr->getNextNE(); ++ } ++ } ++ ++ return NULL; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// check word for prefixes ++char * AffixMgr::prefix_check_morph(const char * word, int len, char in_compound, ++ const FLAG needflag) ++{ ++ char * st; ++ ++ char result[MAXLNLEN]; ++ result[0] = '\0'; ++ ++ pfx = NULL; ++ sfxappnd = NULL; ++ ++ // first handle the special case of 0 length prefixes ++ PfxEntry * pe = (PfxEntry *) pStart[0]; ++ while (pe) { ++ st = pe->check_morph(word,len,in_compound, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ // if (rv) return rv; ++ pe = pe->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)word); ++ PfxEntry * pptr = (PfxEntry *)pStart[sp]; ++ ++ while (pptr) { ++ if (isSubset(pptr->getKey(),word)) { ++ st = pptr->check_morph(word,len,in_compound, needflag); ++ if (st) { ++ // fogemorpheme ++ if ((in_compound != IN_CPD_NOT) || !((pptr->getCont() && ++ (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen()))))) { ++ strcat(result, st); ++ pfx = (AffEntry *)pptr; ++ } ++ free(st); ++ } ++ pptr = pptr->getNextEQ(); ++ } else { ++ pptr = pptr->getNextNE(); ++ } ++ } ++ ++ if (*result) return mystrdup(result); ++ return NULL; ++} ++ ++ ++// check word for prefixes ++char * AffixMgr::prefix_check_twosfx_morph(const char * word, int len, ++ char in_compound, const FLAG needflag) ++{ ++ char * st; ++ ++ char result[MAXLNLEN]; ++ result[0] = '\0'; ++ ++ pfx = NULL; ++ sfxappnd = NULL; ++ ++ // first handle the special case of 0 length prefixes ++ PfxEntry * pe = (PfxEntry *) pStart[0]; ++ while (pe) { ++ st = pe->check_twosfx_morph(word,len,in_compound, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ pe = pe->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)word); ++ PfxEntry * pptr = (PfxEntry *)pStart[sp]; ++ ++ while (pptr) { ++ if (isSubset(pptr->getKey(),word)) { ++ st = pptr->check_twosfx_morph(word, len, in_compound, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ pfx = (AffEntry *)pptr; ++ } ++ pptr = pptr->getNextEQ(); ++ } else { ++ pptr = pptr->getNextNE(); ++ } ++ } ++ ++ if (*result) return mystrdup(result); ++ return NULL; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++ ++// Is word a non compound with a REP substitution (see checkcompoundrep)? ++int AffixMgr::cpdrep_check(const char * word, int wl) ++{ ++ char candidate[MAXLNLEN]; ++ const char * r; ++ int lenr, lenp; ++ ++ if ((wl < 2) || !numrep) return 0; ++ ++ for (int i=0; i < numrep; i++ ) { ++ r = word; ++ lenr = strlen(reptable[i].pattern2); ++ lenp = strlen(reptable[i].pattern); ++ // search every occurence of the pattern in the word ++ while ((r=strstr(r, reptable[i].pattern)) != NULL) { ++ strcpy(candidate, word); ++ if (r-word + lenr + strlen(r+lenp) >= MAXLNLEN) break; ++ strcpy(candidate+(r-word),reptable[i].pattern2); ++ strcpy(candidate+(r-word)+lenr, r+lenp); ++ if (candidate_check(candidate,strlen(candidate))) return 1; ++ r++; // search for the next letter ++ } ++ } ++ return 0; ++} ++ ++// forbid compoundings when there are special patterns at word bound ++int AffixMgr::cpdpat_check(const char * word, int pos) ++{ ++ int len; ++ for (int i = 0; i < numcheckcpd; i++) { ++ if (isSubset(checkcpdtable[i].pattern2, word + pos) && ++ (len = strlen(checkcpdtable[i].pattern)) && (pos > len) && ++ (strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)) return 1; ++ } ++ return 0; ++} ++ ++// forbid compounding with neighbouring upper and lower case characters at word bounds ++int AffixMgr::cpdcase_check(const char * word, int pos) ++{ ++ if (utf8) { ++ w_char u, w; ++ const char * p; ++ u8_u16(&u, 1, word + pos); ++ for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--); ++ u8_u16(&w, 1, p); ++ unsigned short a = (u.h << 8) + u.l; ++ unsigned short b = (w.h << 8) + w.l; ++ if (((unicodetoupper(a, langnum) == a) || (unicodetoupper(b, langnum) == b))) return 1; ++ } else { ++ unsigned char a = *(word + pos - 1); ++ unsigned char b = *(word + pos); ++ if ((csconv[a].ccase || csconv[b].ccase) && (a != '-') && (b != '-')) return 1; ++ } ++ return 0; ++} ++ ++// check compound patterns ++int AffixMgr::defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** def, char all) ++{ ++ signed short btpp[MAXWORDLEN]; // metacharacter (*, ?) positions for backtracking ++ signed short btwp[MAXWORDLEN]; // word positions for metacharacters ++ int btnum[MAXWORDLEN]; // number of matched characters in metacharacter positions ++ short bt = 0; ++ int i; ++ int ok; ++ int w = 0; ++ if (!*words) { ++ w = 1; ++ *words = def; ++ } ++ (*words)[wnum] = rv; ++ ++ for (i = 0; i < numdefcpd; i++) { ++ signed short pp = 0; // pattern position ++ signed short wp = 0; // "words" position ++ int ok2; ++ ok = 1; ++ ok2 = 1; ++ do { ++ while ((pp < defcpdtable[i].len) && (wp <= wnum)) { ++ if (((pp+1) < defcpdtable[i].len) && ++ ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) { ++ int wend = (defcpdtable[i].def[pp+1] == '?') ? wp : wnum; ++ ok2 = 1; ++ pp+=2; ++ btpp[bt] = pp; ++ btwp[bt] = wp; ++ while (wp <= wend) { ++ if (!(*words)[wp]->alen || ++ !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp-2], (*words)[wp]->alen)) { ++ ok2 = 0; ++ break; ++ } ++ wp++; ++ } ++ if (wp <= wnum) ok2 = 0; ++ btnum[bt] = wp - btwp[bt]; ++ if (btnum[bt] > 0) bt++; ++ if (ok2) break; ++ } else { ++ ok2 = 1; ++ if (!(*words)[wp] || !(*words)[wp]->alen || ++ !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp], (*words)[wp]->alen)) { ++ ok = 0; ++ break; ++ } ++ pp++; ++ wp++; ++ if ((defcpdtable[i].len == pp) && !(wp > wnum)) ok = 0; ++ } ++ } ++ if (ok && ok2) { ++ int r = pp; ++ while ((defcpdtable[i].len > r) && ((r+1) < defcpdtable[i].len) && ++ ((defcpdtable[i].def[r+1] == '*') || (defcpdtable[i].def[r+1] == '?'))) r+=2; ++ if (defcpdtable[i].len <= r) return 1; ++ } ++ // backtrack ++ if (bt) do { ++ ok = 1; ++ btnum[bt - 1]--; ++ pp = btpp[bt - 1]; ++ wp = btwp[bt - 1] + btnum[bt - 1]; ++ } while ((btnum[bt - 1] < 0) && --bt); ++ } while (bt); ++ ++ if (ok && ok2 && (!all || (defcpdtable[i].len <= pp))) return 1; ++ // check zero ending ++ while (ok && ok2 && (defcpdtable[i].len > pp) && ((pp+1) < defcpdtable[i].len) && ++ ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) pp+=2; ++ if (ok && ok2 && (defcpdtable[i].len <= pp)) return 1; ++ } ++ (*words)[wnum] = NULL; ++ if (w) *words = NULL; ++ return 0; ++} ++ ++inline int AffixMgr::candidate_check(const char * word, int len) ++{ ++ struct hentry * rv=NULL; ++ ++ rv = lookup(word); ++ if (rv) return 1; ++ ++// rv = prefix_check(word,len,1); ++// if (rv) return 1; ++ ++ rv = affix_check(word,len); ++ if (rv) return 1; ++ return 0; ++} ++ ++// calculate number of syllable for compound-checking ++short AffixMgr::get_syllable(const char * word, int wlen) ++{ ++ if (cpdmaxsyllable==0) return 0; ++ ++ short num=0; ++ ++ if (!utf8) { ++ for (int i=0; i 0; i--) { ++ if (flag_bsearch((unsigned short *) cpdvowels_utf16, ++ ((unsigned short *) w)[i - 1], cpdvowels_utf16_len)) num++; ++ } ++ } ++ return num; ++} ++ ++// check if compound word is correctly spelled ++// hu_mov_rule = spec. Hungarian rule (XXX) ++struct hentry * AffixMgr::compound_check(const char * word, int len, ++ short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words = NULL, ++ char hu_mov_rule = 0, int * cmpdstemnum = NULL, int * cmpdstem = NULL, char is_sug = 0) ++{ ++ int i; ++ short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; ++ int oldcmpdstemnum = 0; ++ struct hentry * rv = NULL; ++ struct hentry * rv_first; ++ struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking ++ char st [MAXWORDUTF8LEN + 4]; ++ char ch; ++ int cmin; ++ int cmax; ++ ++ int checked_prefix; ++ ++#ifdef HUNSTEM ++ if (cmpdstemnum) { ++ if (wordnum == 0) { ++ *cmpdstemnum = 1; ++ } else { ++ (*cmpdstemnum)++; ++ } ++ } ++#endif ++ if (utf8) { ++ for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) { ++ cmin++; ++ for (; (word[cmin] & 0xc0) == 0x80; cmin++); ++ } ++ for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) { ++ cmax--; ++ for (; (word[cmax] & 0xc0) == 0x80; cmax--); ++ } ++ } else { ++ cmin = cpdmin; ++ cmax = len - cpdmin + 1; ++ } ++ ++ strcpy(st, word); ++ ++ for (i = cmin; i < cmax; i++) { ++ ++ oldnumsyllable = numsyllable; ++ oldwordnum = wordnum; ++ checked_prefix = 0; ++ ++ // go to end of the UTF-8 character ++ if (utf8) { ++ for (; (st[i] & 0xc0) == 0x80; i++); ++ if (i >= cmax) return NULL; ++ } ++ ++ ++ ch = st[i]; ++ st[i] = '\0'; ++ ++ sfx = NULL; ++ pfx = NULL; ++ ++ // FIRST WORD ++ ++ rv = lookup(st); // perhaps without prefix ++ ++ // search homonym with compound flag ++ while ((rv) && !hu_mov_rule && ++ ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || ++ !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundbegin && !wordnum && ++ TESTAFF(rv->astr, compoundbegin, rv->alen)) || ++ (compoundmiddle && wordnum && !words && ++ TESTAFF(rv->astr, compoundmiddle, rv->alen)) || ++ (numdefcpd && ++ ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) || ++ (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)))) ++ ))) { ++ rv = rv->next_homonym; ++ } ++ ++ if (!rv) { ++ if (compoundflag && ++ !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { ++ if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, ++ FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule && ++ ((SfxEntry*)sfx)->getCont() && ++ ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())) || (compoundend && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ } ++ if (rv || ++ (((wordnum == 0) && compoundbegin && ++ ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || ++ (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || ++ ((wordnum > 0) && compoundmiddle && ++ ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || ++ (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle))))) ++ ) checked_prefix = 1; ++ // else check forbiddenwords and pseudoroot ++ } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) || ++ TESTAFF(rv->astr, pseudoroot, rv->alen) || ++ (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)) ++ )) { ++ st[i] = ch; ++ continue; ++ } ++ ++ // check non_compound flag in suffix and prefix ++ if ((rv) && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check compoundend flag in suffix and prefix ++ if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check compoundmiddle flag in suffix and prefix ++ if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || ++ (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) { ++ return NULL; ++ } ++ ++ // increment word number, if the second root has a compoundroot flag ++ if ((rv) && compoundroot && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ ++ // first word is acceptable in compound words? ++ if (((rv) && ++ ( checked_prefix || (words && words[wnum]) || ++ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) || ++ ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))// || ++// (numdefcpd && ) ++ ++// LANG_hu section: spec. Hungarian rule ++ || ((langnum == LANG_hu) && hu_mov_rule && ( ++ TESTAFF(rv->astr, 'F', rv->alen) || // XXX hardwired Hungarian dictionary codes ++ TESTAFF(rv->astr, 'G', rv->alen) || ++ TESTAFF(rv->astr, 'H', rv->alen) ++ ) ++ ) ++// END of LANG_hu section ++ ) ++ && ! (( checkcompoundtriple && // test triple letters ++ (word[i-1]==word[i]) && ( ++ ((i>1) && (word[i-1]==word[i-2])) || ++ ((word[i-1]==word[i+1])) // may be word[i+1] == '\0' ++ ) ++ ) || ++ ( ++ // test CHECKCOMPOUNDPATTERN ++ numcheckcpd && cpdpat_check(word, i) ++ ) || ++ ( ++ checkcompoundcase && cpdcase_check(word, i) ++ )) ++ ) ++// LANG_hu section: spec. Hungarian rule ++ || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) && ++ (sfx && ((SfxEntry*)sfx)->getCont() && ( // XXX hardwired Hungarian dic. codes ++ TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) || ++ TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen()) ++ ) ++ ) ++ ) ++// END of LANG_hu section ++ ) { ++ ++// LANG_hu section: spec. Hungarian rule ++ if (langnum == LANG_hu) { ++ // calculate syllable number of the word ++ numsyllable += get_syllable(st, i); ++ ++ // + 1 word, if syllable number of the prefix > 1 (hungarian convention) ++ if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; ++ } ++// END of LANG_hu section ++ ++#ifdef HUNSTEM ++ if (cmpdstem) cmpdstem[*cmpdstemnum - 1] = i; ++#endif ++ ++ // NEXT WORD(S) ++ rv_first = rv; ++ rv = lookup((word+i)); // perhaps without prefix ++ ++ // search homonym with compound flag ++ while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || ++ !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) || ++ (numdefcpd && words && defcpd_check(&words, wnum + 1, rv, NULL,1))))) { ++ rv = rv->next_homonym; ++ } ++ ++ if (rv && words && words[wnum + 1]) return rv; ++ ++ oldnumsyllable2 = numsyllable; ++ oldwordnum2 = wordnum; ++ ++// LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary code ++ if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) { ++ numsyllable--; ++ } ++// END of LANG_hu section ++ ++ // increment word number, if the second root has a compoundroot flag ++ if ((rv) && (compoundroot) && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || ++ (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL; ++ ++ // second word is acceptable, as a root? ++ // hungarian conventions: compounding is acceptable, ++ // when compound forms consist of 2 words, or if more, ++ // then the syllable number of root words must be 6, or lesser. ++ ++ if ((rv) && ( ++ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundend && TESTAFF(rv->astr, compoundend, rv->alen)) ++ ) ++ && ( ++ ((cpdwordmax==-1) || (wordnum+1word), rv->clen)<=cpdmaxsyllable)) ++ ) ++ && ( ++ (!checkcompounddup || (rv != rv_first)) ++ ) ++ ) ++ { ++ // forbid compound word, if it is a non compound word with typical fault ++ if (checkcompoundrep && cpdrep_check(word,len)) return NULL; ++ return rv; ++ } ++ ++ numsyllable = oldnumsyllable2 ; ++ wordnum = oldwordnum2; ++ ++ // perhaps second word has prefix or/and suffix ++ sfx = NULL; ++ sfxflag = FLAG_NULL; ++ rv = (compoundflag) ? affix_check((word+i),strlen(word+i), compoundflag, IN_CPD_END) : NULL; ++ if (!rv && compoundend) { ++ sfx = NULL; ++ pfx = NULL; ++ rv = affix_check((word+i),strlen(word+i), compoundend, IN_CPD_END); ++ } ++ ++ if (!rv && numdefcpd && words) { ++ rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END); ++ if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1)) return rv; ++ rv = NULL; ++ } ++ ++ // check non_compound flag in suffix and prefix ++ if ((rv) && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || ++ (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL; ++ ++ // pfxappnd = prefix of word+i, or NULL ++ // calculate syllable number of prefix. ++ // hungarian convention: when syllable number of prefix is more, ++ // than 1, the prefix+word counts as two words. ++ ++ if (langnum == LANG_hu) { ++ // calculate syllable number of the word ++ numsyllable += get_syllable(word + i, strlen(word + i)); ++ ++ // - affix syllable num. ++ // XXX only second suffix (inflections, not derivations) ++ if (sfxappnd) { ++ char * tmp = myrevstrdup(sfxappnd); ++ numsyllable -= get_syllable(tmp, strlen(tmp)); ++ free(tmp); ++ } ++ ++ // + 1 word, if syllable number of the prefix > 1 (hungarian convention) ++ if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; ++ ++ // increment syllable num, if last word has a SYLLABLENUM flag ++ // and the suffix is beginning `s' ++ ++ if (cpdsyllablenum) { ++ switch (sfxflag) { ++ case 'c': { numsyllable+=2; break; } ++ case 'J': { numsyllable += 1; break; } ++ case 'I': { if (TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; } ++ } ++ } ++ } ++ ++ // increment word number, if the second word has a compoundroot flag ++ if ((rv) && (compoundroot) && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ ++ // second word is acceptable, as a word with prefix or/and suffix? ++ // hungarian conventions: compounding is acceptable, ++ // when compound forms consist 2 word, otherwise ++ // the syllable number of root words is 6, or lesser. ++ if ((rv) && ++ ( ++ ((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) || ++ ((cpdmaxsyllable == 0) || ++ (numsyllable <= cpdmaxsyllable)) ++ ) ++ && ( ++ (!checkcompounddup || (rv != rv_first)) ++ )) { ++ // forbid compound word, if it is a non compound word with typical fault ++ if (checkcompoundrep && cpdrep_check(word, len)) return NULL; ++ return rv; ++ } ++ ++ numsyllable = oldnumsyllable2; ++ wordnum = oldwordnum2; ++#ifdef HUNSTEM ++ if (cmpdstemnum) oldcmpdstemnum = *cmpdstemnum; ++#endif ++ // perhaps second word is a compound word (recursive call) ++ if (wordnum < maxwordnum) { ++ rv = compound_check((word+i),strlen(word+i), wordnum+1, ++ numsyllable, maxwordnum, wnum + 1, words, ++ 0, cmpdstemnum, cmpdstem, is_sug); ++ } else { ++ rv=NULL; ++ } ++ if (rv) { ++ // forbid compound word, if it is a non compound word with typical fault ++ if (checkcompoundrep && cpdrep_check(word, len)) return NULL; ++ return rv; ++ } else { ++#ifdef HUNSTEM ++ if (cmpdstemnum) *cmpdstemnum = oldcmpdstemnum; ++#endif ++ } ++ } ++ st[i] = ch; ++ wordnum = oldwordnum; ++ numsyllable = oldnumsyllable; ++ } ++ ++ return NULL; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// check if compound word is correctly spelled ++// hu_mov_rule = spec. Hungarian rule (XXX) ++int AffixMgr::compound_check_morph(const char * word, int len, ++ short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, ++ char hu_mov_rule = 0, char ** result = NULL, char * partresult = NULL) ++{ ++ int i; ++ short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; ++ int ok = 0; ++ ++ struct hentry * rv = NULL; ++ struct hentry * rv_first; ++ struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking ++ char st [MAXWORDUTF8LEN + 4]; ++ char ch; ++ ++ int checked_prefix; ++ char presult[MAXLNLEN]; ++ ++ int cmin; ++ int cmax; ++ ++ if (utf8) { ++ for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) { ++ cmin++; ++ for (; (word[cmin] & 0xc0) == 0x80; cmin++); ++ } ++ for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) { ++ cmax--; ++ for (; (word[cmax] & 0xc0) == 0x80; cmax--); ++ } ++ } else { ++ cmin = cpdmin; ++ cmax = len - cpdmin + 1; ++ } ++ ++ strcpy(st, word); ++ ++ for (i = cmin; i < cmax; i++) { ++ oldnumsyllable = numsyllable; ++ oldwordnum = wordnum; ++ checked_prefix = 0; ++ ++ // go to end of the UTF-8 character ++ if (utf8) { ++ for (; (st[i] & 0xc0) == 0x80; i++); ++ if (i >= cmax) return 0; ++ } ++ ++ ch = st[i]; ++ st[i] = '\0'; ++ sfx = NULL; ++ ++ // FIRST WORD ++ *presult = '\0'; ++ if (partresult) strcat(presult, partresult); ++ ++ rv = lookup(st); // perhaps without prefix ++ ++ // search homonym with compound flag ++ while ((rv) && !hu_mov_rule && ++ ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || ++ !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundbegin && !wordnum && ++ TESTAFF(rv->astr, compoundbegin, rv->alen)) || ++ (compoundmiddle && wordnum && !words && ++ TESTAFF(rv->astr, compoundmiddle, rv->alen)) || ++ (numdefcpd && ++ ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) || ++ (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)))) ++ ))) { ++ rv = rv->next_homonym; ++ } ++ ++ if (rv) { ++ if (rv->description) { ++ if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen)) ++ strcat(presult, st); ++ strcat(presult, rv->description); ++ } ++ } ++ ++ if (!rv) { ++ if (compoundflag && ++ !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { ++ if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, ++ FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule && ++ ((SfxEntry*)sfx)->getCont() && ++ ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())) || (compoundend && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ } ++ ++ if (rv || ++ (((wordnum == 0) && compoundbegin && ++ ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || ++ (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || ++ ((wordnum > 0) && compoundmiddle && ++ ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || ++ (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle))))) ++ ) { ++ //char * p = prefix_check_morph(st, i, 0, compound); ++ char * p = NULL; ++ if (compoundflag) p = affix_check_morph(st, i, compoundflag); ++ if (!p || (*p == '\0')) { ++ if ((wordnum == 0) && compoundbegin) { ++ p = affix_check_morph(st, i, compoundbegin); ++ } else if ((wordnum > 0) && compoundmiddle) { ++ p = affix_check_morph(st, i, compoundmiddle); ++ } ++ } ++ if (*p != '\0') { ++ line_uniq(p); ++ if (strchr(p, '\n')) { ++ strcat(presult, "("); ++ strcat(presult, line_join(p, '|')); ++ strcat(presult, ")"); ++ } else { ++ strcat(presult, p); ++ } ++ } ++ if (presult[strlen(presult) - 1] == '\n') { ++ presult[strlen(presult) - 1] = '\0'; ++ } ++ checked_prefix = 1; ++ //strcat(presult, "+"); ++ } ++ // else check forbiddenwords ++ } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) || ++ TESTAFF(rv->astr, pseudoroot, rv->alen))) { ++ st[i] = ch; ++ continue; ++ } ++ ++ // check non_compound flag in suffix and prefix ++ if ((rv) && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ continue; ++ } ++ ++ // check compoundend flag in suffix and prefix ++ if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ continue; ++ } ++ ++ // check compoundmiddle flag in suffix and prefix ++ if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) continue; ++ ++ // increment word number, if the second root has a compoundroot flag ++ if ((rv) && (compoundroot) && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ ++ // first word is acceptable in compound words? ++ if (((rv) && ++ ( checked_prefix || (words && words[wnum]) || ++ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) || ++ ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen)) ++// LANG_hu section: spec. Hungarian rule ++ || ((langnum == LANG_hu) && // hu_mov_rule ++ hu_mov_rule && ( ++ TESTAFF(rv->astr, 'F', rv->alen) || ++ TESTAFF(rv->astr, 'G', rv->alen) || ++ TESTAFF(rv->astr, 'H', rv->alen) ++ ) ++ ) ++// END of LANG_hu section ++ ) ++ && ! (( checkcompoundtriple && // test triple letters ++ (word[i-1]==word[i]) && ( ++ ((i>1) && (word[i-1]==word[i-2])) || ++ ((word[i-1]==word[i+1])) // may be word[i+1] == '\0' ++ ) ++ ) || ++ ( ++ // test CHECKCOMPOUNDPATTERN ++ numcheckcpd && cpdpat_check(word, i) ++ ) || ++ ( ++ checkcompoundcase && cpdcase_check(word, i) ++ )) ++ ) ++// LANG_hu section: spec. Hungarian rule ++ || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) && ++ (sfx && ((SfxEntry*)sfx)->getCont() && ( ++ TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) || ++ TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen()) ++ ) ++ ) ++ ) ++// END of LANG_hu section ++ ) { ++ ++// LANG_hu section: spec. Hungarian rule ++ if (langnum == LANG_hu) { ++ // calculate syllable number of the word ++ numsyllable += get_syllable(st, i); ++ ++ // + 1 word, if syllable number of the prefix > 1 (hungarian convention) ++ if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; ++ } ++// END of LANG_hu section ++ ++ // NEXT WORD(S) ++ rv_first = rv; ++ rv = lookup((word+i)); // perhaps without prefix ++ ++ // search homonym with compound flag ++ while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || ++ !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) || ++ (numdefcpd && defcpd_check(&words, wnum + 1, rv, NULL,1))))) { ++ rv = rv->next_homonym; ++ } ++ ++ if (rv && words && words[wnum + 1]) { ++ strcat(*result, presult); ++ if (complexprefixes && rv->description) strcat(*result, rv->description); ++ if (rv->description && ((!rv->astr) || ++ !TESTAFF(rv->astr, lemma_present, rv->alen))) ++ strcat(*result, &(rv->word)); ++ if (!complexprefixes && rv->description) strcat(*result, rv->description); ++ strcat(*result, "\n"); ++ ok = 1; ++ return 0; ++ } ++ ++ oldnumsyllable2 = numsyllable; ++ oldwordnum2 = wordnum; ++ ++// LANG_hu section: spec. Hungarian rule ++ if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) { ++ numsyllable--; ++ } ++// END of LANG_hu section ++ // increment word number, if the second root has a compoundroot flag ++ if ((rv) && (compoundroot) && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) { ++ st[i] = ch; ++ continue; ++ } ++ ++ // second word is acceptable, as a root? ++ // hungarian conventions: compounding is acceptable, ++ // when compound forms consist of 2 words, or if more, ++ // then the syllable number of root words must be 6, or lesser. ++ if ((rv) && ( ++ (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || ++ (compoundend && TESTAFF(rv->astr, compoundend, rv->alen)) ++ ) ++ && ( ++ ((cpdwordmax==-1) || (wordnum+1word),rv->wlen)<=cpdmaxsyllable)) ++ ) ++ && ( ++ (!checkcompounddup || (rv != rv_first)) ++ ) ++ ) ++ { ++ // bad compound word ++ strcat(*result, presult); ++ ++ if (rv->description) { ++ if (complexprefixes) strcat(*result, rv->description); ++ if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen)) ++ strcat(*result, &(rv->word)); ++ if (!complexprefixes) strcat(*result, rv->description); ++ } ++ strcat(*result, "\n"); ++ ok = 1; ++ } ++ ++ numsyllable = oldnumsyllable2 ; ++ wordnum = oldwordnum2; ++ ++ // perhaps second word has prefix or/and suffix ++ sfx = NULL; ++ sfxflag = FLAG_NULL; ++ ++ if (compoundflag) rv = affix_check((word+i),strlen(word+i), compoundflag); else rv = NULL; ++ ++ if (!rv && compoundend) { ++ sfx = NULL; ++ pfx = NULL; ++ rv = affix_check((word+i),strlen(word+i), compoundend); ++ } ++ ++ if (!rv && numdefcpd && words) { ++ rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END); ++ if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) { ++ char * m = NULL; ++ if (compoundflag) m = affix_check_morph((word+i),strlen(word+i), compoundflag); ++ if ((!m || *m == '\0') && compoundend) ++ m = affix_check_morph((word+i),strlen(word+i), compoundend); ++ strcat(*result, presult); ++ if (m) { ++ line_uniq(m); ++ if (strchr(m, '\n')) { ++ strcat(*result, "("); ++ strcat(*result, line_join(m, '|')); ++ strcat(*result, ")"); ++ } else { ++ strcat(*result, m); ++ } ++ free(m); ++ } ++ strcat(*result, "\n"); ++ ok = 1; ++ } ++ } ++ ++ // check non_compound flag in suffix and prefix ++ if ((rv) && ++ ((pfx && ((PfxEntry*)pfx)->getCont() && ++ TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, ++ ((PfxEntry*)pfx)->getContLen())) || ++ (sfx && ((SfxEntry*)sfx)->getCont() && ++ TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, ++ ((SfxEntry*)sfx)->getContLen())))) { ++ rv = NULL; ++ } ++ ++ // check forbiddenwords ++ if ((rv) && (rv->astr) && (TESTAFF(rv->astr,forbiddenword,rv->alen)) ++ && (! TESTAFF(rv->astr, pseudoroot, rv->alen))) { ++ st[i] = ch; ++ continue; ++ } ++ ++ if (langnum == LANG_hu) { ++ // calculate syllable number of the word ++ numsyllable += get_syllable(word + i, strlen(word + i)); ++ ++ // - affix syllable num. ++ // XXX only second suffix (inflections, not derivations) ++ if (sfxappnd) { ++ char * tmp = myrevstrdup(sfxappnd); ++ numsyllable -= get_syllable(tmp, strlen(tmp)); ++ free(tmp); ++ } ++ ++ // + 1 word, if syllable number of the prefix > 1 (hungarian convention) ++ if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; ++ ++ // increment syllable num, if last word has a SYLLABLENUM flag ++ // and the suffix is beginning `s' ++ ++ if (cpdsyllablenum) { ++ switch (sfxflag) { ++ case 'c': { numsyllable+=2; break; } ++ case 'J': { numsyllable += 1; break; } ++ case 'I': { if (rv && TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; } ++ } ++ } ++ } ++ ++ // increment word number, if the second word has a compoundroot flag ++ if ((rv) && (compoundroot) && ++ (TESTAFF(rv->astr, compoundroot, rv->alen))) { ++ wordnum++; ++ } ++ // second word is acceptable, as a word with prefix or/and suffix? ++ // hungarian conventions: compounding is acceptable, ++ // when compound forms consist 2 word, otherwise ++ // the syllable number of root words is 6, or lesser. ++ if ((rv) && ++ ( ++ ((cpdwordmax==-1) || (wordnum+1 0) && *s1 && (*s1 == *end_of_s2)) { ++ s1++; ++ end_of_s2--; ++ len--; ++ } ++ return (*s1 == '\0'); ++ } ++ */ ++ ++inline int AffixMgr::isRevSubset(const char * s1, const char * end_of_s2, int len) ++ { ++ while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) { ++ s1++; ++ end_of_s2--; ++ len--; ++ } ++ return (*s1 == '\0'); ++ } ++ ++// check word for suffixes ++ ++struct hentry * AffixMgr::suffix_check (const char * word, int len, ++ int sfxopts, AffEntry * ppfx, char ** wlst, int maxSug, int * ns, ++ const FLAG cclass, const FLAG needflag, char in_compound) ++{ ++ struct hentry * rv = NULL; ++ char result[MAXLNLEN]; ++ ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ ++ // first handle the special case of 0 length suffixes ++ SfxEntry * se = (SfxEntry *) sStart[0]; ++ ++ while (se) { ++ if (!cclass || se->getCont()) { ++ // suffixes are not allowed in beginning of compounds ++ if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass ++ // except when signed with compoundpermitflag flag ++ (se->getCont() && compoundpermitflag && ++ TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix || ++ // no circumfix flag in prefix and suffix ++ ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) || ++ // circumfix flag in prefix AND suffix ++ ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) && ++ // fogemorpheme ++ (in_compound || ++ !((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) && ++ // pseudoroot on prefix or first suffix ++ (cclass || ++ !(se->getCont() && TESTAFF(se->getCont(), pseudoroot, se->getContLen())) || ++ (ppfx && !((ep->getCont()) && ++ TESTAFF(ep->getCont(), pseudoroot, ++ ep->getContLen()))) ++ ) ++ ) { ++ rv = se->checkword(word,len, sfxopts, ppfx, wlst, maxSug, ns, (FLAG) cclass, ++ needflag, (in_compound ? 0 : onlyincompound)); ++ if (rv) { ++ sfx=(AffEntry *)se; // BUG: sfx not stateless ++ return rv; ++ } ++ } ++ } ++ se = se->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)(word + len - 1)); ++ SfxEntry * sptr = (SfxEntry *) sStart[sp]; ++ ++ while (sptr) { ++ if (isRevSubset(sptr->getKey(), word + len - 1, len) ++ ) { ++ // suffixes are not allowed in beginning of compounds ++ if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass ++ // except when signed with compoundpermitflag flag ++ (sptr->getCont() && compoundpermitflag && ++ TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix || ++ // no circumfix flag in prefix and suffix ++ ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) || ++ // circumfix flag in prefix AND suffix ++ ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) && ++ // fogemorpheme ++ (in_compound || ++ !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) && ++ // pseudoroot on prefix or first suffix ++ (cclass || ++ !(sptr->getCont() && TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen())) || ++ (ppfx && !((ep->getCont()) && ++ TESTAFF(ep->getCont(), pseudoroot, ++ ep->getContLen()))) ++ ) ++ ) { ++ rv = sptr->checkword(word,len, sfxopts, ppfx, wlst, ++ maxSug, ns, cclass, needflag, (in_compound ? 0 : onlyincompound)); ++ if (rv) { ++ sfx=(AffEntry *)sptr; // BUG: sfx not stateless ++ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless ++ if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless ++ if (cclass || sptr->getCont()) { ++ if (!derived) { ++ derived = mystrdup(word); ++ } else { ++ strcpy(result, derived); // XXX check size ++ strcat(result, "\n"); ++ strcat(result, word); ++ free(derived); ++ derived = mystrdup(result); ++ } ++ } ++ return rv; ++ } ++ } ++ sptr = sptr->getNextEQ(); ++ } else { ++ sptr = sptr->getNextNE(); ++ } ++ } ++ ++ return NULL; ++} ++ ++// check word for two-level suffixes ++ ++struct hentry * AffixMgr::suffix_check_twosfx(const char * word, int len, ++ int sfxopts, AffEntry * ppfx, const FLAG needflag) ++{ ++ struct hentry * rv = NULL; ++ ++ // first handle the special case of 0 length suffixes ++ SfxEntry * se = (SfxEntry *) sStart[0]; ++ while (se) { ++ if (contclasses[se->getFlag()]) ++ { ++ rv = se->check_twosfx(word,len, sfxopts, ppfx, needflag); ++ if (rv) return rv; ++ } ++ se = se->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)(word + len - 1)); ++ SfxEntry * sptr = (SfxEntry *) sStart[sp]; ++ ++ while (sptr) { ++ if (isRevSubset(sptr->getKey(), word + len - 1, len)) { ++ if (contclasses[sptr->getFlag()]) ++ { ++ rv = sptr->check_twosfx(word,len, sfxopts, ppfx, needflag); ++ if (rv) { ++ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless ++ if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless ++ return rv; ++ } ++ } ++ sptr = sptr->getNextEQ(); ++ } else { ++ sptr = sptr->getNextNE(); ++ } ++ } ++ ++ return NULL; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++char * AffixMgr::suffix_check_twosfx_morph(const char * word, int len, ++ int sfxopts, AffEntry * ppfx, const FLAG needflag) ++{ ++ char result[MAXLNLEN]; ++ char result2[MAXLNLEN]; ++ char result3[MAXLNLEN]; ++ ++ char * st; ++ ++ result[0] = '\0'; ++ result2[0] = '\0'; ++ result3[0] = '\0'; ++ ++ // first handle the special case of 0 length suffixes ++ SfxEntry * se = (SfxEntry *) sStart[0]; ++ while (se) { ++ if (contclasses[se->getFlag()]) ++ { ++ st = se->check_twosfx_morph(word,len, sfxopts, ppfx, needflag); ++ if (st) { ++ if (ppfx) { ++ if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); ++ } ++ strcat(result, st); ++ free(st); ++ if (se->getMorph()) strcat(result, se->getMorph()); ++ strcat(result, "\n"); ++ } ++ } ++ se = se->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)(word + len - 1)); ++ SfxEntry * sptr = (SfxEntry *) sStart[sp]; ++ ++ while (sptr) { ++ if (isRevSubset(sptr->getKey(), word + len - 1, len)) { ++ if (contclasses[sptr->getFlag()]) ++ { ++ st = sptr->check_twosfx_morph(word,len, sfxopts, ppfx, needflag); ++ if (st) { ++ sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless ++ if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless ++ strcpy(result2, st); ++ free(st); ++ ++ result3[0] = '\0'; ++#ifdef DEBUG ++ unsigned short flag = sptr->getFlag(); ++ if (flag_mode == FLAG_NUM) { ++ sprintf(result3, "<%d>", sptr->getKey()); ++ } else if (flag_mode == FLAG_LONG) { ++ sprintf(result3, "<%c%c>", flag >> 8, (flag << 8) >>8); ++ } else sprintf(result3, "<%c>", flag); ++ strcat(result3, ":"); ++#endif ++ if (sptr->getMorph()) strcat(result3, sptr->getMorph()); ++ strlinecat(result2, result3); ++ strcat(result2, "\n"); ++ strcat(result, result2); ++ } ++ } ++ sptr = sptr->getNextEQ(); ++ } else { ++ sptr = sptr->getNextNE(); ++ } ++ } ++ if (result) return mystrdup(result); ++ return NULL; ++} ++ ++char * AffixMgr::suffix_check_morph(const char * word, int len, ++ int sfxopts, AffEntry * ppfx, const FLAG cclass, const FLAG needflag, char in_compound) ++{ ++ char result[MAXLNLEN]; ++ ++ struct hentry * rv = NULL; ++ ++ result[0] = '\0'; ++ ++ PfxEntry* ep = (PfxEntry *) ppfx; ++ ++ // first handle the special case of 0 length suffixes ++ SfxEntry * se = (SfxEntry *) sStart[0]; ++ while (se) { ++ if (!cclass || se->getCont()) { ++ // suffixes are not allowed in beginning of compounds ++ if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass ++ // except when signed with compoundpermitflag flag ++ (se->getCont() && compoundpermitflag && ++ TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix || ++ // no circumfix flag in prefix and suffix ++ ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) || ++ // circumfix flag in prefix AND suffix ++ ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) && ++ // fogemorpheme ++ (in_compound || ++ !((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) && ++ // pseudoroot on prefix or first suffix ++ (cclass || ++ !(se->getCont() && TESTAFF(se->getCont(), pseudoroot, se->getContLen())) || ++ (ppfx && !((ep->getCont()) && ++ TESTAFF(ep->getCont(), pseudoroot, ++ ep->getContLen()))) ++ ) ++ )) ++ rv = se->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag); ++ while (rv) { ++ if (ppfx) { ++ if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); ++ } ++ if (complexprefixes && rv->description) strcat(result, rv->description); ++ if (rv->description && ((!rv->astr) || ++ !TESTAFF(rv->astr, lemma_present, rv->alen))) ++ strcat(result, &(rv->word)); ++ if (!complexprefixes && rv->description) strcat(result, rv->description); ++ if (se->getMorph()) strcat(result, se->getMorph()); ++ strcat(result, "\n"); ++ rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); ++ } ++ } ++ se = se->getNext(); ++ } ++ ++ // now handle the general case ++ unsigned char sp = *((const unsigned char *)(word + len - 1)); ++ SfxEntry * sptr = (SfxEntry *) sStart[sp]; ++ ++ while (sptr) { ++ if (isRevSubset(sptr->getKey(), word + len - 1, len) ++ ) { ++ // suffixes are not allowed in beginning of compounds ++ if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass ++ // except when signed with compoundpermitflag flag ++ (sptr->getCont() && compoundpermitflag && ++ TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix || ++ // no circumfix flag in prefix and suffix ++ ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) || ++ // circumfix flag in prefix AND suffix ++ ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), ++ circumfix, ep->getContLen())) && ++ (sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) && ++ // fogemorpheme ++ (in_compound || ++ !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) && ++ // pseudoroot on first suffix ++ (cclass || !(sptr->getCont() && ++ TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen()))) ++ )) rv = sptr->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag); ++ while (rv) { ++ if (ppfx) { ++ if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); ++ } ++ if (complexprefixes && rv->description) strcat(result, rv->description); ++ if (rv->description && ((!rv->astr) || ++ !TESTAFF(rv->astr, lemma_present, rv->alen))) strcat(result, &(rv->word)); ++ if (!complexprefixes && rv->description) strcat(result, rv->description); ++#ifdef DEBUG ++ unsigned short flag = sptr->getFlag(); ++ if (flag_mode == FLAG_NUM) { ++ sprintf(result, "<%d>", sptr->getKey()); ++ } else if (flag_mode == FLAG_LONG) { ++ sprintf(result, "<%c%c>", flag >> 8, (flag << 8) >>8); ++ } else sprintf(result, "<%c>", flag); ++ strcat(result, ":"); ++#endif ++ ++ if (sptr->getMorph()) strcat(result, sptr->getMorph()); ++ strcat(result, "\n"); ++ rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); ++ } ++ sptr = sptr->getNextEQ(); ++ } else { ++ sptr = sptr->getNextNE(); ++ } ++ } ++ ++ if (*result) return mystrdup(result); ++ return NULL; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++ ++// check if word with affixes is correctly spelled ++struct hentry * AffixMgr::affix_check (const char * word, int len, const FLAG needflag, char in_compound) ++{ ++ struct hentry * rv= NULL; ++ if (derived) free(derived); ++ derived = NULL; ++ ++ // check all prefixes (also crossed with suffixes if allowed) ++ rv = prefix_check(word, len, in_compound, needflag); ++ if (rv) return rv; ++ ++ // if still not found check all suffixes ++ rv = suffix_check(word, len, 0, NULL, NULL, 0, NULL, FLAG_NULL, needflag, in_compound); ++ ++ if (havecontclass) { ++ sfx = NULL; ++ pfx = NULL; ++ if (rv) return rv; ++ // if still not found check all two-level suffixes ++ rv = suffix_check_twosfx(word, len, 0, NULL, needflag); ++ if (rv) return rv; ++ // if still not found check all two-level suffixes ++ rv = prefix_check_twosfx(word, len, IN_CPD_NOT, needflag); ++ } ++ return rv; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// check if word with affixes is correctly spelled ++char * AffixMgr::affix_check_morph(const char * word, int len, const FLAG needflag, char in_compound) ++{ ++ char result[MAXLNLEN]; ++ char * st = NULL; ++ ++ *result = '\0'; ++ ++ // check all prefixes (also crossed with suffixes if allowed) ++ st = prefix_check_morph(word, len, in_compound); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ ++ // if still not found check all suffixes ++ st = suffix_check_morph(word, len, 0, NULL, '\0', needflag, in_compound); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ ++ if (havecontclass) { ++ sfx = NULL; ++ pfx = NULL; ++ // if still not found check all two-level suffixes ++ st = suffix_check_twosfx_morph(word, len, 0, NULL, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ ++ // if still not found check all two-level suffixes ++ st = prefix_check_twosfx_morph(word, len, IN_CPD_NOT, needflag); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ } ++ ++ return mystrdup(result); ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++ ++int AffixMgr::expand_rootword(struct guessword * wlst, int maxn, const char * ts, ++ int wl, const unsigned short * ap, unsigned short al, char * bad, int badl, ++ char * phone) ++{ ++ ++ int nh=0; ++ // first add root word to list ++ if ((nh < maxn) && !(al && ((pseudoroot && TESTAFF(ap, pseudoroot, al)) || ++ (onlyincompound && TESTAFF(ap, onlyincompound, al))))) { ++ wlst[nh].word = mystrdup(ts); ++ wlst[nh].allow = (1 == 0); ++ wlst[nh].orig = NULL; ++ nh++; ++ // add special phonetic version ++ if (phone && (nh < maxn)) { ++ wlst[nh].word = mystrdup(phone); ++ wlst[nh].allow = (1 == 0); ++ wlst[nh].orig = mystrdup(ts); ++ nh++; ++ } ++ } ++ ++ // handle suffixes ++ for (int i = 0; i < al; i++) { ++ const unsigned char c = (unsigned char) (ap[i] & 0x00FF); ++ SfxEntry * sptr = (SfxEntry *)sFlag[c]; ++ while (sptr) { ++ if ((sptr->getFlag() == ap[i]) && (!sptr->getKeyLen() || ((badl > sptr->getKeyLen()) && ++ (strcmp(sptr->getAffix(), bad + badl - sptr->getKeyLen()) == 0))) && ++ // check pseudoroot flag ++ !(sptr->getCont() && ((pseudoroot && ++ TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen())) || ++ (circumfix && ++ TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())) || ++ (onlyincompound && ++ TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen())))) ++ ) { ++ char * newword = sptr->add(ts, wl); ++ if (newword) { ++ if (nh < maxn) { ++ wlst[nh].word = newword; ++ wlst[nh].allow = sptr->allowCross(); ++ wlst[nh].orig = NULL; ++ nh++; ++ // add special phonetic version ++ if (phone && (nh < maxn)) { ++ char st[MAXWORDUTF8LEN]; ++ strcpy(st, phone); ++ strcat(st, sptr->getKey()); ++ reverseword(st + strlen(phone)); ++ wlst[nh].word = mystrdup(st); ++ wlst[nh].allow = (1 == 0); ++ wlst[nh].orig = mystrdup(newword); ++ nh++; ++ } ++ } else { ++ free(newword); ++ } ++ } ++ } ++ sptr = (SfxEntry *)sptr ->getFlgNxt(); ++ } ++ } ++ ++ int n = nh; ++ ++ // handle cross products of prefixes and suffixes ++ for (int j=1;jgetFlag() == ap[k]) && cptr->allowCross() && (!cptr->getKeyLen() || ((badl > cptr->getKeyLen()) && ++ (strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) { ++ int l1 = strlen(wlst[j].word); ++ char * newword = cptr->add(wlst[j].word, l1); ++ if (newword) { ++ if (nh < maxn) { ++ wlst[nh].word = newword; ++ wlst[nh].allow = cptr->allowCross(); ++ wlst[nh].orig = NULL; ++ nh++; ++ } else { ++ free(newword); ++ } ++ } ++ } ++ cptr = (PfxEntry *)cptr ->getFlgNxt(); ++ } ++ } ++ } ++ ++ ++ // now handle pure prefixes ++ for (int m = 0; m < al; m ++) { ++ const unsigned char c = (unsigned char) (ap[m] & 0x00FF); ++ PfxEntry * ptr = (PfxEntry *) pFlag[c]; ++ while (ptr) { ++ if ((ptr->getFlag() == ap[m]) && (!ptr->getKeyLen() || ((badl > ptr->getKeyLen()) && ++ (strncmp(ptr->getKey(), bad, ptr->getKeyLen()) == 0))) && ++ // check pseudoroot flag ++ !(ptr->getCont() && ((pseudoroot && ++ TESTAFF(ptr->getCont(), pseudoroot, ptr->getContLen())) || ++ (circumfix && ++ TESTAFF(ptr->getCont(), circumfix, ptr->getContLen())) || ++ (onlyincompound && ++ TESTAFF(ptr->getCont(), onlyincompound, ptr->getContLen())))) ++ ) { ++ char * newword = ptr->add(ts, wl); ++ if (newword) { ++ if (nh < maxn) { ++ wlst[nh].word = newword; ++ wlst[nh].allow = ptr->allowCross(); ++ wlst[nh].orig = NULL; ++ nh++; ++ } else { ++ free(newword); ++ } ++ } ++ } ++ ptr = (PfxEntry *)ptr ->getFlgNxt(); ++ } ++ } ++ ++ return nh; ++} ++ ++ ++ ++// return length of replacing table ++int AffixMgr::get_numrep() ++{ ++ return numrep; ++} ++ ++// return replacing table ++struct replentry * AffixMgr::get_reptable() ++{ ++ if (! reptable ) return NULL; ++ return reptable; ++} ++ ++// return replacing table ++struct phonetable * AffixMgr::get_phonetable() ++{ ++ if (! phone ) return NULL; ++ return phone; ++} ++ ++// return length of character map table ++int AffixMgr::get_nummap() ++{ ++ return nummap; ++} ++ ++// return character map table ++struct mapentry * AffixMgr::get_maptable() ++{ ++ if (! maptable ) return NULL; ++ return maptable; ++} ++ ++// return length of word break table ++int AffixMgr::get_numbreak() ++{ ++ return numbreak; ++} ++ ++// return character map table ++char ** AffixMgr::get_breaktable() ++{ ++ if (! breaktable ) return NULL; ++ return breaktable; ++} ++ ++// return text encoding of dictionary ++char * AffixMgr::get_encoding() ++{ ++ if (! encoding ) { ++ encoding = mystrdup("ISO8859-1"); ++ } ++ return mystrdup(encoding); ++} ++ ++// return text encoding of dictionary ++int AffixMgr::get_langnum() ++{ ++ return langnum; ++} ++ ++// return double prefix option ++int AffixMgr::get_complexprefixes() ++{ ++ return complexprefixes; ++} ++ ++FLAG AffixMgr::get_keepcase() ++{ ++ return keepcase; ++} ++ ++int AffixMgr::get_checksharps() ++{ ++ return checksharps; ++} ++ ++// return the preferred ignore string for suggestions ++char * AffixMgr::get_ignore() ++{ ++ if (!ignorechars) return NULL; ++ return ignorechars; ++} ++ ++// return the preferred ignore string for suggestions ++unsigned short * AffixMgr::get_ignore_utf16(int * len) ++{ ++ *len = ignorechars_utf16_len; ++ return ignorechars_utf16; ++} ++ ++// return the keyboard string for suggestions ++char * AffixMgr::get_key_string() ++{ ++ if (! keystring ) return NULL; ++ return mystrdup(keystring); ++} ++ ++// return the preferred try string for suggestions ++char * AffixMgr::get_try_string() ++{ ++ if (! trystring ) return NULL; ++ return mystrdup(trystring); ++} ++ ++// return the preferred try string for suggestions ++const char * AffixMgr::get_wordchars() ++{ ++ return wordchars; ++} ++ ++unsigned short * AffixMgr::get_wordchars_utf16(int * len) ++{ ++ *len = wordchars_utf16_len; ++ return wordchars_utf16; ++} ++ ++// is there compounding? ++int AffixMgr::get_compound() ++{ ++ return compoundflag || compoundbegin || numdefcpd; ++} ++ ++// return the compound words control flag ++FLAG AffixMgr::get_compoundflag() ++{ ++ return compoundflag; ++} ++ ++// return the forbidden words control flag ++FLAG AffixMgr::get_forbiddenword() ++{ ++ return forbiddenword; ++} ++ ++// return the forbidden words control flag ++FLAG AffixMgr::get_nosuggest() ++{ ++ return nosuggest; ++} ++ ++// return the forbidden words flag modify flag ++FLAG AffixMgr::get_pseudoroot() ++{ ++ return pseudoroot; ++} ++ ++// return the onlyincompound flag ++FLAG AffixMgr::get_onlyincompound() ++{ ++ return onlyincompound; ++} ++ ++// return the compound word signal flag ++FLAG AffixMgr::get_compoundroot() ++{ ++ return compoundroot; ++} ++ ++// return the compound begin signal flag ++FLAG AffixMgr::get_compoundbegin() ++{ ++ return compoundbegin; ++} ++ ++// return the value of checknum ++int AffixMgr::get_checknum() ++{ ++ return checknum; ++} ++ ++// return the value of prefix ++const char * AffixMgr::get_prefix() ++{ ++ if (pfx) return ((PfxEntry *)pfx)->getKey(); ++ return NULL; ++} ++ ++// return the value of suffix ++const char * AffixMgr::get_suffix() ++{ ++ return sfxappnd; ++} ++ ++// return the value of derived form (base word with first suffix). ++const char * AffixMgr::get_derived() ++{ ++ return derived; ++} ++ ++// return the value of suffix ++const char * AffixMgr::get_version() ++{ ++ return version; ++} ++ ++// return lemma_present flag ++FLAG AffixMgr::get_lemma_present() ++{ ++ return lemma_present; ++} ++ ++// utility method to look up root words in hash table ++struct hentry * AffixMgr::lookup(const char * word) ++{ ++ if (! pHMgr) return NULL; ++ return pHMgr->lookup(word); ++} ++ ++// return the value of suffix ++const int AffixMgr::have_contclass() ++{ ++ return havecontclass; ++} ++ ++// return utf8 ++int AffixMgr::get_utf8() ++{ ++ return utf8; ++} ++ ++// return nosplitsugs ++int AffixMgr::get_maxngramsugs(void) ++{ ++ return maxngramsugs; ++} ++ ++// return nosplitsugs ++int AffixMgr::get_nosplitsugs(void) ++{ ++ return nosplitsugs; ++} ++ ++// return sugswithdots ++int AffixMgr::get_sugswithdots(void) ++{ ++ return sugswithdots; ++} ++ ++/* parse flag */ ++int AffixMgr::parse_flag(char * line, unsigned short * out, const char * name) { ++ char * s = NULL; ++ if (*out != FLAG_NULL) { ++ HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name); ++ return 1; ++ } ++ if (parse_string(line, &s, name)) return 1; ++ *out = pHMgr->decode_flag(s); ++ free(s); ++ return 0; ++} ++ ++/* parse num */ ++int AffixMgr::parse_num(char * line, int * out, const char * name) { ++ char * s = NULL; ++ if (*out != -1) { ++ HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name); ++ return 1; ++ } ++ if (parse_string(line, &s, name)) return 1; ++ *out = atoi(s); ++ free(s); ++ return 0; ++} ++ ++/* parse in the max syllablecount of compound words and */ ++int AffixMgr::parse_cpdsyllable(char * line) ++{ ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ w_char w[MAXWORDLEN]; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { cpdmaxsyllable = atoi(piece); np++; break; } ++ case 2: { ++ if (!utf8) { ++ cpdvowels = mystrdup(piece); ++ } else { ++ int n = u8_u16(w, MAXWORDLEN, piece); ++ if (n > 0) { ++ flag_qsort((unsigned short *) w, 0, n); ++ cpdvowels_utf16 = (w_char *) malloc(n * sizeof(w_char)); ++ if (!cpdvowels_utf16) return 1; ++ memcpy(cpdvowels_utf16, w, n * sizeof(w_char)); ++ } ++ cpdvowels_utf16_len = n; ++ } ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np < 2) { ++ HUNSPELL_WARNING(stderr, "error: missing compoundsyllable information\n"); ++ return 1; ++ } ++ if (np == 2) cpdvowels = mystrdup("aeiouAEIOU"); ++ return 0; ++} ++ ++/* parse in the typical fault correcting table */ ++int AffixMgr::parse_reptable(char * line, FILE * af) ++{ ++ if (numrep != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate REP tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numrep = atoi(piece); ++ if (numrep < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in replacement table\n"); ++ free(piece); ++ return 1; ++ } ++ reptable = (replentry *) malloc(numrep * sizeof(struct replentry)); ++ if (!reptable) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing replacement table information\n"); ++ return 1; ++ } ++ ++ /* now parse the numrep lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numrep; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ reptable[j].pattern = NULL; ++ reptable[j].pattern2 = NULL; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"REP",3) != 0) { ++ HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n"); ++ numrep = 0; ++ free(piece); ++ return 1; ++ } ++ break; ++ } ++ case 1: { reptable[j].pattern = mystrrep(mystrdup(piece),"_"," "); break; } ++ case 2: { reptable[j].pattern2 = mystrrep(mystrdup(piece),"_"," "); break; } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if ((!(reptable[j].pattern)) || (!(reptable[j].pattern2))) { ++ HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n"); ++ numrep = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++/* parse in the typical fault correcting table */ ++int AffixMgr::parse_phonetable(char * line, FILE * af) ++{ ++ if (phone) { ++ HUNSPELL_WARNING(stderr, "error: duplicate PHONE tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ phone = (phonetable *) malloc(sizeof(struct phonetable)); ++ phone->num = atoi(piece); ++ phone->rules = NULL; ++ phone->utf8 = utf8; ++ if (!phone) return 1; ++ if (phone->num < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in phonelacement table\n"); ++ free(piece); ++ return 1; ++ } ++ phone->rules = (char * *) malloc(2 * (phone->num + 1) * sizeof(char *)); ++ if (!phone->rules) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing PHONE table information\n"); ++ return 1; ++ } ++ ++ /* now parse the phone->num lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < phone->num; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ phone->rules[j * 2] = NULL; ++ phone->rules[j * 2 + 1] = NULL; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"PHONE",5) != 0) { ++ HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n"); ++ phone->num = 0; ++ free(piece); ++ return 1; ++ } ++ break; ++ } ++ case 1: { phone->rules[j * 2] = mystrrep(mystrdup(piece),"_",""); break; } ++ case 2: { phone->rules[j * 2 + 1] = mystrrep(mystrdup(piece),"_",""); break; } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if ((!(phone->rules[j * 2])) || (!(phone->rules[j * 2 + 1]))) { ++ HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n"); ++ phone->num = 0; ++ return 1; ++ } ++ } ++ phone->rules[phone->num * 2] = mystrdup(""); ++ phone->rules[phone->num * 2 + 1] = mystrdup(""); ++ init_phonet_hash(*phone); ++ return 0; ++} ++ ++/* parse in the checkcompoundpattern table */ ++int AffixMgr::parse_checkcpdtable(char * line, FILE * af) ++{ ++ if (numcheckcpd != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate compound pattern tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numcheckcpd = atoi(piece); ++ if (numcheckcpd < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in compound pattern table\n"); ++ free(piece); ++ return 1; ++ } ++ checkcpdtable = (replentry *) malloc(numcheckcpd * sizeof(struct replentry)); ++ if (!checkcpdtable) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing compound pattern table information\n"); ++ return 1; ++ } ++ ++ /* now parse the numcheckcpd lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numcheckcpd; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ checkcpdtable[j].pattern = NULL; ++ checkcpdtable[j].pattern2 = NULL; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"CHECKCOMPOUNDPATTERN",20) != 0) { ++ HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n"); ++ numcheckcpd = 0; ++ free(piece); ++ return 1; ++ } ++ break; ++ } ++ case 1: { checkcpdtable[j].pattern = mystrdup(piece); break; } ++ case 2: { checkcpdtable[j].pattern2 = mystrdup(piece); break; } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if ((!(checkcpdtable[j].pattern)) || (!(checkcpdtable[j].pattern2))) { ++ HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n"); ++ numcheckcpd = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++/* parse in the compound rule table */ ++int AffixMgr::parse_defcpdtable(char * line, FILE * af) ++{ ++ if (numdefcpd != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate compound rule tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numdefcpd = atoi(piece); ++ if (numdefcpd < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in compound rule table\n"); ++ free(piece); ++ return 1; ++ } ++ defcpdtable = (flagentry *) malloc(numdefcpd * sizeof(flagentry)); ++ if (!defcpdtable) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing compound rule table information\n"); ++ return 1; ++ } ++ ++ /* now parse the numdefcpd lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numdefcpd; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ defcpdtable[j].def = NULL; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece, "COMPOUNDRULE", 12) != 0) { ++ HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n"); ++ free(piece); ++ numdefcpd = 0; ++ return 1; ++ } ++ break; ++ } ++ case 1: { ++ defcpdtable[j].len = ++ pHMgr->decode_flags(&(defcpdtable[j].def), piece); ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (!defcpdtable[j].len) { ++ HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n"); ++ numdefcpd = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++ ++/* parse in the character map table */ ++int AffixMgr::parse_maptable(char * line, FILE * af) ++{ ++ if (nummap != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate MAP tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ nummap = atoi(piece); ++ if (nummap < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in map table\n"); ++ free(piece); ++ return 1; ++ } ++ maptable = (mapentry *) malloc(nummap * sizeof(struct mapentry)); ++ if (!maptable) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing map table information\n"); ++ return 1; ++ } ++ ++ /* now parse the nummap lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < nummap; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ maptable[j].set = NULL; ++ maptable[j].len = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"MAP",3) != 0) { ++ HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); ++ nummap = 0; ++ free(piece); ++ return 1; ++ } ++ break; ++ } ++ case 1: { ++ maptable[j].len = 0; ++ maptable[j].set = NULL; ++ maptable[j].set_utf16 = NULL; ++ if (!utf8) { ++ maptable[j].set = mystrdup(piece); ++ maptable[j].len = strlen(maptable[j].set); ++ } else { ++ w_char w[MAXWORDLEN]; ++ int n = u8_u16(w, MAXWORDLEN, piece); ++ if (n > 0) { ++ flag_qsort((unsigned short *) w, 0, n); ++ maptable[j].set_utf16 = (w_char *) malloc(n * sizeof(w_char)); ++ if (!maptable[j].set_utf16) return 1; ++ memcpy(maptable[j].set_utf16, w, n * sizeof(w_char)); ++ } ++ maptable[j].len = n; ++ } ++ break; } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if ((!(maptable[j].set || maptable[j].set_utf16)) || (!(maptable[j].len))) { ++ HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); ++ nummap = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++/* parse in the word breakpoint table */ ++int AffixMgr::parse_breaktable(char * line, FILE * af) ++{ ++ if (numbreak != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate word breakpoint tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numbreak = atoi(piece); ++ if (numbreak < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in BREAK table\n"); ++ free(piece); ++ return 1; ++ } ++ breaktable = (char **) malloc(numbreak * sizeof(char *)); ++ if (!breaktable) return 1; ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing word breakpoint table information\n"); ++ return 1; ++ } ++ ++ /* now parse the numbreak lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numbreak; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"BREAK",5) != 0) { ++ HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n"); ++ free(piece); ++ numbreak = 0; ++ return 1; ++ } ++ break; ++ } ++ case 1: { ++ breaktable[j] = mystrdup(piece); ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (!breaktable) { ++ HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n"); ++ numbreak = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int AffixMgr::parse_affix(char * line, const char at, FILE * af, char * dupflags) ++{ ++ int numents = 0; // number of affentry structures to parse ++ ++ unsigned short aflag = 0; // affix char identifier ++ ++ char ff=0; ++ struct affentry * ptr= NULL; ++ struct affentry * nptr= NULL; ++ ++ char * tp = line; ++ char * nl = line; ++ char * piece; ++ int i = 0; ++ ++ // checking lines with bad syntax ++#ifdef DEBUG ++ int basefieldnum = 0; ++#endif ++ ++ // split affix header line into pieces ++ ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ // piece 1 - is type of affix ++ case 0: { np++; break; } ++ ++ // piece 2 - is affix char ++ case 1: { ++ np++; ++ aflag = pHMgr->decode_flag(piece); ++ if (((at == 'S') && (dupflags[aflag] & dupSFX)) || ++ ((at == 'P') && (dupflags[aflag] & dupPFX))) { ++ HUNSPELL_WARNING(stderr, "error: duplicate affix flag %s in line %s\n", piece, nl); ++ // return 1; XXX permissive mode for bad dictionaries ++ } ++ dupflags[aflag] += ((at == 'S') ? dupSFX : dupPFX); ++ break; ++ } ++ // piece 3 - is cross product indicator ++ case 2: { np++; if (*piece == 'Y') ff = aeXPRODUCT; break; } ++ ++ // piece 4 - is number of affentries ++ case 3: { ++ np++; ++ numents = atoi(piece); ++ if (numents == 0) { ++ char * err = pHMgr->encode_flag(aflag); ++ HUNSPELL_WARNING(stderr, "error: affix %s header has incorrect entry count in line %s\n", ++ err, nl); ++ free(err); ++ return 1; ++ } ++ ptr = (struct affentry *) malloc(numents * sizeof(struct affentry)); ++ if (!ptr) return 1; ++ ptr->opts = ff; ++ if (utf8) ptr->opts += aeUTF8; ++ if (pHMgr->is_aliasf()) ptr->opts += aeALIASF; ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (pHMgr->is_aliasm()) ptr->opts += aeALIASM; ++#endif ++ ptr->aflag = aflag; ++ } ++ ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ // check to make sure we parsed enough pieces ++ if (np != 4) { ++ char * err = pHMgr->encode_flag(aflag); ++ HUNSPELL_WARNING(stderr, "error: affix %s header has insufficient data in line %s\n", err, nl); ++ free(err); ++ free(ptr); ++ return 1; ++ } ++ ++ // store away ptr to first affentry ++ nptr = ptr; ++ ++ // now parse numents affentries for this affix ++ for (int j=0; j < numents; j++) { ++ if (!fgets(nl,MAXLNLEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ np = 0; ++ ++ // split line into pieces ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ // piece 1 - is type ++ case 0: { ++ np++; ++ if (nptr != ptr) nptr->opts = ptr->opts; ++ break; ++ } ++ ++ // piece 2 - is affix char ++ case 1: { ++ np++; ++ if (pHMgr->decode_flag(piece) != aflag) { ++ char * err = pHMgr->encode_flag(aflag); ++ HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl); ++ HUNSPELL_WARNING(stderr, "error: possible incorrect count\n"); ++ free(err); ++ free(piece); ++ return 1; ++ } ++ ++ if (nptr != ptr) nptr->aflag = ptr->aflag; ++ break; ++ } ++ ++ // piece 3 - is string to strip or 0 for null ++ case 2: { ++ np++; ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(piece); else reverseword(piece); ++ } ++ nptr->strip = mystrdup(piece); ++ nptr->stripl = (unsigned char) strlen(nptr->strip); ++ if (strcmp(nptr->strip,"0") == 0) { ++ free(nptr->strip); ++ nptr->strip=mystrdup(""); ++ nptr->stripl = 0; ++ } ++ break; ++ } ++ ++ // piece 4 - is affix string or 0 for null ++ case 3: { ++ char * dash; ++#ifdef HUNSPELL_EXPERIMENTAL ++ nptr->morphcode = NULL; ++#endif ++ nptr->contclass = NULL; ++ nptr->contclasslen = 0; ++ np++; ++ dash = strchr(piece, '/'); ++ if (dash) { ++ *dash = '\0'; ++ ++ if (ignorechars) { ++ if (utf8) { ++ remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len); ++ } else { ++ remove_ignored_chars(piece,ignorechars); ++ } ++ } ++ ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(piece); else reverseword(piece); ++ } ++ nptr->appnd = mystrdup(piece); ++ ++ if (pHMgr->is_aliasf()) { ++ int index = atoi(dash + 1); ++ nptr->contclasslen = (unsigned short) pHMgr->get_aliasf(index, &(nptr->contclass)); ++ } else { ++ nptr->contclasslen = (unsigned short) pHMgr->decode_flags(&(nptr->contclass), dash + 1); ++ flag_qsort(nptr->contclass, 0, nptr->contclasslen); ++ } ++ *dash = '/'; ++ ++ havecontclass = 1; ++ for (unsigned short _i = 0; _i < nptr->contclasslen; _i++) { ++ contclasses[(nptr->contclass)[_i]] = 1; ++ } ++ } else { ++ if (ignorechars) { ++ if (utf8) { ++ remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len); ++ } else { ++ remove_ignored_chars(piece,ignorechars); ++ } ++ } ++ ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(piece); else reverseword(piece); ++ } ++ nptr->appnd = mystrdup(piece); ++ } ++ ++ nptr->appndl = (unsigned char) strlen(nptr->appnd); ++ if (strcmp(nptr->appnd,"0") == 0) { ++ free(nptr->appnd); ++ nptr->appnd=mystrdup(""); ++ nptr->appndl = 0; ++ } ++ break; ++ } ++ ++ // piece 5 - is the conditions descriptions ++ case 4: { ++ np++; ++ if (complexprefixes) { ++ int neg = 0; ++ if (utf8) reverseword_utf(piece); else reverseword(piece); ++ // reverse condition ++ for (char * k = piece + strlen(piece) - 1; k >= piece; k--) { ++ switch(*k) { ++ case '[': { ++ if (neg) *(k+1) = '['; else *k = ']'; ++ break; ++ } ++ case ']': { ++ *k = '['; ++ if (neg) *(k+1) = '^'; ++ neg = 0; ++ break; ++ } ++ case '^': { ++ if (*(k+1) == ']') neg = 1; else *(k+1) = *k; ++ break; ++ } ++ default: { ++ if (neg) *(k+1) = *k; ++ } ++ } ++ } ++ } ++ if (nptr->stripl && (strcmp(piece, ".") != 0) && ++ redundant_condition(at, nptr->strip, nptr->stripl, piece, nl)) ++ strcpy(piece, "."); ++ if (encodeit(nptr,piece)) return 1; ++ break; ++ } ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++ case 5: { ++ np++; ++ if (pHMgr->is_aliasm()) { ++ int index = atoi(piece); ++ nptr->morphcode = pHMgr->get_aliasm(index); ++ } else { ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(piece); else reverseword(piece); ++ } ++ nptr->morphcode = mystrdup(piece); ++ } ++ break; ++ } ++#endif ++ ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ // check to make sure we parsed enough pieces ++ if (np < 4) { ++ char * err = pHMgr->encode_flag(aflag); ++ HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl); ++ free(err); ++ free(ptr); ++ return 1; ++ } ++ ++#ifdef DEBUG ++#ifdef HUNSPELL_EXPERIMENTAL ++ // detect unnecessary fields, excepting comments ++ if (basefieldnum) { ++ int fieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6); ++ if (fieldnum != basefieldnum) ++ HUNSPELL_WARNING(stderr, "warning: bad field number:\n%s\n", nl); ++ } else { ++ basefieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6); ++ } ++#endif ++#endif ++ nptr++; ++ } ++ ++ // now create SfxEntry or PfxEntry objects and use links to ++ // build an ordered (sorted by affix string) list ++ nptr = ptr; ++ for (int k = 0; k < numents; k++) { ++ if (at == 'P') { ++ PfxEntry * pfxptr = new PfxEntry(this,nptr); ++ build_pfxtree((AffEntry *)pfxptr); ++ } else { ++ SfxEntry * sfxptr = new SfxEntry(this,nptr); ++ build_sfxtree((AffEntry *)sfxptr); ++ } ++ nptr++; ++ } ++ free(ptr); ++ return 0; ++} ++ ++int AffixMgr::redundant_condition(char ft, char * strip, int stripl, const char * cond, char * warnvar) { ++ int condl = strlen(cond); ++ int i; ++ int j; ++ int neg; ++ int in; ++ if (ft == 'P') { // prefix ++ if (strncmp(strip, cond, condl) == 0) return 1; ++ if (utf8) { ++ } else { ++ for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) { ++ if (cond[j] != '[') { ++ if (cond[j] != strip[i]) { ++ HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); ++ } ++ } else { ++ neg = (cond[j+1] == '^') ? 1 : 0; ++ in = 0; ++ do { ++ j++; ++ if (strip[i] == cond[j]) in = 1; ++ } while ((j < (condl - 1)) && (cond[j] != ']')); ++ if (j == (condl - 1) && (cond[j] != ']')) { ++ HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar); ++ return 0; ++ } ++ if ((!neg && !in) || (neg && in)) { ++ HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); ++ return 0; ++ } ++ } ++ } ++ if (j >= condl) return 1; ++ } ++ } else { // suffix ++ if ((stripl >= condl) && strcmp(strip + stripl - condl, cond) == 0) return 1; ++ if (utf8) { ++ } else { ++ for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) { ++ if (cond[j] != ']') { ++ if (cond[j] != strip[i]) { ++ HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); ++ } ++ } else { ++ in = 0; ++ do { ++ j--; ++ if (strip[i] == cond[j]) in = 1; ++ } while ((j > 0) && (cond[j] != '[')); ++ if ((j == 0) && (cond[j] != '[')) { ++ HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar); ++ return 0; ++ } ++ neg = (cond[j+1] == '^') ? 1 : 0; ++ if ((!neg && !in) || (neg && in)) { ++ HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); ++ return 0; ++ } ++ } ++ } ++ if (j < 0) return 1; ++ } ++ } ++ return 0; ++} +Index: mozilla/extensions/spellcheck/hunspell/hunspell/affixmgr.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/affixmgr.hxx +@@ -0,0 +1,272 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _AFFIXMGR_HXX_ ++#define _AFFIXMGR_HXX_ ++ ++#ifdef MOZILLA_CLIENT ++#ifdef __SUNPRO_CC // for SunONE Studio compiler ++using namespace std; ++#endif ++#include ++#else ++#include ++#endif ++ ++#include "atypes.hxx" ++#include "baseaffix.hxx" ++#include "hashmgr.hxx" ++#include "phonet.hxx" ++ ++// check flag duplication ++#define dupSFX (1 << 0) ++#define dupPFX (1 << 1) ++ ++class AffixMgr ++{ ++ ++ AffEntry * pStart[SETSIZE]; ++ AffEntry * sStart[SETSIZE]; ++ AffEntry * pFlag[CONTSIZE]; ++ AffEntry * sFlag[CONTSIZE]; ++ HashMgr * pHMgr; ++ char * keystring; ++ char * trystring; ++ char * encoding; ++ struct cs_info * csconv; ++ int utf8; ++ int complexprefixes; ++ FLAG compoundflag; ++ FLAG compoundbegin; ++ FLAG compoundmiddle; ++ FLAG compoundend; ++ FLAG compoundroot; ++ FLAG compoundforbidflag; ++ FLAG compoundpermitflag; ++ int checkcompounddup; ++ int checkcompoundrep; ++ int checkcompoundcase; ++ int checkcompoundtriple; ++ FLAG forbiddenword; ++ FLAG nosuggest; ++ FLAG pseudoroot; ++ int cpdmin; ++ int numrep; ++ replentry * reptable; ++ int nummap; ++ mapentry * maptable; ++ int numbreak; ++ char ** breaktable; ++ int numcheckcpd; ++ replentry * checkcpdtable; ++ int numdefcpd; ++ flagentry * defcpdtable; ++ phonetable * phone; ++ int maxngramsugs; ++ int nosplitsugs; ++ int sugswithdots; ++ int cpdwordmax; ++ int cpdmaxsyllable; ++ char * cpdvowels; ++ w_char * cpdvowels_utf16; ++ int cpdvowels_utf16_len; ++ char * cpdsyllablenum; ++ const char * pfxappnd; // BUG: not stateless ++ const char * sfxappnd; // BUG: not stateless ++ FLAG sfxflag; // BUG: not stateless ++ char * derived; // BUG: not stateless ++ AffEntry * sfx; // BUG: not stateless ++ AffEntry * pfx; // BUG: not stateless ++ int checknum; ++ char * wordchars; ++ unsigned short * wordchars_utf16; ++ int wordchars_utf16_len; ++ char * ignorechars; ++ unsigned short * ignorechars_utf16; ++ int ignorechars_utf16_len; ++ char * version; ++ char * lang; ++ int langnum; ++ FLAG lemma_present; ++ FLAG circumfix; ++ FLAG onlyincompound; ++ FLAG keepcase; ++ int checksharps; ++ ++ int havecontclass; // boolean variable ++ char contclasses[CONTSIZE]; // flags of possible continuing classes (twofold affix) ++ flag flag_mode; ++ ++public: ++ ++ AffixMgr(const char * affpath, HashMgr * ptr); ++ ~AffixMgr(); ++ struct hentry * affix_check(const char * word, int len, ++ const unsigned short needflag = (unsigned short) 0, char in_compound = IN_CPD_NOT); ++ struct hentry * prefix_check(const char * word, int len, ++ char in_compound, const FLAG needflag = FLAG_NULL); ++ inline int isSubset(const char * s1, const char * s2); ++ struct hentry * prefix_check_twosfx(const char * word, int len, ++ char in_compound, const FLAG needflag = FLAG_NULL); ++ inline int isRevSubset(const char * s1, const char * end_of_s2, int len); ++ struct hentry * suffix_check(const char * word, int len, int sfxopts, AffEntry* ppfx, ++ char ** wlst, int maxSug, int * ns, const FLAG cclass = FLAG_NULL, ++ const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); ++ struct hentry * suffix_check_twosfx(const char * word, int len, ++ int sfxopts, AffEntry* ppfx, const FLAG needflag = FLAG_NULL); ++ ++ char * affix_check_morph(const char * word, int len, ++ const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); ++ char * prefix_check_morph(const char * word, int len, ++ char in_compound, const FLAG needflag = FLAG_NULL); ++ char * suffix_check_morph (const char * word, int len, int sfxopts, AffEntry * ppfx, ++ const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); ++ ++ char * prefix_check_twosfx_morph(const char * word, int len, ++ char in_compound, const FLAG needflag = FLAG_NULL); ++ char * suffix_check_twosfx_morph(const char * word, int len, ++ int sfxopts, AffEntry * ppfx, const FLAG needflag = FLAG_NULL); ++ ++ int expand_rootword(struct guessword * wlst, int maxn, const char * ts, ++ int wl, const unsigned short * ap, unsigned short al, char * bad, int, ++ char *); ++ ++ short get_syllable (const char * word, int wlen); ++ int cpdrep_check(const char * word, int len); ++ int cpdpat_check(const char * word, int len); ++ int defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** rwords, char all); ++ int cpdcase_check(const char * word, int len); ++ inline int candidate_check(const char * word, int len); ++ struct hentry * compound_check(const char * word, int len, ++ short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, ++ char hu_mov_rule, int * cmpdstemnum, int * cmpdstem, char is_sug); ++ ++ int compound_check_morph(const char * word, int len, ++ short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, ++ char hu_mov_rule, char ** result, char * partresult); ++ ++ struct hentry * lookup(const char * word); ++ int get_numrep(); ++ struct replentry * get_reptable(); ++ struct phonetable * get_phonetable(); ++ int get_nummap(); ++ struct mapentry * get_maptable(); ++ int get_numbreak(); ++ char ** get_breaktable(); ++ char * get_encoding(); ++ int get_langnum(); ++ char * get_key_string(); ++ char * get_try_string(); ++ const char * get_wordchars(); ++ unsigned short * get_wordchars_utf16(int * len); ++ char * get_ignore(); ++ unsigned short * get_ignore_utf16(int * len); ++ int get_compound(); ++ FLAG get_compoundflag(); ++ FLAG get_compoundbegin(); ++ FLAG get_forbiddenword(); ++ FLAG get_nosuggest(); ++// FLAG get_circumfix(); ++ FLAG get_pseudoroot(); ++ FLAG get_onlyincompound(); ++ FLAG get_compoundroot(); ++ FLAG get_lemma_present(); ++ int get_checknum(); ++ char * get_possible_root(); ++ const char * get_prefix(); ++ const char * get_suffix(); ++ const char * get_derived(); ++ const char * get_version(); ++ const int have_contclass(); ++ int get_utf8(); ++ int get_complexprefixes(); ++ char * get_suffixed(char ); ++ int get_maxngramsugs(); ++ int get_nosplitsugs(); ++ int get_sugswithdots(void); ++ FLAG get_keepcase(void); ++ int get_checksharps(void); ++ ++private: ++ int parse_file(const char * affpath); ++// int parse_string(char * line, char ** out, const char * name); ++ int parse_flag(char * line, unsigned short * out, const char * name); ++ int parse_num(char * line, int * out, const char * name); ++// int parse_array(char * line, char ** out, unsigned short ** out_utf16, ++// int * out_utf16_len, const char * name); ++ int parse_cpdsyllable(char * line); ++ int parse_reptable(char * line, FILE * af); ++ int parse_phonetable(char * line, FILE * af); ++ int parse_maptable(char * line, FILE * af); ++ int parse_breaktable(char * line, FILE * af); ++ int parse_checkcpdtable(char * line, FILE * af); ++ int parse_defcpdtable(char * line, FILE * af); ++ int parse_affix(char * line, const char at, FILE * af, char * dupflags); ++ ++ int encodeit(struct affentry * ptr, char * cs); ++ int build_pfxtree(AffEntry* pfxptr); ++ int build_sfxtree(AffEntry* sfxptr); ++ int process_pfx_order(); ++ int process_sfx_order(); ++ AffEntry * process_pfx_in_order(AffEntry * ptr, AffEntry * nptr); ++ AffEntry * process_sfx_in_order(AffEntry * ptr, AffEntry * nptr); ++ int process_pfx_tree_to_list(); ++ int process_sfx_tree_to_list(); ++ int redundant_condition(char, char * strip, int stripl, const char * cond, char *); ++}; ++ ++#endif ++ +Index: mozilla/extensions/spellcheck/hunspell/hunspell/atypes.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/atypes.hxx +@@ -0,0 +1,154 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _ATYPES_HXX_ ++#define _ATYPES_HXX_ ++ ++#ifndef HUNSPELL_WARNING ++#ifdef HUNSPELL_WARNING_ON ++#define HUNSPELL_WARNING fprintf ++#else ++// empty inline function to switch off warnings (instead of the C99 standard variadic macros) ++static inline void HUNSPELL_WARNING(FILE *, const char *, ...) {} ++#endif ++#endif ++ ++// HUNSTEM def. ++#define HUNSTEM ++ ++#include "csutil.hxx" ++#include "hashmgr.hxx" ++ ++#define SETSIZE 256 ++#define CONTSIZE 65536 ++#define MAXWORDLEN 100 ++#define MAXWORDUTF8LEN 256 ++ ++// affentry options ++#define aeXPRODUCT (1 << 0) ++#define aeUTF8 (1 << 1) ++#define aeALIASF (1 << 2) ++#define aeALIASM (1 << 3) ++#define aeINFIX (1 << 4) ++ ++// compound options ++#define IN_CPD_NOT 0 ++#define IN_CPD_BEGIN 1 ++#define IN_CPD_END 2 ++#define IN_CPD_OTHER 3 ++ ++#define MAXLNLEN 8192 ++ ++#define MINCPDLEN 3 ++#define MAXCOMPOUND 10 ++ ++#define MAXACC 1000 ++ ++#define FLAG unsigned short ++#define FLAG_NULL 0x00 ++#define FREE_FLAG(a) a = 0 ++ ++#define TESTAFF( a, b , c ) flag_bsearch((unsigned short *) a, (unsigned short) b, c) ++ ++struct affentry ++{ ++ char * strip; ++ char * appnd; ++ unsigned char stripl; ++ unsigned char appndl; ++ char numconds; ++ char opts; ++ unsigned short aflag; ++ union { ++ char base[SETSIZE]; ++ struct { ++ char ascii[SETSIZE/2]; ++ char neg[8]; ++ char all[8]; ++ w_char * wchars[8]; ++ int wlen[8]; ++ } utf8; ++ } conds; ++#ifdef HUNSPELL_EXPERIMENTAL ++ char * morphcode; ++#endif ++ unsigned short * contclass; ++ short contclasslen; ++}; ++ ++struct mapentry { ++ char * set; ++ w_char * set_utf16; ++ int len; ++}; ++ ++struct flagentry { ++ FLAG * def; ++ int len; ++}; ++ ++struct guessword { ++ char * word; ++ bool allow; ++ char * orig; ++}; ++ ++#endif ++ ++ ++ ++ ++ +Index: mozilla/extensions/spellcheck/hunspell/hunspell/baseaffix.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/baseaffix.hxx +@@ -0,0 +1,87 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _BASEAFF_HXX_ ++#define _BASEAFF_HXX_ ++ ++class AffEntry ++{ ++public: ++ ++protected: ++ char * appnd; ++ char * strip; ++ unsigned char appndl; ++ unsigned char stripl; ++ char numconds; ++ char opts; ++ unsigned short aflag; ++ union { ++ char base[SETSIZE]; ++ struct { ++ char ascii[SETSIZE/2]; ++ char neg[8]; ++ char all[8]; ++ w_char * wchars[8]; ++ int wlen[8]; ++ } utf8; ++ } conds; ++ char * morphcode; ++ unsigned short * contclass; ++ short contclasslen; ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/csutil.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/csutil.cpp +@@ -0,0 +1,5400 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "csutil.hxx" ++#include "atypes.hxx" ++#include "langnum.hxx" ++ ++#ifdef OPENOFFICEORG ++# include ++#else ++# ifndef MOZILLA_CLIENT ++# include "utf_info.cxx" ++# define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info))) ++# endif ++#endif ++ ++#ifdef MOZILLA_CLIENT ++#include "nsCOMPtr.h" ++#include "nsServiceManagerUtils.h" ++#include "nsIUnicodeEncoder.h" ++#include "nsIUnicodeDecoder.h" ++#include "nsICaseConversion.h" ++#include "nsICharsetConverterManager.h" ++#include "nsUnicharUtilCIID.h" ++#include "nsUnicharUtils.h" ++ ++static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); ++static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID); ++#endif ++ ++#ifdef MOZILLA_CLIENT ++#ifdef __SUNPRO_CC // for SunONE Studio compiler ++using namespace std; ++#endif ++#else ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++static struct unicode_info2 * utf_tbl = NULL; ++static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances ++ ++/* only UTF-16 (BMP) implementation */ ++char * u16_u8(char * dest, int size, const w_char * src, int srclen) { ++ char * u8 = dest; ++ char * u8_max = u8 + size; ++ const w_char * u2 = src; ++ const w_char * u2_max = src + srclen; ++ while ((u2 < u2_max) && (u8 < u8_max)) { ++ if (u2->h) { // > 0xFF ++ // XXX 4-byte haven't implemented yet. ++ if (u2->h >= 0x08) { // >= 0x800 (3-byte UTF-8 character) ++ *u8 = 0xe0 + (u2->h >> 4); ++ u8++; ++ if (u8 < u8_max) { ++ *u8 = 0x80 + ((u2->h & 0xf) << 2) + (u2->l >> 6); ++ u8++; ++ if (u8 < u8_max) { ++ *u8 = 0x80 + (u2->l & 0x3f); ++ u8++; ++ } ++ } ++ } else { // < 0x800 (2-byte UTF-8 character) ++ *u8 = 0xc0 + (u2->h << 2) + (u2->l >> 6); ++ u8++; ++ if (u8 < u8_max) { ++ *u8 = 0x80 + (u2->l & 0x3f); ++ u8++; ++ } ++ } ++ } else { // <= 0xFF ++ if (u2->l & 0x80) { // >0x80 (2-byte UTF-8 character) ++ *u8 = 0xc0 + (u2->l >> 6); ++ u8++; ++ if (u8 < u8_max) { ++ *u8 = 0x80 + (u2->l & 0x3f); ++ u8++; ++ } ++ } else { // < 0x80 (1-byte UTF-8 character) ++ *u8 = u2->l; ++ u8++; ++ } ++ } ++ u2++; ++ } ++ *u8 = '\0'; ++ return dest; ++} ++ ++ ++/* only UTF-16 (BMP) implementation */ ++int u8_u16(w_char * dest, int size, const char * src) { ++ const char * u8 = src; ++ w_char * u2 = dest; ++ w_char * u2_max = u2 + size; ++ ++ while ((u2 < u2_max) && *u8) { ++ switch ((*u8) & 0xf0) { ++ case 0x00: ++ case 0x10: ++ case 0x20: ++ case 0x30: ++ case 0x40: ++ case 0x50: ++ case 0x60: ++ case 0x70: { ++ u2->h = 0; ++ u2->l = *u8; ++ break; ++ } ++ case 0x80: ++ case 0x90: ++ case 0xa0: ++ case 0xb0: { ++ HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Unexpected continuation bytes in %d. character position\n%s\n", u8 - src, src); ++ u2->h = 0xff; ++ u2->l = 0xfd; ++ break; ++ } ++ case 0xc0: ++ case 0xd0: { // 2-byte UTF-8 codes ++ if ((*(u8+1) & 0xc0) == 0x80) { ++ u2->h = (*u8 & 0x1f) >> 2; ++ u2->l = (*u8 << 6) + (*(u8+1) & 0x3f); ++ u8++; ++ } else { ++ HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); ++ u2->h = 0xff; ++ u2->l = 0xfd; ++ } ++ break; ++ } ++ case 0xe0: { // 3-byte UTF-8 codes ++ if ((*(u8+1) & 0xc0) == 0x80) { ++ u2->h = ((*u8 & 0x0f) << 4) + ((*(u8+1) & 0x3f) >> 2); ++ u8++; ++ if ((*(u8+1) & 0xc0) == 0x80) { ++ u2->l = (*u8 << 6) + (*(u8+1) & 0x3f); ++ u8++; ++ } else { ++ HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); ++ u2->h = 0xff; ++ u2->l = 0xfd; ++ } ++ } else { ++ HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); ++ u2->h = 0xff; ++ u2->l = 0xfd; ++ } ++ break; ++ } ++ case 0xf0: { // 4 or more byte UTF-8 codes ++ HUNSPELL_WARNING(stderr, "This UTF-8 encoding can't convert to UTF-16:\n%s\n", src); ++ u2->h = 0xff; ++ u2->l = 0xfd; ++ return -1; ++ } ++ } ++ u8++; ++ u2++; ++ } ++ return u2 - dest; ++} ++ ++void flag_qsort(unsigned short flags[], int begin, int end) { ++ unsigned short reg; ++ if (end > begin) { ++ unsigned short pivot = flags[begin]; ++ int l = begin + 1; ++ int r = end; ++ while(l < r) { ++ if (flags[l] <= pivot) { ++ l++; ++ } else { ++ r--; ++ reg = flags[l]; ++ flags[l] = flags[r]; ++ flags[r] = reg; ++ } ++ } ++ l--; ++ reg = flags[begin]; ++ flags[begin] = flags[l]; ++ flags[l] = reg; ++ ++ flag_qsort(flags, begin, l); ++ flag_qsort(flags, r, end); ++ } ++ } ++ ++int flag_bsearch(unsigned short flags[], unsigned short flag, int length) { ++ int mid; ++ int left = 0; ++ int right = length - 1; ++ while (left <= right) { ++ mid = (left + right) / 2; ++ if (flags[mid] == flag) return 1; ++ if (flag < flags[mid]) right = mid - 1; ++ else left = mid + 1; ++ } ++ return 0; ++} ++ ++ // strip strings into token based on single char delimiter ++ // acts like strsep() but only uses a delim char and not ++ // a delim string ++ // default delimiter: white space characters ++ ++ char * mystrsep(char ** stringp, const char delim) ++ { ++ char * rv = NULL; ++ char * mp = *stringp; ++ int n = strlen(mp); ++ if (n > 0) { ++ char * dp; ++ if (delim) { ++ dp = (char *)memchr(mp,(int)((unsigned char)delim),n); ++ } else { ++ // don't use isspace() here, the string can be in some random charset ++ // that's way different than the locale's ++ for (dp = mp; (*dp && *dp != ' ' && *dp != '\t'); dp++); ++ if (!*dp) dp = NULL; ++ } ++ if (dp) { ++ *stringp = dp+1; ++ int nc = (int)((unsigned long)dp - (unsigned long)mp); ++ rv = (char *) malloc(nc+1); ++ if (rv) { ++ memcpy(rv,mp,nc); ++ *(rv+nc) = '\0'; ++ return rv; ++ } ++ } else { ++ rv = (char *) malloc(n+1); ++ if (rv) { ++ memcpy(rv, mp, n); ++ *(rv+n) = '\0'; ++ *stringp = mp + n; ++ return rv; ++ } ++ } ++ } ++ return NULL; ++ } ++ ++ ++ // replaces strdup with ansi version ++ char * mystrdup(const char * s) ++ { ++ char * d = NULL; ++ if (s) { ++ int sl = strlen(s); ++ d = (char *) malloc(((sl+1) * sizeof(char))); ++ if (d) memcpy(d,s,((sl+1)*sizeof(char))); ++ } ++ return d; ++ } ++ ++ ++ // remove cross-platform text line end characters ++ void mychomp(char * s) ++ { ++ int k = strlen(s); ++ if ((k > 0) && ((*(s+k-1)=='\r') || (*(s+k-1)=='\n'))) *(s+k-1) = '\0'; ++ if ((k > 1) && (*(s+k-2) == '\r')) *(s+k-2) = '\0'; ++ } ++ ++ ++ // does an ansi strdup of the reverse of a string ++ char * myrevstrdup(const char * s) ++ { ++ char * d = NULL; ++ if (s) { ++ int sl = strlen(s); ++ d = (char *) malloc((sl+1) * sizeof(char)); ++ if (d) { ++ const char * p = s + sl - 1; ++ char * q = d; ++ while (p >= s) *q++ = *p--; ++ *q = '\0'; ++ } ++ } ++ return d; ++ } ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++ // append s to ends of every lines in text ++ void strlinecat(char * dest, const char * s) ++ { ++ char * dup = mystrdup(dest); ++ char * source = dup; ++ int len = strlen(s); ++ while (*source) { ++ if (*source == '\n') { ++ strncpy(dest, s, len); ++ dest += len; ++ } ++ *dest = *source; ++ source++; dest++; ++ } ++ strcpy(dest, s); ++ free(dup); ++ } ++ ++// break text to lines ++// return number of lines ++int line_tok(const char * text, char *** lines) { ++ int linenum = 0; ++ char * dup = mystrdup(text); ++ char * p = strchr(dup, '\n'); ++ while (p) { ++ linenum++; ++ *p = '\0'; ++ p++; ++ p = strchr(p, '\n'); ++ } ++ *lines = (char **) calloc(linenum + 1, sizeof(char *)); ++ if (!(*lines)) return -1; ++ ++ p = dup; ++ for (int i = 0; i < linenum + 1; i++) { ++ (*lines)[i] = mystrdup(p); ++ p += strlen(p) + 1; ++ } ++ free(dup); ++ return linenum; ++} ++ ++// uniq line in place ++char * line_uniq(char * text) { ++ char ** lines; ++ int linenum = line_tok(text, &lines); ++ int i; ++ strcpy(text, lines[0]); ++ for ( i = 1; i<=linenum; i++ ) { ++ int dup = 0; ++ for (int j = 0; j < i; j++) { ++ if (strcmp(lines[i], lines[j]) == 0) dup = 1; ++ } ++ if (!dup) { ++ if ((i > 1) || (*(lines[0]) != '\0')) strcat(text, "\n"); ++ strcat(text, lines[i]); ++ } ++ } ++ for ( i = 0; i<=linenum; i++ ) { ++ if (lines[i]) free(lines[i]); ++ } ++ if (lines) free(lines); ++ return text; ++} ++ ++// change \n to char c ++char * line_join(char * text, char c) { ++ char * p; ++ for (p = text; *p; p++) if (*p == '\n') *p = c; ++ return text; ++} ++ ++// leave only last {[^}]*} substring for handling zero morphemes ++char * delete_zeros(char * morphout) { ++ char * p = morphout; ++ char * q = p; ++ char * q2 = NULL; ++ int suffix = 0; ++ ++ for (;*p && *(p+1);) { ++ switch (*p) { ++ case '{': ++ q2 = q; ++ q--; ++ break; ++ case '}': ++ if (q2) { ++ suffix = 1; ++ q--; ++ } ++ break; ++ default: ++ if (suffix) { ++ q = q2; ++ } ++ suffix = 0; ++ *q = *p; ++ } ++ p++; ++ q++; ++ } ++ *q = '\0'; ++ return morphout; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++char * mystrrep(char * word, const char * pat, const char * rep) { ++ char * pos = strstr(word, pat); ++ if (pos) { ++ int replen = strlen(rep); ++ int patlen = strlen(pat); ++ if (replen < patlen) { ++ char * end = word + strlen(word); ++ char * next = pos + replen; ++ char * prev = pos + strlen(pat); ++ for (; prev < end; *next = *prev, prev++, next++); ++ *next = '\0'; ++ } else if (replen > patlen) { ++ char * end = pos + patlen; ++ char * next = word + strlen(word) + replen - patlen; ++ char * prev = next - replen + patlen; ++ for (; prev >= end; *next = *prev, prev--, next--); ++ } ++ strncpy(pos, rep, replen); ++ } ++ return word; ++} ++ ++ // reverse word ++ int reverseword(char * word) { ++ char r; ++ for (char * dest = word + strlen(word) - 1; word < dest; word++, dest--) { ++ r=*word; ++ *word = *dest; ++ *dest = r; ++ } ++ return 0; ++ } ++ ++ // reverse word (error: 1) ++ int reverseword_utf(char * word) { ++ w_char w[MAXWORDLEN]; ++ w_char * p; ++ w_char r; ++ int l = u8_u16(w, MAXWORDLEN, word); ++ if (l == -1) return 1; ++ p = w; ++ for (w_char * dest = w + l - 1; p < dest; p++, dest--) { ++ r=*p; ++ *p = *dest; ++ *dest = r; ++ } ++ u16_u8(word, MAXWORDUTF8LEN, w, l); ++ return 0; ++ } ++ ++ // convert null terminated string to all caps ++ void mkallcap(char * p, const struct cs_info * csconv) ++ { ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].cupper; ++ p++; ++ } ++ } ++ ++ // convert null terminated string to all little ++ void mkallsmall(char * p, const struct cs_info * csconv) ++ { ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].clower; ++ p++; ++ } ++ } ++ ++void mkallsmall_utf(w_char * u, int nc, int langnum) { ++ for (int i = 0; i < nc; i++) { ++ unsigned short idx = (u[i].h << 8) + u[i].l; ++ if (idx != unicodetolower(idx, langnum)) { ++ u[i].h = (unsigned char) (unicodetolower(idx, langnum) >> 8); ++ u[i].l = (unsigned char) (unicodetolower(idx, langnum) & 0x00FF); ++ } ++ } ++} ++ ++void mkallcap_utf(w_char * u, int nc, int langnum) { ++ for (int i = 0; i < nc; i++) { ++ unsigned short idx = (u[i].h << 8) + u[i].l; ++ if (idx != unicodetoupper(idx, langnum)) { ++ u[i].h = (unsigned char) (unicodetoupper(idx, langnum) >> 8); ++ u[i].l = (unsigned char) (unicodetoupper(idx, langnum) & 0x00FF); ++ } ++ } ++} ++ ++ // convert null terminated string to have intial capital ++ void mkinitcap(char * p, const struct cs_info * csconv) ++ { ++ if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; ++ } ++ ++#ifndef MOZILLA_CLIENT ++ // convert null terminated string to all caps using encoding ++ void enmkallcap(char * d, const char * p, const char * encoding) ++ ++ { ++ struct cs_info * csconv = get_current_cs(encoding); ++ while (*p != '\0') { ++ *d++ = csconv[((unsigned char) *p)].cupper; ++ p++; ++ } ++ *d = '\0'; ++ } ++ ++ // convert null terminated string to all little using encoding ++ void enmkallsmall(char * d, const char * p, const char * encoding) ++ { ++ struct cs_info * csconv = get_current_cs(encoding); ++ while (*p != '\0') { ++ *d++ = csconv[((unsigned char) *p)].clower; ++ p++; ++ } ++ *d = '\0'; ++ } ++ ++ // convert null terminated string to have intial capital using encoding ++ void enmkinitcap(char * d, const char * p, const char * encoding) ++ { ++ struct cs_info * csconv = get_current_cs(encoding); ++ memcpy(d,p,(strlen(p)+1)); ++ if (*p != '\0') *d= csconv[((unsigned char)*p)].cupper; ++ } ++ ++// these are simple character mappings for the ++// encodings supported ++// supplying isupper, tolower, and toupper ++ ++struct cs_info iso1_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++ ++struct cs_info iso2_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xb1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x01, 0xb3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x01, 0xb5, 0xa5 }, ++{ 0x01, 0xb6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x01, 0xb9, 0xa9 }, ++{ 0x01, 0xba, 0xaa }, ++{ 0x01, 0xbb, 0xab }, ++{ 0x01, 0xbc, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x01, 0xbe, 0xae }, ++{ 0x01, 0xbf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xa1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xa3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xa5 }, ++{ 0x00, 0xb6, 0xa6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xa9 }, ++{ 0x00, 0xba, 0xaa }, ++{ 0x00, 0xbb, 0xab }, ++{ 0x00, 0xbc, 0xac }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xae }, ++{ 0x00, 0xbf, 0xaf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++ ++struct cs_info iso3_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xb1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x01, 0xb6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x01, 0x69, 0xa9 }, ++{ 0x01, 0xba, 0xaa }, ++{ 0x01, 0xbb, 0xab }, ++{ 0x01, 0xbc, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x01, 0xbf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xa1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xa6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0x49 }, ++{ 0x00, 0xba, 0xaa }, ++{ 0x00, 0xbb, 0xab }, ++{ 0x00, 0xbc, 0xac }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xaf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x00, 0xc3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x00, 0xd0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xe3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso4_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xb1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x01, 0xb3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x01, 0xb5, 0xa5 }, ++{ 0x01, 0xb6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x01, 0xb9, 0xa9 }, ++{ 0x01, 0xba, 0xaa }, ++{ 0x01, 0xbb, 0xab }, ++{ 0x01, 0xbc, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x01, 0xbe, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xa1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xa3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xa5 }, ++{ 0x00, 0xb6, 0xa6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xa9 }, ++{ 0x00, 0xba, 0xaa }, ++{ 0x00, 0xbb, 0xab }, ++{ 0x00, 0xbc, 0xac }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xae }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso5_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xf1, 0xa1 }, ++{ 0x01, 0xf2, 0xa2 }, ++{ 0x01, 0xf3, 0xa3 }, ++{ 0x01, 0xf4, 0xa4 }, ++{ 0x01, 0xf5, 0xa5 }, ++{ 0x01, 0xf6, 0xa6 }, ++{ 0x01, 0xf7, 0xa7 }, ++{ 0x01, 0xf8, 0xa8 }, ++{ 0x01, 0xf9, 0xa9 }, ++{ 0x01, 0xfa, 0xaa }, ++{ 0x01, 0xfb, 0xab }, ++{ 0x01, 0xfc, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x01, 0xfe, 0xae }, ++{ 0x01, 0xff, 0xaf }, ++{ 0x01, 0xd0, 0xb0 }, ++{ 0x01, 0xd1, 0xb1 }, ++{ 0x01, 0xd2, 0xb2 }, ++{ 0x01, 0xd3, 0xb3 }, ++{ 0x01, 0xd4, 0xb4 }, ++{ 0x01, 0xd5, 0xb5 }, ++{ 0x01, 0xd6, 0xb6 }, ++{ 0x01, 0xd7, 0xb7 }, ++{ 0x01, 0xd8, 0xb8 }, ++{ 0x01, 0xd9, 0xb9 }, ++{ 0x01, 0xda, 0xba }, ++{ 0x01, 0xdb, 0xbb }, ++{ 0x01, 0xdc, 0xbc }, ++{ 0x01, 0xdd, 0xbd }, ++{ 0x01, 0xde, 0xbe }, ++{ 0x01, 0xdf, 0xbf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x00, 0xd0, 0xb0 }, ++{ 0x00, 0xd1, 0xb1 }, ++{ 0x00, 0xd2, 0xb2 }, ++{ 0x00, 0xd3, 0xb3 }, ++{ 0x00, 0xd4, 0xb4 }, ++{ 0x00, 0xd5, 0xb5 }, ++{ 0x00, 0xd6, 0xb6 }, ++{ 0x00, 0xd7, 0xb7 }, ++{ 0x00, 0xd8, 0xb8 }, ++{ 0x00, 0xd9, 0xb9 }, ++{ 0x00, 0xda, 0xba }, ++{ 0x00, 0xdb, 0xbb }, ++{ 0x00, 0xdc, 0xbc }, ++{ 0x00, 0xdd, 0xbd }, ++{ 0x00, 0xde, 0xbe }, ++{ 0x00, 0xdf, 0xbf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xa1 }, ++{ 0x00, 0xf2, 0xa2 }, ++{ 0x00, 0xf3, 0xa3 }, ++{ 0x00, 0xf4, 0xa4 }, ++{ 0x00, 0xf5, 0xa5 }, ++{ 0x00, 0xf6, 0xa6 }, ++{ 0x00, 0xf7, 0xa7 }, ++{ 0x00, 0xf8, 0xa8 }, ++{ 0x00, 0xf9, 0xa9 }, ++{ 0x00, 0xfa, 0xaa }, ++{ 0x00, 0xfb, 0xab }, ++{ 0x00, 0xfc, 0xac }, ++{ 0x00, 0xfd, 0xfd }, ++{ 0x00, 0xfe, 0xae }, ++{ 0x00, 0xff, 0xaf }, ++}; ++ ++struct cs_info iso6_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xc0 }, ++{ 0x00, 0xc1, 0xc1 }, ++{ 0x00, 0xc2, 0xc2 }, ++{ 0x00, 0xc3, 0xc3 }, ++{ 0x00, 0xc4, 0xc4 }, ++{ 0x00, 0xc5, 0xc5 }, ++{ 0x00, 0xc6, 0xc6 }, ++{ 0x00, 0xc7, 0xc7 }, ++{ 0x00, 0xc8, 0xc8 }, ++{ 0x00, 0xc9, 0xc9 }, ++{ 0x00, 0xca, 0xca }, ++{ 0x00, 0xcb, 0xcb }, ++{ 0x00, 0xcc, 0xcc }, ++{ 0x00, 0xcd, 0xcd }, ++{ 0x00, 0xce, 0xce }, ++{ 0x00, 0xcf, 0xcf }, ++{ 0x00, 0xd0, 0xd0 }, ++{ 0x00, 0xd1, 0xd1 }, ++{ 0x00, 0xd2, 0xd2 }, ++{ 0x00, 0xd3, 0xd3 }, ++{ 0x00, 0xd4, 0xd4 }, ++{ 0x00, 0xd5, 0xd5 }, ++{ 0x00, 0xd6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x00, 0xd8, 0xd8 }, ++{ 0x00, 0xd9, 0xd9 }, ++{ 0x00, 0xda, 0xda }, ++{ 0x00, 0xdb, 0xdb }, ++{ 0x00, 0xdc, 0xdc }, ++{ 0x00, 0xdd, 0xdd }, ++{ 0x00, 0xde, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xe0 }, ++{ 0x00, 0xe1, 0xe1 }, ++{ 0x00, 0xe2, 0xe2 }, ++{ 0x00, 0xe3, 0xe3 }, ++{ 0x00, 0xe4, 0xe4 }, ++{ 0x00, 0xe5, 0xe5 }, ++{ 0x00, 0xe6, 0xe6 }, ++{ 0x00, 0xe7, 0xe7 }, ++{ 0x00, 0xe8, 0xe8 }, ++{ 0x00, 0xe9, 0xe9 }, ++{ 0x00, 0xea, 0xea }, ++{ 0x00, 0xeb, 0xeb }, ++{ 0x00, 0xec, 0xec }, ++{ 0x00, 0xed, 0xed }, ++{ 0x00, 0xee, 0xee }, ++{ 0x00, 0xef, 0xef }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xf1 }, ++{ 0x00, 0xf2, 0xf2 }, ++{ 0x00, 0xf3, 0xf3 }, ++{ 0x00, 0xf4, 0xf4 }, ++{ 0x00, 0xf5, 0xf5 }, ++{ 0x00, 0xf6, 0xf6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xf8 }, ++{ 0x00, 0xf9, 0xf9 }, ++{ 0x00, 0xfa, 0xfa }, ++{ 0x00, 0xfb, 0xfb }, ++{ 0x00, 0xfc, 0xfc }, ++{ 0x00, 0xfd, 0xfd }, ++{ 0x00, 0xfe, 0xfe }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso7_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x01, 0xdc, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x01, 0xdd, 0xb8 }, ++{ 0x01, 0xde, 0xb9 }, ++{ 0x01, 0xdf, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x01, 0xfc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x01, 0xfd, 0xbe }, ++{ 0x01, 0xfe, 0xbf }, ++{ 0x00, 0xc0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x00, 0xd2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x01, 0xf7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x00, 0xdc, 0xb6 }, ++{ 0x00, 0xdd, 0xb8 }, ++{ 0x00, 0xde, 0xb9 }, ++{ 0x00, 0xdf, 0xba }, ++{ 0x00, 0xe0, 0xe0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd3 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xd7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xbc }, ++{ 0x00, 0xfd, 0xbe }, ++{ 0x00, 0xfe, 0xbf }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso8_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xc0 }, ++{ 0x00, 0xc1, 0xc1 }, ++{ 0x00, 0xc2, 0xc2 }, ++{ 0x00, 0xc3, 0xc3 }, ++{ 0x00, 0xc4, 0xc4 }, ++{ 0x00, 0xc5, 0xc5 }, ++{ 0x00, 0xc6, 0xc6 }, ++{ 0x00, 0xc7, 0xc7 }, ++{ 0x00, 0xc8, 0xc8 }, ++{ 0x00, 0xc9, 0xc9 }, ++{ 0x00, 0xca, 0xca }, ++{ 0x00, 0xcb, 0xcb }, ++{ 0x00, 0xcc, 0xcc }, ++{ 0x00, 0xcd, 0xcd }, ++{ 0x00, 0xce, 0xce }, ++{ 0x00, 0xcf, 0xcf }, ++{ 0x00, 0xd0, 0xd0 }, ++{ 0x00, 0xd1, 0xd1 }, ++{ 0x00, 0xd2, 0xd2 }, ++{ 0x00, 0xd3, 0xd3 }, ++{ 0x00, 0xd4, 0xd4 }, ++{ 0x00, 0xd5, 0xd5 }, ++{ 0x00, 0xd6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x00, 0xd8, 0xd8 }, ++{ 0x00, 0xd9, 0xd9 }, ++{ 0x00, 0xda, 0xda }, ++{ 0x00, 0xdb, 0xdb }, ++{ 0x00, 0xdc, 0xdc }, ++{ 0x00, 0xdd, 0xdd }, ++{ 0x00, 0xde, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xe0 }, ++{ 0x00, 0xe1, 0xe1 }, ++{ 0x00, 0xe2, 0xe2 }, ++{ 0x00, 0xe3, 0xe3 }, ++{ 0x00, 0xe4, 0xe4 }, ++{ 0x00, 0xe5, 0xe5 }, ++{ 0x00, 0xe6, 0xe6 }, ++{ 0x00, 0xe7, 0xe7 }, ++{ 0x00, 0xe8, 0xe8 }, ++{ 0x00, 0xe9, 0xe9 }, ++{ 0x00, 0xea, 0xea }, ++{ 0x00, 0xeb, 0xeb }, ++{ 0x00, 0xec, 0xec }, ++{ 0x00, 0xed, 0xed }, ++{ 0x00, 0xee, 0xee }, ++{ 0x00, 0xef, 0xef }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xf1 }, ++{ 0x00, 0xf2, 0xf2 }, ++{ 0x00, 0xf3, 0xf3 }, ++{ 0x00, 0xf4, 0xf4 }, ++{ 0x00, 0xf5, 0xf5 }, ++{ 0x00, 0xf6, 0xf6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xf8 }, ++{ 0x00, 0xf9, 0xf9 }, ++{ 0x00, 0xfa, 0xfa }, ++{ 0x00, 0xfb, 0xfb }, ++{ 0x00, 0xfc, 0xfc }, ++{ 0x00, 0xfd, 0xfd }, ++{ 0x00, 0xfe, 0xfe }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso9_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0xfd, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0xdd }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0x69, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0x49 }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso10_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xc0 }, ++{ 0x00, 0xc1, 0xc1 }, ++{ 0x00, 0xc2, 0xc2 }, ++{ 0x00, 0xc3, 0xc3 }, ++{ 0x00, 0xc4, 0xc4 }, ++{ 0x00, 0xc5, 0xc5 }, ++{ 0x00, 0xc6, 0xc6 }, ++{ 0x00, 0xc7, 0xc7 }, ++{ 0x00, 0xc8, 0xc8 }, ++{ 0x00, 0xc9, 0xc9 }, ++{ 0x00, 0xca, 0xca }, ++{ 0x00, 0xcb, 0xcb }, ++{ 0x00, 0xcc, 0xcc }, ++{ 0x00, 0xcd, 0xcd }, ++{ 0x00, 0xce, 0xce }, ++{ 0x00, 0xcf, 0xcf }, ++{ 0x00, 0xd0, 0xd0 }, ++{ 0x00, 0xd1, 0xd1 }, ++{ 0x00, 0xd2, 0xd2 }, ++{ 0x00, 0xd3, 0xd3 }, ++{ 0x00, 0xd4, 0xd4 }, ++{ 0x00, 0xd5, 0xd5 }, ++{ 0x00, 0xd6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x00, 0xd8, 0xd8 }, ++{ 0x00, 0xd9, 0xd9 }, ++{ 0x00, 0xda, 0xda }, ++{ 0x00, 0xdb, 0xdb }, ++{ 0x00, 0xdc, 0xdc }, ++{ 0x00, 0xdd, 0xdd }, ++{ 0x00, 0xde, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xe0 }, ++{ 0x00, 0xe1, 0xe1 }, ++{ 0x00, 0xe2, 0xe2 }, ++{ 0x00, 0xe3, 0xe3 }, ++{ 0x00, 0xe4, 0xe4 }, ++{ 0x00, 0xe5, 0xe5 }, ++{ 0x00, 0xe6, 0xe6 }, ++{ 0x00, 0xe7, 0xe7 }, ++{ 0x00, 0xe8, 0xe8 }, ++{ 0x00, 0xe9, 0xe9 }, ++{ 0x00, 0xea, 0xea }, ++{ 0x00, 0xeb, 0xeb }, ++{ 0x00, 0xec, 0xec }, ++{ 0x00, 0xed, 0xed }, ++{ 0x00, 0xee, 0xee }, ++{ 0x00, 0xef, 0xef }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xf1 }, ++{ 0x00, 0xf2, 0xf2 }, ++{ 0x00, 0xf3, 0xf3 }, ++{ 0x00, 0xf4, 0xf4 }, ++{ 0x00, 0xf5, 0xf5 }, ++{ 0x00, 0xf6, 0xf6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xf8 }, ++{ 0x00, 0xf9, 0xf9 }, ++{ 0x00, 0xfa, 0xfa }, ++{ 0x00, 0xfb, 0xfb }, ++{ 0x00, 0xfc, 0xfc }, ++{ 0x00, 0xfd, 0xfd }, ++{ 0x00, 0xfe, 0xfe }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info koi8r_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xb3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x01, 0xa3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xe0 }, ++{ 0x00, 0xc1, 0xe1 }, ++{ 0x00, 0xc2, 0xe2 }, ++{ 0x00, 0xc3, 0xe3 }, ++{ 0x00, 0xc4, 0xe4 }, ++{ 0x00, 0xc5, 0xe5 }, ++{ 0x00, 0xc6, 0xe6 }, ++{ 0x00, 0xc7, 0xe7 }, ++{ 0x00, 0xc8, 0xe8 }, ++{ 0x00, 0xc9, 0xe9 }, ++{ 0x00, 0xca, 0xea }, ++{ 0x00, 0xcb, 0xeb }, ++{ 0x00, 0xcc, 0xec }, ++{ 0x00, 0xcd, 0xed }, ++{ 0x00, 0xce, 0xee }, ++{ 0x00, 0xcf, 0xef }, ++{ 0x00, 0xd0, 0xf0 }, ++{ 0x00, 0xd1, 0xf1 }, ++{ 0x00, 0xd2, 0xf2 }, ++{ 0x00, 0xd3, 0xf3 }, ++{ 0x00, 0xd4, 0xf4 }, ++{ 0x00, 0xd5, 0xf5 }, ++{ 0x00, 0xd6, 0xf6 }, ++{ 0x00, 0xd7, 0xf7 }, ++{ 0x00, 0xd8, 0xf8 }, ++{ 0x00, 0xd9, 0xf9 }, ++{ 0x00, 0xda, 0xfa }, ++{ 0x00, 0xdb, 0xfb }, ++{ 0x00, 0xdc, 0xfc }, ++{ 0x00, 0xdd, 0xfd }, ++{ 0x00, 0xde, 0xfe }, ++{ 0x00, 0xdf, 0xff }, ++{ 0x01, 0xc0, 0xe0 }, ++{ 0x01, 0xc1, 0xe1 }, ++{ 0x01, 0xc2, 0xe2 }, ++{ 0x01, 0xc3, 0xe3 }, ++{ 0x01, 0xc4, 0xe4 }, ++{ 0x01, 0xc5, 0xe5 }, ++{ 0x01, 0xc6, 0xe6 }, ++{ 0x01, 0xc7, 0xe7 }, ++{ 0x01, 0xc8, 0xe8 }, ++{ 0x01, 0xc9, 0xe9 }, ++{ 0x01, 0xca, 0xea }, ++{ 0x01, 0xcb, 0xeb }, ++{ 0x01, 0xcc, 0xec }, ++{ 0x01, 0xcd, 0xed }, ++{ 0x01, 0xce, 0xee }, ++{ 0x01, 0xcf, 0xef }, ++{ 0x01, 0xd0, 0xf0 }, ++{ 0x01, 0xd1, 0xf1 }, ++{ 0x01, 0xd2, 0xf2 }, ++{ 0x01, 0xd3, 0xf3 }, ++{ 0x01, 0xd4, 0xf4 }, ++{ 0x01, 0xd5, 0xf5 }, ++{ 0x01, 0xd6, 0xf6 }, ++{ 0x01, 0xd7, 0xf7 }, ++{ 0x01, 0xd8, 0xf8 }, ++{ 0x01, 0xd9, 0xf9 }, ++{ 0x01, 0xda, 0xfa }, ++{ 0x01, 0xdb, 0xfb }, ++{ 0x01, 0xdc, 0xfc }, ++{ 0x01, 0xdd, 0xfd }, ++{ 0x01, 0xde, 0xfe }, ++{ 0x01, 0xdf, 0xff }, ++}; ++ ++struct cs_info koi8u_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xb3 }, ++{ 0x00, 0xa4, 0xb4 }, /* ie */ ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xb6 }, /* i */ ++{ 0x00, 0xa7, 0xb7 }, /* ii */ ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xbd }, /* g'' */ ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x01, 0xa3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, /* IE */ ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, /* I */ ++{ 0x00, 0xb7, 0xb7 }, /* II */ ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xe0 }, ++{ 0x00, 0xc1, 0xe1 }, ++{ 0x00, 0xc2, 0xe2 }, ++{ 0x00, 0xc3, 0xe3 }, ++{ 0x00, 0xc4, 0xe4 }, ++{ 0x00, 0xc5, 0xe5 }, ++{ 0x00, 0xc6, 0xe6 }, ++{ 0x00, 0xc7, 0xe7 }, ++{ 0x00, 0xc8, 0xe8 }, ++{ 0x00, 0xc9, 0xe9 }, ++{ 0x00, 0xca, 0xea }, ++{ 0x00, 0xcb, 0xeb }, ++{ 0x00, 0xcc, 0xec }, ++{ 0x00, 0xcd, 0xed }, ++{ 0x00, 0xce, 0xee }, ++{ 0x00, 0xcf, 0xef }, ++{ 0x00, 0xd0, 0xf0 }, ++{ 0x00, 0xd1, 0xf1 }, ++{ 0x00, 0xd2, 0xf2 }, ++{ 0x00, 0xd3, 0xf3 }, ++{ 0x00, 0xd4, 0xf4 }, ++{ 0x00, 0xd5, 0xf5 }, ++{ 0x00, 0xd6, 0xf6 }, ++{ 0x00, 0xd7, 0xf7 }, ++{ 0x00, 0xd8, 0xf8 }, ++{ 0x00, 0xd9, 0xf9 }, ++{ 0x00, 0xda, 0xfa }, ++{ 0x00, 0xdb, 0xfb }, ++{ 0x00, 0xdc, 0xfc }, ++{ 0x00, 0xdd, 0xfd }, ++{ 0x00, 0xde, 0xfe }, ++{ 0x00, 0xdf, 0xff }, ++{ 0x01, 0xc0, 0xe0 }, ++{ 0x01, 0xc1, 0xe1 }, ++{ 0x01, 0xc2, 0xe2 }, ++{ 0x01, 0xc3, 0xe3 }, ++{ 0x01, 0xc4, 0xe4 }, ++{ 0x01, 0xc5, 0xe5 }, ++{ 0x01, 0xc6, 0xe6 }, ++{ 0x01, 0xc7, 0xe7 }, ++{ 0x01, 0xc8, 0xe8 }, ++{ 0x01, 0xc9, 0xe9 }, ++{ 0x01, 0xca, 0xea }, ++{ 0x01, 0xcb, 0xeb }, ++{ 0x01, 0xcc, 0xec }, ++{ 0x01, 0xcd, 0xed }, ++{ 0x01, 0xce, 0xee }, ++{ 0x01, 0xcf, 0xef }, ++{ 0x01, 0xd0, 0xf0 }, ++{ 0x01, 0xd1, 0xf1 }, ++{ 0x01, 0xd2, 0xf2 }, ++{ 0x01, 0xd3, 0xf3 }, ++{ 0x01, 0xd4, 0xf4 }, ++{ 0x01, 0xd5, 0xf5 }, ++{ 0x01, 0xd6, 0xf6 }, ++{ 0x01, 0xd7, 0xf7 }, ++{ 0x01, 0xd8, 0xf8 }, ++{ 0x01, 0xd9, 0xf9 }, ++{ 0x01, 0xda, 0xfa }, ++{ 0x01, 0xdb, 0xfb }, ++{ 0x01, 0xdc, 0xfc }, ++{ 0x01, 0xdd, 0xfd }, ++{ 0x01, 0xde, 0xfe }, ++{ 0x01, 0xdf, 0xff }, ++}; ++ ++struct cs_info cp1251_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x01, 0x90, 0x80 }, ++{ 0x01, 0x83, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x81 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x01, 0x9a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x01, 0x9c, 0x8c }, ++{ 0x01, 0x9d, 0x8d }, ++{ 0x01, 0x9e, 0x8e }, ++{ 0x01, 0x9f, 0x8f }, ++{ 0x00, 0x90, 0x80 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x8a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x8c }, ++{ 0x00, 0x9d, 0x8d }, ++{ 0x00, 0x9e, 0x8e }, ++{ 0x00, 0x9f, 0x8f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xa2, 0xa1 }, ++{ 0x00, 0xa2, 0xa1 }, ++{ 0x01, 0xbc, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x01, 0xb4, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x01, 0xb8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x01, 0xba, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x01, 0xbf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x01, 0xb3, 0xb2 }, ++{ 0x00, 0xb3, 0xb2 }, ++{ 0x00, 0xb4, 0xa5 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xa8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xaa }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xa3 }, ++{ 0x01, 0xbe, 0xbd }, ++{ 0x00, 0xbe, 0xbd }, ++{ 0x00, 0xbf, 0xaf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x01, 0xf7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x01, 0xff, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xd7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xdf }, ++}; ++ ++struct cs_info iso13_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0A, 0x0A }, ++{ 0x00, 0x0B, 0x0B }, ++{ 0x00, 0x0C, 0x0C }, ++{ 0x00, 0x0D, 0x0D }, ++{ 0x00, 0x0E, 0x0E }, ++{ 0x00, 0x0F, 0x0F }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1A, 0x1A }, ++{ 0x00, 0x1B, 0x1B }, ++{ 0x00, 0x1C, 0x1C }, ++{ 0x00, 0x1D, 0x1D }, ++{ 0x00, 0x1E, 0x1E }, ++{ 0x00, 0x1F, 0x1F }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2A, 0x2A }, ++{ 0x00, 0x2B, 0x2B }, ++{ 0x00, 0x2C, 0x2C }, ++{ 0x00, 0x2D, 0x2D }, ++{ 0x00, 0x2E, 0x2E }, ++{ 0x00, 0x2F, 0x2F }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3A, 0x3A }, ++{ 0x00, 0x3B, 0x3B }, ++{ 0x00, 0x3C, 0x3C }, ++{ 0x00, 0x3D, 0x3D }, ++{ 0x00, 0x3E, 0x3E }, ++{ 0x00, 0x3F, 0x3F }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6A, 0x4A }, ++{ 0x01, 0x6B, 0x4B }, ++{ 0x01, 0x6C, 0x4C }, ++{ 0x01, 0x6D, 0x4D }, ++{ 0x01, 0x6E, 0x4E }, ++{ 0x01, 0x6F, 0x4F }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7A, 0x5A }, ++{ 0x00, 0x5B, 0x5B }, ++{ 0x00, 0x5C, 0x5C }, ++{ 0x00, 0x5D, 0x5D }, ++{ 0x00, 0x5E, 0x5E }, ++{ 0x00, 0x5F, 0x5F }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6A, 0x4A }, ++{ 0x00, 0x6B, 0x4B }, ++{ 0x00, 0x6C, 0x4C }, ++{ 0x00, 0x6D, 0x4D }, ++{ 0x00, 0x6E, 0x4E }, ++{ 0x00, 0x6F, 0x4F }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7A, 0x5A }, ++{ 0x00, 0x7B, 0x7B }, ++{ 0x00, 0x7C, 0x7C }, ++{ 0x00, 0x7D, 0x7D }, ++{ 0x00, 0x7E, 0x7E }, ++{ 0x00, 0x7F, 0x7F }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8A, 0x8A }, ++{ 0x00, 0x8B, 0x8B }, ++{ 0x00, 0x8C, 0x8C }, ++{ 0x00, 0x8D, 0x8D }, ++{ 0x00, 0x8E, 0x8E }, ++{ 0x00, 0x8F, 0x8F }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9A, 0x9A }, ++{ 0x00, 0x9B, 0x9B }, ++{ 0x00, 0x9C, 0x9C }, ++{ 0x00, 0x9D, 0x9D }, ++{ 0x00, 0x9E, 0x9E }, ++{ 0x00, 0x9F, 0x9F }, ++{ 0x00, 0xA0, 0xA0 }, ++{ 0x00, 0xA1, 0xA1 }, ++{ 0x00, 0xA2, 0xA2 }, ++{ 0x00, 0xA3, 0xA3 }, ++{ 0x00, 0xA4, 0xA4 }, ++{ 0x00, 0xA5, 0xA5 }, ++{ 0x00, 0xA6, 0xA6 }, ++{ 0x00, 0xA7, 0xA7 }, ++{ 0x01, 0xB8, 0xA8 }, ++{ 0x00, 0xA9, 0xA9 }, ++{ 0x01, 0xBA, 0xAA }, ++{ 0x00, 0xAB, 0xAB }, ++{ 0x00, 0xAC, 0xAC }, ++{ 0x00, 0xAD, 0xAD }, ++{ 0x00, 0xAE, 0xAE }, ++{ 0x01, 0xBF, 0xAF }, ++{ 0x00, 0xB0, 0xB0 }, ++{ 0x00, 0xB1, 0xB1 }, ++{ 0x00, 0xB2, 0xB2 }, ++{ 0x00, 0xB3, 0xB3 }, ++{ 0x00, 0xB4, 0xB4 }, ++{ 0x00, 0xB5, 0xB5 }, ++{ 0x00, 0xB6, 0xB6 }, ++{ 0x00, 0xB7, 0xB7 }, ++{ 0x00, 0xB8, 0xA8 }, ++{ 0x00, 0xB9, 0xB9 }, ++{ 0x00, 0xBA, 0xAA }, ++{ 0x00, 0xBB, 0xBB }, ++{ 0x00, 0xBC, 0xBC }, ++{ 0x00, 0xBD, 0xBD }, ++{ 0x00, 0xBE, 0xBE }, ++{ 0x00, 0xBF, 0xAF }, ++{ 0x01, 0xE0, 0xC0 }, ++{ 0x01, 0xE1, 0xC1 }, ++{ 0x01, 0xE2, 0xC2 }, ++{ 0x01, 0xE3, 0xC3 }, ++{ 0x01, 0xE4, 0xC4 }, ++{ 0x01, 0xE5, 0xC5 }, ++{ 0x01, 0xE6, 0xC6 }, ++{ 0x01, 0xE7, 0xC7 }, ++{ 0x01, 0xE8, 0xC8 }, ++{ 0x01, 0xE9, 0xC9 }, ++{ 0x01, 0xEA, 0xCA }, ++{ 0x01, 0xEB, 0xCB }, ++{ 0x01, 0xEC, 0xCC }, ++{ 0x01, 0xED, 0xCD }, ++{ 0x01, 0xEE, 0xCE }, ++{ 0x01, 0xEF, 0xCF }, ++{ 0x01, 0xF0, 0xD0 }, ++{ 0x01, 0xF1, 0xD1 }, ++{ 0x01, 0xF2, 0xD2 }, ++{ 0x01, 0xF3, 0xD3 }, ++{ 0x01, 0xF4, 0xD4 }, ++{ 0x01, 0xF5, 0xD5 }, ++{ 0x01, 0xF6, 0xD6 }, ++{ 0x00, 0xD7, 0xD7 }, ++{ 0x01, 0xF8, 0xD8 }, ++{ 0x01, 0xF9, 0xD9 }, ++{ 0x01, 0xFA, 0xDA }, ++{ 0x01, 0xFB, 0xDB }, ++{ 0x01, 0xFC, 0xDC }, ++{ 0x01, 0xFD, 0xDD }, ++{ 0x01, 0xFE, 0xDE }, ++{ 0x00, 0xDF, 0xDF }, ++{ 0x00, 0xE0, 0xC0 }, ++{ 0x00, 0xE1, 0xC1 }, ++{ 0x00, 0xE2, 0xC2 }, ++{ 0x00, 0xE3, 0xC3 }, ++{ 0x00, 0xE4, 0xC4 }, ++{ 0x00, 0xE5, 0xC5 }, ++{ 0x00, 0xE6, 0xC6 }, ++{ 0x00, 0xE7, 0xC7 }, ++{ 0x00, 0xE8, 0xC8 }, ++{ 0x00, 0xE9, 0xC9 }, ++{ 0x00, 0xEA, 0xCA }, ++{ 0x00, 0xEB, 0xCB }, ++{ 0x00, 0xEC, 0xCC }, ++{ 0x00, 0xED, 0xCD }, ++{ 0x00, 0xEE, 0xCE }, ++{ 0x00, 0xEF, 0xCF }, ++{ 0x00, 0xF0, 0xD0 }, ++{ 0x00, 0xF1, 0xD1 }, ++{ 0x00, 0xF2, 0xD2 }, ++{ 0x00, 0xF3, 0xD3 }, ++{ 0x00, 0xF4, 0xD4 }, ++{ 0x00, 0xF5, 0xD5 }, ++{ 0x00, 0xF6, 0xD6 }, ++{ 0x00, 0xF7, 0xF7 }, ++{ 0x00, 0xF8, 0xD8 }, ++{ 0x00, 0xF9, 0xD9 }, ++{ 0x00, 0xFA, 0xDA }, ++{ 0x00, 0xFB, 0xDB }, ++{ 0x00, 0xFC, 0xDC }, ++{ 0x00, 0xFD, 0xDD }, ++{ 0x00, 0xFE, 0xDE }, ++{ 0x00, 0xFF, 0xFF }, ++}; ++ ++ ++struct cs_info iso14_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x01, 0xa2, 0xa1 }, ++{ 0x00, 0xa2, 0xa1 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x01, 0xa5, 0xa4 }, ++{ 0x00, 0xa5, 0xa4 }, ++{ 0x01, 0xa6, 0xab }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x01, 0xb8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x01, 0xba, 0xaa }, ++{ 0x00, 0xab, 0xa6 }, ++{ 0x01, 0xbc, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x01, 0xff, 0xaf }, ++{ 0x01, 0xb1, 0xb0 }, ++{ 0x00, 0xb1, 0xb0 }, ++{ 0x01, 0xb3, 0xb2 }, ++{ 0x00, 0xb3, 0xb2 }, ++{ 0x01, 0xb5, 0xb4 }, ++{ 0x00, 0xb5, 0xb4 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x01, 0xb9, 0xb7 }, ++{ 0x00, 0xb8, 0xa8 }, ++{ 0x00, 0xb9, 0xb6 }, ++{ 0x00, 0xba, 0xaa }, ++{ 0x01, 0xbf, 0xbb }, ++{ 0x00, 0xbc, 0xac }, ++{ 0x01, 0xbe, 0xbd }, ++{ 0x00, 0xbe, 0xbd }, ++{ 0x00, 0xbf, 0xbb }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x01, 0xf7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xd7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct cs_info iso15_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x01, 0xa8, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa6 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x01, 0xb8, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb4 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x01, 0xbd, 0xbc }, ++{ 0x00, 0xbd, 0xbc }, ++{ 0x01, 0xff, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x01, 0xe0, 0xc0 }, ++{ 0x01, 0xe1, 0xc1 }, ++{ 0x01, 0xe2, 0xc2 }, ++{ 0x01, 0xe3, 0xc3 }, ++{ 0x01, 0xe4, 0xc4 }, ++{ 0x01, 0xe5, 0xc5 }, ++{ 0x01, 0xe6, 0xc6 }, ++{ 0x01, 0xe7, 0xc7 }, ++{ 0x01, 0xe8, 0xc8 }, ++{ 0x01, 0xe9, 0xc9 }, ++{ 0x01, 0xea, 0xca }, ++{ 0x01, 0xeb, 0xcb }, ++{ 0x01, 0xec, 0xcc }, ++{ 0x01, 0xed, 0xcd }, ++{ 0x01, 0xee, 0xce }, ++{ 0x01, 0xef, 0xcf }, ++{ 0x01, 0xf0, 0xd0 }, ++{ 0x01, 0xf1, 0xd1 }, ++{ 0x01, 0xf2, 0xd2 }, ++{ 0x01, 0xf3, 0xd3 }, ++{ 0x01, 0xf4, 0xd4 }, ++{ 0x01, 0xf5, 0xd5 }, ++{ 0x01, 0xf6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x01, 0xf8, 0xd8 }, ++{ 0x01, 0xf9, 0xd9 }, ++{ 0x01, 0xfa, 0xda }, ++{ 0x01, 0xfb, 0xdb }, ++{ 0x01, 0xfc, 0xdc }, ++{ 0x01, 0xfd, 0xdd }, ++{ 0x01, 0xfe, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xc0 }, ++{ 0x00, 0xe1, 0xc1 }, ++{ 0x00, 0xe2, 0xc2 }, ++{ 0x00, 0xe3, 0xc3 }, ++{ 0x00, 0xe4, 0xc4 }, ++{ 0x00, 0xe5, 0xc5 }, ++{ 0x00, 0xe6, 0xc6 }, ++{ 0x00, 0xe7, 0xc7 }, ++{ 0x00, 0xe8, 0xc8 }, ++{ 0x00, 0xe9, 0xc9 }, ++{ 0x00, 0xea, 0xca }, ++{ 0x00, 0xeb, 0xcb }, ++{ 0x00, 0xec, 0xcc }, ++{ 0x00, 0xed, 0xcd }, ++{ 0x00, 0xee, 0xce }, ++{ 0x00, 0xef, 0xcf }, ++{ 0x00, 0xf0, 0xd0 }, ++{ 0x00, 0xf1, 0xd1 }, ++{ 0x00, 0xf2, 0xd2 }, ++{ 0x00, 0xf3, 0xd3 }, ++{ 0x00, 0xf4, 0xd4 }, ++{ 0x00, 0xf5, 0xd5 }, ++{ 0x00, 0xf6, 0xd6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xd8 }, ++{ 0x00, 0xf9, 0xd9 }, ++{ 0x00, 0xfa, 0xda }, ++{ 0x00, 0xfb, 0xdb }, ++{ 0x00, 0xfc, 0xdc }, ++{ 0x00, 0xfd, 0xdd }, ++{ 0x00, 0xfe, 0xde }, ++{ 0x00, 0xff, 0xbe }, ++}; ++ ++struct cs_info iscii_devanagari_tbl[] = { ++{ 0x00, 0x00, 0x00 }, ++{ 0x00, 0x01, 0x01 }, ++{ 0x00, 0x02, 0x02 }, ++{ 0x00, 0x03, 0x03 }, ++{ 0x00, 0x04, 0x04 }, ++{ 0x00, 0x05, 0x05 }, ++{ 0x00, 0x06, 0x06 }, ++{ 0x00, 0x07, 0x07 }, ++{ 0x00, 0x08, 0x08 }, ++{ 0x00, 0x09, 0x09 }, ++{ 0x00, 0x0a, 0x0a }, ++{ 0x00, 0x0b, 0x0b }, ++{ 0x00, 0x0c, 0x0c }, ++{ 0x00, 0x0d, 0x0d }, ++{ 0x00, 0x0e, 0x0e }, ++{ 0x00, 0x0f, 0x0f }, ++{ 0x00, 0x10, 0x10 }, ++{ 0x00, 0x11, 0x11 }, ++{ 0x00, 0x12, 0x12 }, ++{ 0x00, 0x13, 0x13 }, ++{ 0x00, 0x14, 0x14 }, ++{ 0x00, 0x15, 0x15 }, ++{ 0x00, 0x16, 0x16 }, ++{ 0x00, 0x17, 0x17 }, ++{ 0x00, 0x18, 0x18 }, ++{ 0x00, 0x19, 0x19 }, ++{ 0x00, 0x1a, 0x1a }, ++{ 0x00, 0x1b, 0x1b }, ++{ 0x00, 0x1c, 0x1c }, ++{ 0x00, 0x1d, 0x1d }, ++{ 0x00, 0x1e, 0x1e }, ++{ 0x00, 0x1f, 0x1f }, ++{ 0x00, 0x20, 0x20 }, ++{ 0x00, 0x21, 0x21 }, ++{ 0x00, 0x22, 0x22 }, ++{ 0x00, 0x23, 0x23 }, ++{ 0x00, 0x24, 0x24 }, ++{ 0x00, 0x25, 0x25 }, ++{ 0x00, 0x26, 0x26 }, ++{ 0x00, 0x27, 0x27 }, ++{ 0x00, 0x28, 0x28 }, ++{ 0x00, 0x29, 0x29 }, ++{ 0x00, 0x2a, 0x2a }, ++{ 0x00, 0x2b, 0x2b }, ++{ 0x00, 0x2c, 0x2c }, ++{ 0x00, 0x2d, 0x2d }, ++{ 0x00, 0x2e, 0x2e }, ++{ 0x00, 0x2f, 0x2f }, ++{ 0x00, 0x30, 0x30 }, ++{ 0x00, 0x31, 0x31 }, ++{ 0x00, 0x32, 0x32 }, ++{ 0x00, 0x33, 0x33 }, ++{ 0x00, 0x34, 0x34 }, ++{ 0x00, 0x35, 0x35 }, ++{ 0x00, 0x36, 0x36 }, ++{ 0x00, 0x37, 0x37 }, ++{ 0x00, 0x38, 0x38 }, ++{ 0x00, 0x39, 0x39 }, ++{ 0x00, 0x3a, 0x3a }, ++{ 0x00, 0x3b, 0x3b }, ++{ 0x00, 0x3c, 0x3c }, ++{ 0x00, 0x3d, 0x3d }, ++{ 0x00, 0x3e, 0x3e }, ++{ 0x00, 0x3f, 0x3f }, ++{ 0x00, 0x40, 0x40 }, ++{ 0x01, 0x61, 0x41 }, ++{ 0x01, 0x62, 0x42 }, ++{ 0x01, 0x63, 0x43 }, ++{ 0x01, 0x64, 0x44 }, ++{ 0x01, 0x65, 0x45 }, ++{ 0x01, 0x66, 0x46 }, ++{ 0x01, 0x67, 0x47 }, ++{ 0x01, 0x68, 0x48 }, ++{ 0x01, 0x69, 0x49 }, ++{ 0x01, 0x6a, 0x4a }, ++{ 0x01, 0x6b, 0x4b }, ++{ 0x01, 0x6c, 0x4c }, ++{ 0x01, 0x6d, 0x4d }, ++{ 0x01, 0x6e, 0x4e }, ++{ 0x01, 0x6f, 0x4f }, ++{ 0x01, 0x70, 0x50 }, ++{ 0x01, 0x71, 0x51 }, ++{ 0x01, 0x72, 0x52 }, ++{ 0x01, 0x73, 0x53 }, ++{ 0x01, 0x74, 0x54 }, ++{ 0x01, 0x75, 0x55 }, ++{ 0x01, 0x76, 0x56 }, ++{ 0x01, 0x77, 0x57 }, ++{ 0x01, 0x78, 0x58 }, ++{ 0x01, 0x79, 0x59 }, ++{ 0x01, 0x7a, 0x5a }, ++{ 0x00, 0x5b, 0x5b }, ++{ 0x00, 0x5c, 0x5c }, ++{ 0x00, 0x5d, 0x5d }, ++{ 0x00, 0x5e, 0x5e }, ++{ 0x00, 0x5f, 0x5f }, ++{ 0x00, 0x60, 0x60 }, ++{ 0x00, 0x61, 0x41 }, ++{ 0x00, 0x62, 0x42 }, ++{ 0x00, 0x63, 0x43 }, ++{ 0x00, 0x64, 0x44 }, ++{ 0x00, 0x65, 0x45 }, ++{ 0x00, 0x66, 0x46 }, ++{ 0x00, 0x67, 0x47 }, ++{ 0x00, 0x68, 0x48 }, ++{ 0x00, 0x69, 0x49 }, ++{ 0x00, 0x6a, 0x4a }, ++{ 0x00, 0x6b, 0x4b }, ++{ 0x00, 0x6c, 0x4c }, ++{ 0x00, 0x6d, 0x4d }, ++{ 0x00, 0x6e, 0x4e }, ++{ 0x00, 0x6f, 0x4f }, ++{ 0x00, 0x70, 0x50 }, ++{ 0x00, 0x71, 0x51 }, ++{ 0x00, 0x72, 0x52 }, ++{ 0x00, 0x73, 0x53 }, ++{ 0x00, 0x74, 0x54 }, ++{ 0x00, 0x75, 0x55 }, ++{ 0x00, 0x76, 0x56 }, ++{ 0x00, 0x77, 0x57 }, ++{ 0x00, 0x78, 0x58 }, ++{ 0x00, 0x79, 0x59 }, ++{ 0x00, 0x7a, 0x5a }, ++{ 0x00, 0x7b, 0x7b }, ++{ 0x00, 0x7c, 0x7c }, ++{ 0x00, 0x7d, 0x7d }, ++{ 0x00, 0x7e, 0x7e }, ++{ 0x00, 0x7f, 0x7f }, ++{ 0x00, 0x80, 0x80 }, ++{ 0x00, 0x81, 0x81 }, ++{ 0x00, 0x82, 0x82 }, ++{ 0x00, 0x83, 0x83 }, ++{ 0x00, 0x84, 0x84 }, ++{ 0x00, 0x85, 0x85 }, ++{ 0x00, 0x86, 0x86 }, ++{ 0x00, 0x87, 0x87 }, ++{ 0x00, 0x88, 0x88 }, ++{ 0x00, 0x89, 0x89 }, ++{ 0x00, 0x8a, 0x8a }, ++{ 0x00, 0x8b, 0x8b }, ++{ 0x00, 0x8c, 0x8c }, ++{ 0x00, 0x8d, 0x8d }, ++{ 0x00, 0x8e, 0x8e }, ++{ 0x00, 0x8f, 0x8f }, ++{ 0x00, 0x90, 0x90 }, ++{ 0x00, 0x91, 0x91 }, ++{ 0x00, 0x92, 0x92 }, ++{ 0x00, 0x93, 0x93 }, ++{ 0x00, 0x94, 0x94 }, ++{ 0x00, 0x95, 0x95 }, ++{ 0x00, 0x96, 0x96 }, ++{ 0x00, 0x97, 0x97 }, ++{ 0x00, 0x98, 0x98 }, ++{ 0x00, 0x99, 0x99 }, ++{ 0x00, 0x9a, 0x9a }, ++{ 0x00, 0x9b, 0x9b }, ++{ 0x00, 0x9c, 0x9c }, ++{ 0x00, 0x9d, 0x9d }, ++{ 0x00, 0x9e, 0x9e }, ++{ 0x00, 0x9f, 0x9f }, ++{ 0x00, 0xa0, 0xa0 }, ++{ 0x00, 0xa1, 0xa1 }, ++{ 0x00, 0xa2, 0xa2 }, ++{ 0x00, 0xa3, 0xa3 }, ++{ 0x00, 0xa4, 0xa4 }, ++{ 0x00, 0xa5, 0xa5 }, ++{ 0x00, 0xa6, 0xa6 }, ++{ 0x00, 0xa7, 0xa7 }, ++{ 0x00, 0xa8, 0xa8 }, ++{ 0x00, 0xa9, 0xa9 }, ++{ 0x00, 0xaa, 0xaa }, ++{ 0x00, 0xab, 0xab }, ++{ 0x00, 0xac, 0xac }, ++{ 0x00, 0xad, 0xad }, ++{ 0x00, 0xae, 0xae }, ++{ 0x00, 0xaf, 0xaf }, ++{ 0x00, 0xb0, 0xb0 }, ++{ 0x00, 0xb1, 0xb1 }, ++{ 0x00, 0xb2, 0xb2 }, ++{ 0x00, 0xb3, 0xb3 }, ++{ 0x00, 0xb4, 0xb4 }, ++{ 0x00, 0xb5, 0xb5 }, ++{ 0x00, 0xb6, 0xb6 }, ++{ 0x00, 0xb7, 0xb7 }, ++{ 0x00, 0xb8, 0xb8 }, ++{ 0x00, 0xb9, 0xb9 }, ++{ 0x00, 0xba, 0xba }, ++{ 0x00, 0xbb, 0xbb }, ++{ 0x00, 0xbc, 0xbc }, ++{ 0x00, 0xbd, 0xbd }, ++{ 0x00, 0xbe, 0xbe }, ++{ 0x00, 0xbf, 0xbf }, ++{ 0x00, 0xc0, 0xc0 }, ++{ 0x00, 0xc1, 0xc1 }, ++{ 0x00, 0xc2, 0xc2 }, ++{ 0x00, 0xc3, 0xc3 }, ++{ 0x00, 0xc4, 0xc4 }, ++{ 0x00, 0xc5, 0xc5 }, ++{ 0x00, 0xc6, 0xc6 }, ++{ 0x00, 0xc7, 0xc7 }, ++{ 0x00, 0xc8, 0xc8 }, ++{ 0x00, 0xc9, 0xc9 }, ++{ 0x00, 0xca, 0xca }, ++{ 0x00, 0xcb, 0xcb }, ++{ 0x00, 0xcc, 0xcc }, ++{ 0x00, 0xcd, 0xcd }, ++{ 0x00, 0xce, 0xce }, ++{ 0x00, 0xcf, 0xcf }, ++{ 0x00, 0xd0, 0xd0 }, ++{ 0x00, 0xd1, 0xd1 }, ++{ 0x00, 0xd2, 0xd2 }, ++{ 0x00, 0xd3, 0xd3 }, ++{ 0x00, 0xd4, 0xd4 }, ++{ 0x00, 0xd5, 0xd5 }, ++{ 0x00, 0xd6, 0xd6 }, ++{ 0x00, 0xd7, 0xd7 }, ++{ 0x00, 0xd8, 0xd8 }, ++{ 0x00, 0xd9, 0xd9 }, ++{ 0x00, 0xda, 0xda }, ++{ 0x00, 0xdb, 0xdb }, ++{ 0x00, 0xdc, 0xdc }, ++{ 0x00, 0xdd, 0xdd }, ++{ 0x00, 0xde, 0xde }, ++{ 0x00, 0xdf, 0xdf }, ++{ 0x00, 0xe0, 0xe0 }, ++{ 0x00, 0xe1, 0xe1 }, ++{ 0x00, 0xe2, 0xe2 }, ++{ 0x00, 0xe3, 0xe3 }, ++{ 0x00, 0xe4, 0xe4 }, ++{ 0x00, 0xe5, 0xe5 }, ++{ 0x00, 0xe6, 0xe6 }, ++{ 0x00, 0xe7, 0xe7 }, ++{ 0x00, 0xe8, 0xe8 }, ++{ 0x00, 0xe9, 0xe9 }, ++{ 0x00, 0xea, 0xea }, ++{ 0x00, 0xeb, 0xeb }, ++{ 0x00, 0xec, 0xec }, ++{ 0x00, 0xed, 0xed }, ++{ 0x00, 0xee, 0xee }, ++{ 0x00, 0xef, 0xef }, ++{ 0x00, 0xf0, 0xf0 }, ++{ 0x00, 0xf1, 0xf1 }, ++{ 0x00, 0xf2, 0xf2 }, ++{ 0x00, 0xf3, 0xf3 }, ++{ 0x00, 0xf4, 0xf4 }, ++{ 0x00, 0xf5, 0xf5 }, ++{ 0x00, 0xf6, 0xf6 }, ++{ 0x00, 0xf7, 0xf7 }, ++{ 0x00, 0xf8, 0xf8 }, ++{ 0x00, 0xf9, 0xf9 }, ++{ 0x00, 0xfa, 0xfa }, ++{ 0x00, 0xfb, 0xfb }, ++{ 0x00, 0xfc, 0xfc }, ++{ 0x00, 0xfd, 0xfd }, ++{ 0x00, 0xfe, 0xfe }, ++{ 0x00, 0xff, 0xff }, ++}; ++ ++struct enc_entry encds[] = { ++{"ISO8859-1",iso1_tbl}, ++{"ISO8859-2",iso2_tbl}, ++{"ISO8859-3",iso3_tbl}, ++{"ISO8859-4",iso4_tbl}, ++{"ISO8859-5",iso5_tbl}, ++{"ISO8859-6",iso6_tbl}, ++{"ISO8859-7",iso7_tbl}, ++{"ISO8859-8",iso8_tbl}, ++{"ISO8859-9",iso9_tbl}, ++{"ISO8859-10",iso10_tbl}, ++{"KOI8-R",koi8r_tbl}, ++{"KOI8-U",koi8u_tbl}, ++{"microsoft-cp1251",cp1251_tbl}, ++{"ISO8859-13", iso13_tbl}, ++{"ISO8859-14", iso14_tbl}, ++{"ISO8859-15", iso15_tbl}, ++{"ISCII-DEVANAGARI", iscii_devanagari_tbl}, ++}; ++ ++struct cs_info * get_current_cs(const char * es) { ++ struct cs_info * ccs = encds[0].cs_table; ++ int n = sizeof(encds) / sizeof(encds[0]); ++ for (int i = 0; i < n; i++) { ++ if (strcmp(es,encds[i].enc_name) == 0) { ++ ccs = encds[i].cs_table; ++ } ++ } ++ return ccs; ++} ++#else ++// XXX This function was rewritten for mozilla. Instead of storing the ++// conversion tables static in this file, create them when needed ++// with help the mozilla backend. ++struct cs_info * get_current_cs(const char * es) { ++ struct cs_info *ccs; ++ ++ nsCOMPtr encoder; ++ nsCOMPtr decoder; ++ nsCOMPtr caseConv; ++ ++ nsresult rv; ++ nsCOMPtr ccm = do_GetService(kCharsetConverterManagerCID, &rv); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ ++ rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder)); ++ if (encoder && NS_SUCCEEDED(rv)) ++ encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?'); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder)); ++ ++ caseConv = do_GetService(kUnicharUtilCID, &rv); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ ++ ccs = (struct cs_info *) malloc(256 * sizeof(cs_info)); ++ ++ PRInt32 charLength = 256; ++ PRInt32 uniLength = 512; ++ char *source = (char *)malloc(charLength * sizeof(char)); ++ PRUnichar *uni = (PRUnichar *)malloc(uniLength * sizeof(PRUnichar)); ++ char *lower = (char *)malloc(charLength * sizeof(char)); ++ char *upper = (char *)malloc(charLength * sizeof(char)); ++ ++ // Create a long string of all chars. ++ unsigned int i; ++ for (i = 0x00; i <= 0xff ; ++i) { ++ source[i] = i; ++ } ++ ++ // Convert this long string to unicode ++ rv = decoder->Convert(source, &charLength, uni, &uniLength); ++ ++ // Do case conversion stuff, and convert back. ++ caseConv->ToUpper(uni, uni, uniLength); ++ encoder->Convert(uni, &uniLength, upper, &charLength); ++ ++ uniLength = 512; ++ charLength = 256; ++ rv = decoder->Convert(source, &charLength, uni, &uniLength); ++ caseConv->ToLower(uni, uni, uniLength); ++ encoder->Convert(uni, &uniLength, lower, &charLength); ++ ++ // Store ++ for (i = 0x00; i <= 0xff ; ++i) { ++ ccs[i].cupper = upper[i]; ++ ccs[i].clower = lower[i]; ++ ++ if (ccs[i].clower != (unsigned char)i) ++ ccs[i].ccase = true; ++ else ++ ccs[i].ccase = false; ++ ++ } ++ ++ free(source); ++ free(uni); ++ free(lower); ++ free(upper); ++ ++ return ccs; ++} ++#endif ++ ++// primitive isalpha() replacement for tokenization ++char * get_casechars(const char * enc) { ++ struct cs_info * csconv = get_current_cs(enc); ++ char expw[MAXLNLEN]; ++ char * p = expw; ++ for (int i = 0; i <= 255; i++) { ++ if ((csconv[i].cupper != csconv[i].clower)) { ++ *p = (char) i; ++ p++; ++ } ++ } ++ *p = '\0'; ++#ifdef MOZILLA_CLIENT ++ delete csconv; ++#endif ++ return mystrdup(expw); ++} ++ ++ ++ ++struct lang_map lang2enc[] = { ++{"ar", "UTF-8", LANG_ar}, ++{"az", "UTF-8", LANG_az}, ++{"bg", "microsoft-cp1251", LANG_bg}, ++{"ca", "ISO8859-1", LANG_ca}, ++{"cs", "ISO8859-2", LANG_cs}, ++{"da", "ISO8859-1", LANG_da}, ++{"de", "ISO8859-1", LANG_de}, ++{"el", "ISO8859-7", LANG_el}, ++{"en", "ISO8859-1", LANG_en}, ++{"es", "ISO8859-1", LANG_es}, ++{"eu", "ISO8859-1", LANG_eu}, ++{"gl", "ISO8859-1", LANG_gl}, ++{"fr", "ISO8859-15", LANG_fr}, ++{"hr", "ISO8859-2", LANG_hr}, ++{"hu", "ISO8859-2", LANG_hu}, ++{"it", "ISO8859-1", LANG_it}, ++{"la", "ISO8859-1", LANG_la}, ++{"lv", "ISO8859-13", LANG_lv}, ++{"nl", "ISO8859-1", LANG_nl}, ++{"pl", "ISO8859-2", LANG_pl}, ++{"pt", "ISO8859-1", LANG_pt}, ++{"sv", "ISO8859-1", LANG_sv}, ++{"tr", "UTF-8", LANG_tr}, ++{"ru", "KOI8-R", LANG_ru}, ++{"uk", "KOI8-U", LANG_uk} ++}; ++ ++ ++const char * get_default_enc(const char * lang) { ++ int n = sizeof(lang2enc) / sizeof(lang2enc[0]); ++ for (int i = 0; i < n; i++) { ++ if (strcmp(lang,lang2enc[i].lang) == 0) { ++ return lang2enc[i].def_enc; ++ } ++ } ++ return NULL; ++} ++ ++int get_lang_num(const char * lang) { ++ int n = sizeof(lang2enc) / sizeof(lang2enc[0]); ++ for (int i = 0; i < n; i++) { ++ if (strncmp(lang,lang2enc[i].lang,2) == 0) { ++ return lang2enc[i].num; ++ } ++ } ++ return LANG_xx; ++} ++ ++#ifndef OPENOFFICEORG ++#ifndef MOZILLA_CLIENT ++int initialize_utf_tbl() { ++ utf_tbl_count++; ++ if (utf_tbl) return 0; ++ utf_tbl = (unicode_info2 *) malloc(CONTSIZE * sizeof(unicode_info2)); ++ if (utf_tbl) { ++ int j; ++ for (j = 0; j < CONTSIZE; j++) { ++ utf_tbl[j].cletter = 0; ++ utf_tbl[j].clower = (unsigned short) j; ++ utf_tbl[j].cupper = (unsigned short) j; ++ } ++ for (j = 0; j < UTF_LST_LEN; j++) { ++ utf_tbl[utf_lst[j].c].cletter = 1; ++ utf_tbl[utf_lst[j].c].clower = utf_lst[j].clower; ++ utf_tbl[utf_lst[j].c].cupper = utf_lst[j].cupper; ++ } ++ } else return 1; ++ return 0; ++} ++#endif ++#endif ++ ++void free_utf_tbl() { ++ if (utf_tbl_count > 0) utf_tbl_count--; ++ if (utf_tbl && (utf_tbl_count == 0)) { ++ free(utf_tbl); ++ utf_tbl = NULL; ++ } ++} ++ ++#ifdef MOZILLA_CLIENT ++static nsCOMPtr& getcaseConv() ++{ ++ nsresult rv; ++ static nsCOMPtr caseConv = do_GetService(kUnicharUtilCID, &rv); ++ return caseConv; ++} ++#endif ++ ++unsigned short unicodetoupper(unsigned short c, int langnum) ++{ ++ // In Azeri and Turkish, I and i dictinct letters: ++ // There are a dotless lower case i pair of upper `I', ++ // and an upper I with dot pair of lower `i'. ++ if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr))) ++ return 0x0130; ++#ifdef OPENOFFICEORG ++ return u_toupper(c); ++#else ++#ifdef MOZILLA_CLIENT ++ PRUnichar ch2; ++ getcaseConv()->ToUpper((PRUnichar) c, &ch2); ++ return ch2; ++#else ++ return (utf_tbl) ? utf_tbl[c].cupper : c; ++#endif ++#endif ++} ++ ++unsigned short unicodetolower(unsigned short c, int langnum) ++{ ++ // In Azeri and Turkish, I and i dictinct letters: ++ // There are a dotless lower case i pair of upper `I', ++ // and an upper I with dot pair of lower `i'. ++ if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr))) ++ return 0x0131; ++#ifdef OPENOFFICEORG ++ return u_tolower(c); ++#else ++#ifdef MOZILLA_CLIENT ++ PRUnichar ch2; ++ getcaseConv()->ToLower((PRUnichar) c, &ch2); ++ return ch2; ++#else ++ return (utf_tbl) ? utf_tbl[c].clower : c; ++#endif ++#endif ++} ++ ++int unicodeisalpha(unsigned short c) ++{ ++#ifdef OPENOFFICEORG ++ return u_isalpha(c); ++#else ++ return (utf_tbl) ? utf_tbl[c].cletter : 0; ++#endif ++} ++ ++/* get type of capitalization */ ++int get_captype(char * word, int nl, cs_info * csconv) { ++ // now determine the capitalization type of the first nl letters ++ int ncap = 0; ++ int nneutral = 0; ++ int firstcap = 0; ++ ++ for (char * q = word; *q != '\0'; q++) { ++ if (csconv[*((unsigned char *)q)].ccase) ncap++; ++ if (csconv[*((unsigned char *)q)].cupper == csconv[*((unsigned char *)q)].clower) nneutral++; ++ } ++ if (ncap) { ++ firstcap = csconv[*((unsigned char *) word)].ccase; ++ } ++ ++ // now finally set the captype ++ if (ncap == 0) { ++ return NOCAP; ++ } else if ((ncap == 1) && firstcap) { ++ return INITCAP; ++ } else if ((ncap == nl) || ((ncap + nneutral) == nl)) { ++ return ALLCAP; ++ } else if ((ncap > 1) && firstcap) { ++ return HUHINITCAP; ++ } ++ return HUHCAP; ++} ++ ++int get_captype_utf8(w_char * word, int nl, int langnum) { ++ // now determine the capitalization type of the first nl letters ++ int ncap = 0; ++ int nneutral = 0; ++ int firstcap = 0; ++ unsigned short idx; ++ // don't check too long words ++ if (nl >= MAXWORDLEN) return 0; ++ // big Unicode character (non BMP area) ++ if (nl == -1) return NOCAP; ++ for (int i = 0; i < nl; i++) { ++ idx = (word[i].h << 8) + word[i].l; ++ if (idx != unicodetolower(idx, langnum)) ncap++; ++ if (unicodetoupper(idx, langnum) == unicodetolower(idx, langnum)) nneutral++; ++ } ++ if (ncap) { ++ idx = (word[0].h << 8) + word[0].l; ++ firstcap = (idx != unicodetolower(idx, langnum)); ++ } ++ ++ // now finally set the captype ++ if (ncap == 0) { ++ return NOCAP; ++ } else if ((ncap == 1) && firstcap) { ++ return INITCAP; ++ } else if ((ncap == nl) || ((ncap + nneutral) == nl)) { ++ return ALLCAP; ++ } else if ((ncap > 1) && firstcap) { ++ return HUHINITCAP; ++ } ++ return HUHCAP; ++} ++ ++ ++// strip all ignored characters in the string ++void remove_ignored_chars_utf(char * word, unsigned short ignored_chars[], int ignored_len) ++{ ++ w_char w[MAXWORDLEN]; ++ w_char w2[MAXWORDLEN]; ++ int i; ++ int j; ++ int len = u8_u16(w, MAXWORDLEN, word); ++ for (i = 0, j = 0; i < len; i++) { ++ if (!flag_bsearch(ignored_chars, ((unsigned short *) w)[i], ignored_len)) { ++ w2[j] = w[i]; ++ j++; ++ } ++ } ++ if (j < i) u16_u8(word, MAXWORDUTF8LEN, w2, j); ++} ++ ++// strip all ignored characters in the string ++void remove_ignored_chars(char * word, char * ignored_chars) ++{ ++ for (char * p = word; *p != '\0'; p++) { ++ if (!strchr(ignored_chars, *p)) { ++ *word = *p; ++ word++; ++ } ++ } ++ *word = '\0'; ++} ++ ++int parse_string(char * line, char ** out, const char * warnvar) ++{ ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ if (*out) { ++ HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", warnvar); ++ return 1; ++ } ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ *out = mystrdup(piece); ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ HUNSPELL_WARNING(stderr, "error: missing %s information\n", warnvar); ++ return 1; ++ } ++ return 0; ++} ++ ++int parse_array(char * line, char ** out, ++ unsigned short ** out_utf16, int * out_utf16_len, const char * name, int utf8) { ++ if (parse_string(line, out, name)) return 1; ++ if (utf8) { ++ w_char w[MAXWORDLEN]; ++ int n = u8_u16(w, MAXWORDLEN, *out); ++ if (n > 0) { ++ flag_qsort((unsigned short *) w, 0, n); ++ *out_utf16 = (unsigned short *) malloc(n * sizeof(unsigned short)); ++ if (!*out_utf16) return 1; ++ memcpy(*out_utf16, w, n * sizeof(unsigned short)); ++ } ++ *out_utf16_len = n; ++ } ++ return 0; ++} +Index: mozilla/extensions/spellcheck/hunspell/hunspell/csutil.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/csutil.hxx +@@ -0,0 +1,233 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef __CSUTILHXX__ ++#define __CSUTILHXX__ ++ ++// First some base level utility routines ++ ++#define NOCAP 0 ++#define INITCAP 1 ++#define ALLCAP 2 ++#define HUHCAP 3 ++#define HUHINITCAP 4 ++ ++#define FIELD_STEM "st:" ++#define FIELD_POS "po:" ++#define FIELD_SUFF "su:" ++#define FIELD_PREF "pr:" ++#define FIELD_FREQ "fr:" ++#define FIELD_PHON "ph:" ++#define FIELD_HYPH "hy:" ++#define FIELD_COMP "co:" ++ ++// default flags ++#define ONLYUPCASEFLAG 65535 ++ ++typedef struct { ++ unsigned char l; ++ unsigned char h; ++} w_char; ++ ++#define w_char_eq(a,b) (((a).l == (b).l) && ((a).h == (b).h)) ++ ++// convert UTF-16 characters to UTF-8 ++char * u16_u8(char * dest, int size, const w_char * src, int srclen); ++ ++// convert UTF-8 characters to UTF-16 ++int u8_u16(w_char * dest, int size, const char * src); ++ ++// sort 2-byte vector ++void flag_qsort(unsigned short flags[], int begin, int end); ++ ++// binary search in 2-byte vector ++int flag_bsearch(unsigned short flags[], unsigned short flag, int right); ++ ++// remove end of line char(s) ++void mychomp(char * s); ++ ++// duplicate string ++char * mystrdup(const char * s); ++ ++// duplicate reverse of string ++char * myrevstrdup(const char * s); ++ ++// parse into tokens with char delimiter ++char * mystrsep(char ** sptr, const char delim); ++// parse into tokens with char delimiter ++char * mystrsep2(char ** sptr, const char delim); ++ ++// parse into tokens with char delimiter ++char * mystrrep(char *, const char *, const char *); ++ ++// append s to ends of every lines in text ++void strlinecat(char * lines, const char * s); ++ ++// tokenize into lines with new line ++ int line_tok(const char * text, char *** lines); ++ ++// tokenize into lines with new line and uniq in place ++ char * line_uniq(char * text); ++ ++// change \n to c in place ++ char * line_join(char * text, char c); ++ ++// leave only last {[^}]*} pattern in string ++ char * delete_zeros(char * morphout); ++ ++// reverse word ++ int reverseword(char *); ++ ++// reverse word ++ int reverseword_utf(char *); ++ ++// character encoding information ++struct cs_info { ++ unsigned char ccase; ++ unsigned char clower; ++ unsigned char cupper; ++}; ++ ++// two character arrays ++struct replentry { ++ char * pattern; ++ char * pattern2; ++}; ++ ++// Unicode character encoding information ++struct unicode_info { ++ unsigned short c; ++ unsigned short cupper; ++ unsigned short clower; ++}; ++ ++struct unicode_info2 { ++ char cletter; ++ unsigned short cupper; ++ unsigned short clower; ++}; ++ ++int initialize_utf_tbl(); ++void free_utf_tbl(); ++unsigned short unicodetoupper(unsigned short c, int langnum); ++unsigned short unicodetolower(unsigned short c, int langnum); ++int unicodeisalpha(unsigned short c); ++ ++struct enc_entry { ++ const char * enc_name; ++ struct cs_info * cs_table; ++}; ++ ++// language to encoding default map ++ ++struct lang_map { ++ const char * lang; ++ const char * def_enc; ++ int num; ++}; ++ ++struct cs_info * get_current_cs(const char * es); ++ ++const char * get_default_enc(const char * lang); ++ ++// get language identifiers of language codes ++int get_lang_num(const char * lang); ++ ++// get characters of the given 8bit encoding with lower- and uppercase forms ++char * get_casechars(const char * enc); ++ ++// convert null terminated string to all caps using encoding ++void enmkallcap(char * d, const char * p, const char * encoding); ++ ++// convert null terminated string to all little using encoding ++void enmkallsmall(char * d, const char * p, const char * encoding); ++ ++// convert null terminated string to have intial capital using encoding ++void enmkinitcap(char * d, const char * p, const char * encoding); ++ ++// convert null terminated string to all caps ++void mkallcap(char * p, const struct cs_info * csconv); ++ ++// convert null terminated string to all little ++void mkallsmall(char * p, const struct cs_info * csconv); ++ ++// convert null terminated string to have intial capital ++void mkinitcap(char * p, const struct cs_info * csconv); ++ ++// convert first nc characters of UTF-8 string to little ++void mkallsmall_utf(w_char * u, int nc, int langnum); ++ ++// convert first nc characters of UTF-8 string to capital ++void mkallcap_utf(w_char * u, int nc, int langnum); ++ ++// get type of capitalization ++int get_captype(char * q, int nl, cs_info *); ++ ++// get type of capitalization (UTF-8) ++int get_captype_utf8(w_char * q, int nl, int langnum); ++ ++// strip all ignored characters in the string ++void remove_ignored_chars_utf(char * word, unsigned short ignored_chars[], int ignored_len); ++ ++// strip all ignored characters in the string ++void remove_ignored_chars(char * word, char * ignored_chars); ++ ++int parse_string(char * line, char ** out, const char * name); ++ ++int parse_array(char * line, char ** out, ++ unsigned short ** out_utf16, int * out_utf16_len, const char * name, int utf8); ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/hashmgr.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/hashmgr.cpp +@@ -0,0 +1,941 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "hashmgr.hxx" ++#include "csutil.hxx" ++#include "atypes.hxx" ++ ++#ifdef MOZILLA_CLIENT ++#ifdef __SUNPRO_CC // for SunONE Studio compiler ++using namespace std; ++#endif ++#else ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++// build a hash table from a munched word list ++ ++HashMgr::HashMgr(const char * tpath, const char * apath) ++{ ++ tablesize = 0; ++ tableptr = NULL; ++ flag_mode = FLAG_CHAR; ++ complexprefixes = 0; ++ utf8 = 0; ++ langnum = 0; ++ lang = NULL; ++ enc = NULL; ++ csconv = 0; ++ ignorechars = NULL; ++ ignorechars_utf16 = NULL; ++ ignorechars_utf16_len = 0; ++ numaliasf = 0; ++ aliasf = NULL; ++ numaliasm = 0; ++ aliasm = NULL; ++ forbiddenword = FLAG_NULL; // forbidden word signing flag ++ load_config(apath); ++ int ec = load_tables(tpath); ++ if (ec) { ++ /* error condition - what should we do here */ ++ HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n",ec); ++ if (tableptr) { ++ free(tableptr); ++ tableptr = NULL; ++ } ++ tablesize = 0; ++ } ++} ++ ++ ++HashMgr::~HashMgr() ++{ ++ if (tableptr) { ++ // now pass through hash table freeing up everything ++ // go through column by column of the table ++ for (int i=0; i < tablesize; i++) { ++ struct hentry * pt = tableptr[i]; ++ struct hentry * nt = NULL; ++/* if (pt) { ++ if (pt->astr && (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen))) free(pt->astr); ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (pt->description && !aliasm) free(pt->description); ++#endif ++ pt = pt->next; ++ } ++*/ ++ while(pt) { ++ nt = pt->next; ++ if (pt->astr && (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen))) free(pt->astr); ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (pt->description && !aliasm) free(pt->description); ++#endif ++ free(pt); ++ pt = nt; ++ } ++ } ++ free(tableptr); ++ } ++ tablesize = 0; ++ ++ if (aliasf) { ++ for (int j = 0; j < (numaliasf); j++) free(aliasf[j]); ++ free(aliasf); ++ aliasf = NULL; ++ if (aliasflen) { ++ free(aliasflen); ++ aliasflen = NULL; ++ } ++ } ++ if (aliasm) { ++ for (int j = 0; j < (numaliasm); j++) free(aliasm[j]); ++ free(aliasm); ++ aliasm = NULL; ++ } ++ ++#ifndef OPENOFFICEORG ++#ifndef MOZILLA_CLIENT ++ if (utf8) free_utf_tbl(); ++#endif ++#endif ++ ++ if (enc) free(enc); ++ if (lang) free(lang); ++ ++ if (ignorechars) free(ignorechars); ++ if (ignorechars_utf16) free(ignorechars_utf16); ++} ++ ++// lookup a root word in the hashtable ++ ++struct hentry * HashMgr::lookup(const char *word) const ++{ ++ struct hentry * dp; ++ if (tableptr) { ++ dp = tableptr[hash(word)]; ++ if (!dp) return NULL; ++ for ( ; dp != NULL; dp = dp->next) { ++ if (strcmp(word,&(dp->word)) == 0) return dp; ++ } ++ } ++ return NULL; ++} ++ ++// add a word to the hash table (private) ++int HashMgr::add_word(const char * word, int wbl, int wcl, unsigned short * aff, ++ int al, const char * desc, bool onlyupcase) ++{ ++ bool upcasehomonym = false; ++ int descl = (desc) ? strlen(desc) : 0; ++ // variable-length hash record with word and optional fields ++ // instead of mmap implementation temporarily ++ struct hentry* hp = ++ (struct hentry *) malloc (sizeof(struct hentry) + wbl + descl + 1); ++ if (!hp) return 1; ++ char * hpw = &(hp->word); ++ strcpy(hpw, word); ++ if (desc && strncmp(desc, FIELD_PHON, strlen(FIELD_PHON)) == 0) { ++ strcpy(hpw + wbl + 1, desc + strlen(FIELD_PHON)); ++ hp->var = 1; ++ } else { ++ hp->var = 0; ++ } ++ if (ignorechars != NULL) { ++ if (utf8) { ++ remove_ignored_chars_utf(hpw, ignorechars_utf16, ignorechars_utf16_len); ++ } else { ++ remove_ignored_chars(hpw, ignorechars); ++ } ++ } ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(hpw); else reverseword(hpw); ++ } ++ ++ int i = hash(hpw); ++ ++ hp->blen = (unsigned char) wbl; ++ hp->clen = (unsigned char) wcl; ++ hp->alen = (short) al; ++ hp->astr = aff; ++ hp->next = NULL; ++ hp->next_homonym = NULL; ++#ifdef HUNSPELL_EXPERIMENTAL ++ if (aliasm) { ++ hp->description = (desc) ? get_aliasm(atoi(desc)) : mystrdup(desc); ++ } else { ++ hp->description = mystrdup(desc); ++ if (desc && !hp->description) ++ { ++ free(hp->astr); ++ free(hp); ++ return 1; ++ } ++ if (hp->description && complexprefixes) { ++ if (utf8) reverseword_utf(hp->description); else reverseword(hp->description); ++ } ++ } ++#endif ++ ++ struct hentry * dp = tableptr[i]; ++ if (!dp) { ++ tableptr[i] = hp; ++ return 0; ++ } ++ while (dp->next != NULL) { ++ if ((!dp->next_homonym) && (strcmp(&(hp->word), &(dp->word)) == 0)) { ++ // remove hidden onlyupcase homonym ++ if (!onlyupcase) { ++ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { ++ free(dp->astr); ++ dp->astr = hp->astr; ++ dp->alen = hp->alen; ++ free(hp); ++ return 0; ++ } else { ++ dp->next_homonym = hp; ++ } ++ } else { ++ upcasehomonym = true; ++ } ++ } ++ dp=dp->next; ++ } ++ if (strcmp(&(hp->word), &(dp->word)) == 0) { ++ // remove hidden onlyupcase homonym ++ if (!onlyupcase) { ++ if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { ++ free(dp->astr); ++ dp->astr = hp->astr; ++ dp->alen = hp->alen; ++ free(hp); ++ return 0; ++ } else { ++ dp->next_homonym = hp; ++ } ++ } else { ++ upcasehomonym = true; ++ } ++ } ++ if (!upcasehomonym) { ++ dp->next = hp; ++ } else { ++ // remove hidden onlyupcase homonym ++ if (hp->astr) free(hp->astr); ++ free(hp); ++ } ++ return 0; ++} ++ ++int HashMgr::add_hidden_capitalized_word(char * word, int wbl, int wcl, ++ unsigned short * flags, int al, char * dp, int captype) ++{ ++ // add inner capitalized forms to handle the following allcap forms: ++ // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG ++ // Allcaps with suffixes: CIA's -> CIA'S ++ if (((captype == HUHCAP) || (captype == HUHINITCAP) || ++ ((captype == ALLCAP) && (flags != NULL))) && ++ !((flags != NULL) && TESTAFF(flags, forbiddenword, al))) { ++ unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (al+1)); ++ if (!flags2) return 1; ++ if (al) memcpy(flags2, flags, al * sizeof(unsigned short)); ++ flags2[al] = ONLYUPCASEFLAG; ++ if (utf8) { ++ char st[MAXDELEN]; ++ w_char w[MAXDELEN]; ++ int wlen = u8_u16(w, MAXDELEN, word); ++ mkallsmall_utf(w, wlen, langnum); ++ mkallcap_utf(w, 1, langnum); ++ u16_u8(st, MAXDELEN, w, wlen); ++ return add_word(st,wbl,wcl,flags2,al+1,dp, true); ++ } else { ++ mkallsmall(word, csconv); ++ mkinitcap(word, csconv); ++ return add_word(word,wbl,wcl,flags2,al+1,dp, true); ++ } ++ } ++ return 0; ++} ++ ++// detect captype and modify word length for UTF-8 encoding ++int HashMgr::get_clen_and_captype(const char * word, int wbl, int * captype) { ++ int len; ++ if (utf8) { ++ w_char dest_utf[MAXDELEN]; ++ len = u8_u16(dest_utf, MAXDELEN, word); ++ *captype = get_captype_utf8(dest_utf, len, langnum); ++ } else { ++ len = wbl; ++ *captype = get_captype((char *) word, len, csconv); ++ } ++ return len; ++} ++ ++// add a custom dic. word to the hash table (public) ++int HashMgr::put_word(const char * word, char * aff) ++{ ++ unsigned short * flags; ++ int al = 0; ++ if (aff) { ++ al = decode_flags(&flags, aff); ++ flag_qsort(flags, 0, al); ++ } else { ++ flags = NULL; ++ } ++ ++ int captype; ++ int wbl = strlen(word); ++ int wcl = get_clen_and_captype(word, wbl, &captype); ++ add_word(word, wbl, wcl, flags, al, NULL, false); ++ return add_hidden_capitalized_word((char *) word, wbl, wcl, flags, al, NULL, captype); ++} ++ ++int HashMgr::put_word_pattern(const char * word, const char * pattern) ++{ ++ // detect captype and modify word length for UTF-8 encoding ++ struct hentry * dp = lookup(pattern); ++ if (dp && dp->astr) { ++ int captype; ++ int wbl = strlen(word); ++ int wcl = get_clen_and_captype(word, wbl, &captype); ++ if (aliasf) { ++ add_word(word, wbl, wcl, dp->astr, dp->alen, NULL, false); ++ } else { ++ unsigned short * flags = (unsigned short *) malloc (dp->alen * sizeof(short)); ++ if (flags) { ++ memcpy((void *) flags, (void *) dp->astr, dp->alen * sizeof(short)); ++ add_word(word, wbl, wcl, flags, dp->alen, NULL, false); ++ } else return 1; ++ } ++ return add_hidden_capitalized_word((char *) word, wbl, wcl, dp->astr, dp->alen, NULL, captype); ++ } ++ return 1; ++} ++ ++// walk the hash table entry by entry - null at end ++// initialize: col=-1; hp = NULL; hp = walk_hashtable(&col, hp); ++struct hentry * HashMgr::walk_hashtable(int &col, struct hentry * hp) const ++{ ++ if (hp && hp->next != NULL) return hp->next; ++ for (col++; col < tablesize; col++) { ++ if (tableptr[col]) return tableptr[col]; ++ } ++ // null at end and reset to start ++ col = -1; ++ return NULL; ++} ++ ++// load a munched word list and build a hash table on the fly ++int HashMgr::load_tables(const char * tpath) ++{ ++ int al; ++ char * ap; ++ char * dp; ++ unsigned short * flags; ++ ++ // raw dictionary - munched file ++ FILE * rawdict = fopen(tpath, "r"); ++ if (rawdict == NULL) return 1; ++ ++ // first read the first line of file to get hash table size */ ++ char ts[MAXDELEN]; ++ if (! fgets(ts, MAXDELEN-1,rawdict)) { ++ HUNSPELL_WARNING(stderr, "error: empty dic file\n"); ++ fclose(rawdict); ++ return 2; ++ } ++ mychomp(ts); ++ ++ /* remove byte order mark */ ++ if (strncmp(ts,"\xEF\xBB\xBF",3) == 0) { ++ memmove(ts, ts+3, strlen(ts+3)+1); ++ HUNSPELL_WARNING(stderr, "warning: dic file begins with byte order mark: possible incompatibility with old Hunspell versions\n"); ++ } ++ ++ if ((*ts < '1') || (*ts > '9')) HUNSPELL_WARNING(stderr, "error - missing word count in dictionary file\n"); ++ tablesize = atoi(ts); ++ if (!tablesize) { ++ fclose(rawdict); ++ return 4; ++ } ++ tablesize = tablesize + 5 + USERWORD; ++ if ((tablesize %2) == 0) tablesize++; ++ ++ // allocate the hash table ++ tableptr = (struct hentry **) malloc(tablesize * sizeof(struct hentry *)); ++ if (! tableptr) { ++ fclose(rawdict); ++ return 3; ++ } ++ for (int i=0; i 1x 2y Zz) ++ len = strlen(flags); ++ if (len%2 == 1) HUNSPELL_WARNING(stderr, "error: length of FLAG_LONG flagvector is odd: %s\n", flags); ++ len /= 2; ++ *result = (unsigned short *) malloc(len * sizeof(short)); ++ if (!*result) return -1; ++ for (int i = 0; i < len; i++) { ++ (*result)[i] = (((unsigned short) flags[i * 2]) << 8) + (unsigned short) flags[i * 2 + 1]; ++ } ++ break; ++ } ++ case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521 23 233) ++ len = 1; ++ char * src = flags; ++ unsigned short * dest; ++ char * p; ++ for (p = flags; *p; p++) { ++ if (*p == ',') len++; ++ } ++ *result = (unsigned short *) malloc(len * sizeof(short)); ++ if (!*result) return -1; ++ dest = *result; ++ for (p = flags; *p; p++) { ++ if (*p == ',') { ++ *dest = (unsigned short) atoi(src); ++ if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); ++ src = p + 1; ++ dest++; ++ } ++ } ++ *dest = (unsigned short) atoi(src); ++ if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); ++ break; ++ } ++ case FLAG_UNI: { // UTF-8 characters ++ w_char w[MAXDELEN/2]; ++ len = u8_u16(w, MAXDELEN/2, flags); ++ *result = (unsigned short *) malloc(len * sizeof(short)); ++ if (!*result) return -1; ++ memcpy(*result, w, len * sizeof(short)); ++ break; ++ } ++ default: { // Ispell's one-character flags (erfg -> e r f g) ++ unsigned short * dest; ++ len = strlen(flags); ++ *result = (unsigned short *) malloc(len * sizeof(short)); ++ if (!*result) return -1; ++ dest = *result; ++ for (unsigned char * p = (unsigned char *) flags; *p; p++) { ++ *dest = (unsigned short) *p; ++ dest++; ++ } ++ } ++ } ++ return len; ++} ++ ++unsigned short HashMgr::decode_flag(const char * f) { ++ unsigned short s = 0; ++ switch (flag_mode) { ++ case FLAG_LONG: ++ s = ((unsigned short) f[0] << 8) + (unsigned short) f[1]; ++ break; ++ case FLAG_NUM: ++ s = (unsigned short) atoi(f); ++ break; ++ case FLAG_UNI: ++ u8_u16((w_char *) &s, 1, f); ++ break; ++ default: ++ s = (unsigned short) *((unsigned char *)f); ++ } ++ if (!s) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); ++ return s; ++} ++ ++char * HashMgr::encode_flag(unsigned short f) { ++ unsigned char ch[10]; ++ if (f==0) return mystrdup("(NULL)"); ++ if (flag_mode == FLAG_LONG) { ++ ch[0] = (unsigned char) (f >> 8); ++ ch[1] = (unsigned char) (f - ((f >> 8) << 8)); ++ ch[2] = '\0'; ++ } else if (flag_mode == FLAG_NUM) { ++ sprintf((char *) ch, "%d", f); ++ } else if (flag_mode == FLAG_UNI) { ++ u16_u8((char *) &ch, 10, (w_char *) &f, 1); ++ } else { ++ ch[0] = (unsigned char) (f); ++ ch[1] = '\0'; ++ } ++ return mystrdup((char *) ch); ++} ++ ++// read in aff file and set flag mode ++int HashMgr::load_config(const char * affpath) ++{ ++ int firstline = 1; ++ ++ // io buffers ++ char line[MAXDELEN+1]; ++ ++ // open the affix file ++ FILE * afflst; ++ afflst = fopen(affpath,"r"); ++ if (!afflst) { ++ HUNSPELL_WARNING(stderr, "Error - could not open affix description file %s\n",affpath); ++ return 1; ++ } ++ ++ // read in each line ignoring any that do not ++ // start with a known line type indicator ++ ++ while (fgets(line,MAXDELEN,afflst)) { ++ mychomp(line); ++ ++ /* remove byte order mark */ ++ if (firstline) { ++ firstline = 0; ++ if (strncmp(line,"\xEF\xBB\xBF",3) == 0) memmove(line, line+3, strlen(line+3)+1); ++ } ++ ++ /* parse in the try string */ ++ if ((strncmp(line,"FLAG",4) == 0) && isspace(line[4])) { ++ if (flag_mode != FLAG_CHAR) { ++ HUNSPELL_WARNING(stderr, "error: duplicate FLAG parameter\n"); ++ } ++ if (strstr(line, "long")) flag_mode = FLAG_LONG; ++ if (strstr(line, "num")) flag_mode = FLAG_NUM; ++ if (strstr(line, "UTF-8")) flag_mode = FLAG_UNI; ++ if (flag_mode == FLAG_CHAR) { ++ HUNSPELL_WARNING(stderr, "error: FLAG need `num', `long' or `UTF-8' parameter: %s\n", line); ++ } ++ } ++ if (strncmp(line,"FORBIDDENWORD",13) == 0) { ++ char * st = NULL; ++ if (parse_string(line, &st, "FORBIDDENWORD")) { ++ fclose(afflst); ++ return 1; ++ } ++ forbiddenword = decode_flag(st); ++ free(st); ++ } ++ if (strncmp(line, "SET", 3) == 0) { ++ if (parse_string(line, &enc, "SET")) { ++ fclose(afflst); ++ return 1; ++ } ++ if (strcmp(enc, "UTF-8") == 0) { ++ utf8 = 1; ++#ifndef OPENOFFICEORG ++#ifndef MOZILLA_CLIENT ++ initialize_utf_tbl(); ++#endif ++#endif ++ } else csconv = get_current_cs(enc); ++ } ++ if (strncmp(line, "LANG", 4) == 0) { ++ if (parse_string(line, &lang, "LANG")) { ++ fclose(afflst); ++ return 1; ++ } ++ langnum = get_lang_num(lang); ++ } ++ ++ /* parse in the ignored characters (for example, Arabic optional diacritics characters */ ++ if (strncmp(line,"IGNORE",6) == 0) { ++ if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++ if ((strncmp(line,"AF",2) == 0) && isspace(line[2])) { ++ if (parse_aliasf(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++ if ((strncmp(line,"AM",2) == 0) && isspace(line[2])) { ++ if (parse_aliasm(line, afflst)) { ++ fclose(afflst); ++ return 1; ++ } ++ } ++#endif ++ if (strncmp(line,"COMPLEXPREFIXES",15) == 0) complexprefixes = 1; ++ if (((strncmp(line,"SFX",3) == 0) || (strncmp(line,"PFX",3) == 0)) && isspace(line[3])) break; ++ } ++ if (csconv == NULL) csconv = get_current_cs("ISO8859-1"); ++ fclose(afflst); ++ return 0; ++} ++ ++/* parse in the ALIAS table */ ++int HashMgr::parse_aliasf(char * line, FILE * af) ++{ ++ if (numaliasf != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate AF (alias for flag vector) tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numaliasf = atoi(piece); ++ if (numaliasf < 1) { ++ numaliasf = 0; ++ aliasf = NULL; ++ aliasflen = NULL; ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in AF table\n"); ++ free(piece); ++ return 1; ++ } ++ aliasf = (unsigned short **) malloc(numaliasf * sizeof(unsigned short *)); ++ aliasflen = (unsigned short *) malloc(numaliasf * sizeof(short)); ++ if (!aliasf || !aliasflen) { ++ numaliasf = 0; ++ if (aliasf) free(aliasf); ++ if (aliasflen) free(aliasflen); ++ aliasf = NULL; ++ aliasflen = NULL; ++ return 1; ++ } ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ numaliasf = 0; ++ free(aliasf); ++ free(aliasflen); ++ aliasf = NULL; ++ aliasflen = NULL; ++ HUNSPELL_WARNING(stderr, "error: missing AF table information\n"); ++ return 1; ++ } ++ ++ /* now parse the numaliasf lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numaliasf; j++) { ++ if (!fgets(nl,MAXDELEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ aliasf[j] = NULL; ++ aliasflen[j] = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"AF",2) != 0) { ++ numaliasf = 0; ++ free(aliasf); ++ free(aliasflen); ++ aliasf = NULL; ++ aliasflen = NULL; ++ HUNSPELL_WARNING(stderr, "error: AF table is corrupt\n"); ++ free(piece); ++ return 1; ++ } ++ break; ++ } ++ case 1: { ++ aliasflen[j] = (unsigned short) decode_flags(&(aliasf[j]), piece); ++ flag_qsort(aliasf[j], 0, aliasflen[j]); ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (!aliasf[j]) { ++ free(aliasf); ++ free(aliasflen); ++ aliasf = NULL; ++ aliasflen = NULL; ++ numaliasf = 0; ++ HUNSPELL_WARNING(stderr, "error: AF table is corrupt\n"); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int HashMgr::is_aliasf() { ++ return (aliasf != NULL); ++} ++ ++int HashMgr::get_aliasf(int index, unsigned short ** fvec) { ++ if ((index > 0) && (index <= numaliasf)) { ++ *fvec = aliasf[index - 1]; ++ return aliasflen[index - 1]; ++ } ++ HUNSPELL_WARNING(stderr, "error: bad flag alias index: %d\n", index); ++ *fvec = NULL; ++ return 0; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++/* parse morph alias definitions */ ++int HashMgr::parse_aliasm(char * line, FILE * af) ++{ ++ if (numaliasm != 0) { ++ HUNSPELL_WARNING(stderr, "error: duplicate AM (aliases for morphological descriptions) tables used\n"); ++ return 1; ++ } ++ char * tp = line; ++ char * piece; ++ int i = 0; ++ int np = 0; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { np++; break; } ++ case 1: { ++ numaliasm = atoi(piece); ++ if (numaliasm < 1) { ++ HUNSPELL_WARNING(stderr, "incorrect number of entries in AM table\n"); ++ free(piece); ++ return 1; ++ } ++ aliasm = (char **) malloc(numaliasm * sizeof(char *)); ++ if (!aliasm) { ++ numaliasm = 0; ++ return 1; ++ } ++ np++; ++ break; ++ } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (np != 2) { ++ numaliasm = 0; ++ free(aliasm); ++ aliasm = NULL; ++ HUNSPELL_WARNING(stderr, "error: missing AM alias information\n"); ++ return 1; ++ } ++ ++ /* now parse the numaliasm lines to read in the remainder of the table */ ++ char * nl = line; ++ for (int j=0; j < numaliasm; j++) { ++ if (!fgets(nl,MAXDELEN,af)) return 1; ++ mychomp(nl); ++ tp = nl; ++ i = 0; ++ aliasm[j] = NULL; ++ piece = mystrsep(&tp, 0); ++ while (piece) { ++ if (*piece != '\0') { ++ switch(i) { ++ case 0: { ++ if (strncmp(piece,"AM",2) != 0) { ++ HUNSPELL_WARNING(stderr, "error: AM table is corrupt\n"); ++ free(piece); ++ numaliasm = 0; ++ free(aliasm); ++ aliasm = NULL; ++ return 1; ++ } ++ break; ++ } ++ case 1: { ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(piece); ++ else reverseword(piece); ++ } ++ aliasm[j] = mystrdup(piece); ++ break; } ++ default: break; ++ } ++ i++; ++ } ++ free(piece); ++ piece = mystrsep(&tp, 0); ++ } ++ if (!aliasm[j]) { ++ numaliasm = 0; ++ free(aliasm); ++ aliasm = NULL; ++ HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int HashMgr::is_aliasm() { ++ return (aliasm != NULL); ++} ++ ++char * HashMgr::get_aliasm(int index) { ++ if ((index > 0) && (index <= numaliasm)) return aliasm[index - 1]; ++ HUNSPELL_WARNING(stderr, "error: bad morph. alias index: %d\n", index); ++ return NULL; ++} ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/hashmgr.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/hashmgr.hxx +@@ -0,0 +1,129 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _HASHMGR_HXX_ ++#define _HASHMGR_HXX_ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#else ++#include ++#endif ++ ++#include "htypes.hxx" ++ ++enum flag { FLAG_CHAR, FLAG_LONG, FLAG_NUM, FLAG_UNI }; ++ ++class HashMgr ++{ ++ int tablesize; ++ struct hentry ** tableptr; ++ int userword; ++ flag flag_mode; ++ int complexprefixes; ++ int utf8; ++ unsigned short forbiddenword; ++ int langnum; ++ char * enc; ++ char * lang; ++ struct cs_info * csconv; ++ char * ignorechars; ++ unsigned short * ignorechars_utf16; ++ int ignorechars_utf16_len; ++ int numaliasf; // flag vector `compression' with aliases ++ unsigned short ** aliasf; ++ unsigned short * aliasflen; ++ int numaliasm; // morphological desciption `compression' with aliases ++ char ** aliasm; ++ ++ ++public: ++ HashMgr(const char * tpath, const char * apath); ++ ~HashMgr(); ++ ++ struct hentry * lookup(const char *) const; ++ int hash(const char *) const; ++ struct hentry * walk_hashtable(int & col, struct hentry * hp) const; ++ ++ int put_word(const char * word, char * ap); ++ int put_word_pattern(const char * word, const char * pattern); ++ int decode_flags(unsigned short ** result, char * flags); ++ unsigned short decode_flag(const char * flag); ++ char * encode_flag(unsigned short flag); ++ int is_aliasf(); ++ int get_aliasf(int index, unsigned short ** fvec); ++#ifdef HUNSPELL_EXPERIMENTAL ++ int is_aliasm(); ++ char * get_aliasm(int index); ++#endif ++ ++ ++private: ++ int get_clen_and_captype(const char * word, int wbl, int * captype); ++ int load_tables(const char * tpath); ++ int add_word(const char * word, int wbl, int wcl, unsigned short * ap, ++ int al, const char * desc, bool onlyupcase); ++ int load_config(const char * affpath); ++ int parse_aliasf(char * line, FILE * af); ++ int add_hidden_capitalized_word(char * word, int wbl, int wcl, ++ unsigned short * flags, int al, char * dp, int captype); ++#ifdef HUNSPELL_EXPERIMENTAL ++ int parse_aliasm(char * line, FILE * af); ++#endif ++ ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/htypes.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/htypes.hxx +@@ -0,0 +1,85 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _HTYPES_HXX_ ++#define _HTYPES_HXX_ ++ ++#define MAXDELEN 8192 ++ ++#define ROTATE_LEN 5 ++ ++#define ROTATE(v,q) \ ++ (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q))-1)); ++ ++// approx. number of user defined words ++#define USERWORD 1000 ++ ++struct hentry ++{ ++ unsigned char blen; // word length in bytes ++ unsigned char clen; // word length in characters (different for UTF-8 enc.) ++ short alen; // length of affix flag vector ++ unsigned short * astr; // affix flag vector ++ struct hentry * next; // next word with same hash code ++ struct hentry * next_homonym; // next homonym word (with same hash code) ++#ifdef HUNSPELL_EXPERIMENTAL ++ char * description; // morphological data (optional) ++#endif ++ char var; // variable fields (only for special pronounciation yet) ++ char word; // variable-length word (8-bit or UTF-8 encoding) ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.cpp +@@ -0,0 +1,1807 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#endif ++ ++#include "hunspell.hxx" ++#include "hunspell.h" ++ ++#ifndef MOZILLA_CLIENT ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++Hunspell::Hunspell(const char * affpath, const char * dpath) ++{ ++ encoding = NULL; ++ csconv = NULL; ++ utf8 = 0; ++ complexprefixes = 0; ++ ++ /* first set up the hash manager */ ++ pHMgr = new HashMgr(dpath, affpath); ++ ++ /* next set up the affix manager */ ++ /* it needs access to the hash manager lookup methods */ ++ pAMgr = new AffixMgr(affpath,pHMgr); ++ ++ /* get the preferred try string and the dictionary */ ++ /* encoding from the Affix Manager for that dictionary */ ++ char * try_string = pAMgr->get_try_string(); ++ encoding = pAMgr->get_encoding(); ++ csconv = get_current_cs(encoding); ++ langnum = pAMgr->get_langnum(); ++ utf8 = pAMgr->get_utf8(); ++ complexprefixes = pAMgr->get_complexprefixes(); ++ wordbreak = pAMgr->get_breaktable(); ++ ++ /* and finally set up the suggestion manager */ ++ pSMgr = new SuggestMgr(try_string, MAXSUGGESTION, pAMgr); ++ if (try_string) free(try_string); ++ ++} ++ ++Hunspell::~Hunspell() ++{ ++ if (pSMgr) delete pSMgr; ++ if (pAMgr) delete pAMgr; ++ if (pHMgr) delete pHMgr; ++ pSMgr = NULL; ++ pAMgr = NULL; ++ pHMgr = NULL; ++#ifdef MOZILLA_CLIENT ++ free(csconv); ++#endif ++ csconv= NULL; ++ if (encoding) free(encoding); ++ encoding = NULL; ++} ++ ++ ++// make a copy of src at destination while removing all leading ++// blanks and removing any trailing periods after recording ++// their presence with the abbreviation flag ++// also since already going through character by character, ++// set the capitalization type ++// return the length of the "cleaned" (and UTF-8 encoded) word ++ ++int Hunspell::cleanword2(char * dest, const char * src, ++ w_char * dest_utf, int * nc, int * pcaptype, int * pabbrev) ++{ ++ unsigned char * p = (unsigned char *) dest; ++ const unsigned char * q = (const unsigned char * ) src; ++ ++ // first skip over any leading blanks ++ while ((*q != '\0') && (*q == ' ')) q++; ++ ++ // now strip off any trailing periods (recording their presence) ++ *pabbrev = 0; ++ int nl = strlen((const char *)q); ++ while ((nl > 0) && (*(q+nl-1)=='.')) { ++ nl--; ++ (*pabbrev)++; ++ } ++ ++ // if no characters are left it can't be capitalized ++ if (nl <= 0) { ++ *pcaptype = NOCAP; ++ *p = '\0'; ++ return 0; ++ } ++ ++ strncpy(dest, (char *) q, nl); ++ *(dest + nl) = '\0'; ++ nl = strlen(dest); ++ if (utf8) { ++ *nc = u8_u16(dest_utf, MAXWORDLEN, dest); ++ // don't check too long words ++ if (*nc >= MAXWORDLEN) return 0; ++ if (*nc == -1) { // big Unicode character (non BMP area) ++ *pcaptype = NOCAP; ++ return nl; ++ } ++ *pcaptype = get_captype_utf8(dest_utf, *nc, langnum); ++ } else { ++ *pcaptype = get_captype(dest, nl, csconv); ++ *nc = nl; ++ } ++ return nl; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++int Hunspell::cleanword(char * dest, const char * src, ++ int * pcaptype, int * pabbrev) ++{ ++ unsigned char * p = (unsigned char *) dest; ++ const unsigned char * q = (const unsigned char * ) src; ++ int firstcap = 0; ++ ++ // first skip over any leading blanks ++ while ((*q != '\0') && (*q == ' ')) q++; ++ ++ // now strip off any trailing periods (recording their presence) ++ *pabbrev = 0; ++ int nl = strlen((const char *)q); ++ while ((nl > 0) && (*(q+nl-1)=='.')) { ++ nl--; ++ (*pabbrev)++; ++ } ++ ++ // if no characters are left it can't be capitalized ++ if (nl <= 0) { ++ *pcaptype = NOCAP; ++ *p = '\0'; ++ return 0; ++ } ++ ++ // now determine the capitalization type of the first nl letters ++ int ncap = 0; ++ int nneutral = 0; ++ int nc = 0; ++ ++ if (!utf8) { ++ while (nl > 0) { ++ nc++; ++ if (csconv[(*q)].ccase) ncap++; ++ if (csconv[(*q)].cupper == csconv[(*q)].clower) nneutral++; ++ *p++ = *q++; ++ nl--; ++ } ++ // remember to terminate the destination string ++ *p = '\0'; ++ firstcap = csconv[(unsigned char)(*dest)].ccase; ++ } else { ++ unsigned short idx; ++ w_char t[MAXWORDLEN]; ++ nc = u8_u16(t, MAXWORDLEN, src); ++ for (int i = 0; i < nc; i++) { ++ idx = (t[i].h << 8) + t[i].l; ++ unsigned short low = unicodetolower(idx, langnum); ++ if (idx != low) ncap++; ++ if (unicodetoupper(idx, langnum) == low) nneutral++; ++ } ++ u16_u8(dest, MAXWORDUTF8LEN, t, nc); ++ if (ncap) { ++ idx = (t[0].h << 8) + t[0].l; ++ firstcap = (idx != unicodetolower(idx, langnum)); ++ } ++ } ++ ++ // now finally set the captype ++ if (ncap == 0) { ++ *pcaptype = NOCAP; ++ } else if ((ncap == 1) && firstcap) { ++ *pcaptype = INITCAP; ++ } else if ((ncap == nc) || ((ncap + nneutral) == nc)){ ++ *pcaptype = ALLCAP; ++ } else if ((ncap > 1) && firstcap) { ++ *pcaptype = HUHINITCAP; ++ } else { ++ *pcaptype = HUHCAP; ++ } ++ return strlen(dest); ++} ++#endif ++ ++void Hunspell::mkallcap(char * p) ++{ ++ if (utf8) { ++ w_char u[MAXWORDLEN]; ++ int nc = u8_u16(u, MAXWORDLEN, p); ++ unsigned short idx; ++ for (int i = 0; i < nc; i++) { ++ idx = (u[i].h << 8) + u[i].l; ++ if (idx != unicodetoupper(idx, langnum)) { ++ u[i].h = (unsigned char) (unicodetoupper(idx, langnum) >> 8); ++ u[i].l = (unsigned char) (unicodetoupper(idx, langnum) & 0x00FF); ++ } ++ } ++ u16_u8(p, MAXWORDUTF8LEN, u, nc); ++ } else { ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].cupper; ++ p++; ++ } ++ } ++} ++ ++int Hunspell::mkallcap2(char * p, w_char * u, int nc) ++{ ++ if (utf8) { ++ unsigned short idx; ++ for (int i = 0; i < nc; i++) { ++ idx = (u[i].h << 8) + u[i].l; ++ unsigned short up = unicodetoupper(idx, langnum); ++ if (idx != up) { ++ u[i].h = (unsigned char) (up >> 8); ++ u[i].l = (unsigned char) (up & 0x00FF); ++ } ++ } ++ u16_u8(p, MAXWORDUTF8LEN, u, nc); ++ return strlen(p); ++ } else { ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].cupper; ++ p++; ++ } ++ } ++ return nc; ++} ++ ++ ++void Hunspell::mkallsmall(char * p) ++{ ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].clower; ++ p++; ++ } ++} ++ ++int Hunspell::mkallsmall2(char * p, w_char * u, int nc) ++{ ++ if (utf8) { ++ unsigned short idx; ++ for (int i = 0; i < nc; i++) { ++ idx = (u[i].h << 8) + u[i].l; ++ unsigned short low = unicodetolower(idx, langnum); ++ if (idx != low) { ++ u[i].h = (unsigned char) (low >> 8); ++ u[i].l = (unsigned char) (low & 0x00FF); ++ } ++ } ++ u16_u8(p, MAXWORDUTF8LEN, u, nc); ++ return strlen(p); ++ } else { ++ while (*p != '\0') { ++ *p = csconv[((unsigned char) *p)].clower; ++ p++; ++ } ++ } ++ return nc; ++} ++ ++// convert UTF-8 sharp S codes to latin 1 ++char * Hunspell::sharps_u8_l1(char * dest, char * source) { ++ char * p = dest; ++ *p = *source; ++ for (p++, source++; *(source - 1); p++, source++) { ++ *p = *source; ++ if (*source == '\x9F') *--p = '\xDF'; ++ } ++ return dest; ++} ++ ++// recursive search for right ss - sharp s permutations ++hentry * Hunspell::spellsharps(char * base, char * pos, int n, ++ int repnum, char * tmp, int * info, char **root) { ++ pos = strstr(pos, "ss"); ++ if (pos && (n < MAXSHARPS)) { ++ *pos = '\xC3'; ++ *(pos + 1) = '\x9F'; ++ hentry * h = spellsharps(base, pos + 2, n + 1, repnum + 1, tmp, info, root); ++ if (h) return h; ++ *pos = 's'; ++ *(pos + 1) = 's'; ++ h = spellsharps(base, pos + 2, n + 1, repnum, tmp, info, root); ++ if (h) return h; ++ } else if (repnum > 0) { ++ if (utf8) return checkword(base, info, root); ++ return checkword(sharps_u8_l1(tmp, base), info, root); ++ } ++ return NULL; ++} ++ ++int Hunspell::is_keepcase(const hentry * rv) { ++ return pAMgr && rv->astr && pAMgr->get_keepcase() && ++ TESTAFF(rv->astr, pAMgr->get_keepcase(), rv->alen); ++} ++ ++/* insert a word to beginning of the suggestion array and return ns */ ++int Hunspell::insert_sug(char ***slst, char * word, int ns) { ++ if (ns == MAXSUGGESTION) { ++ ns--; ++ free((*slst)[ns]); ++ } ++ for (int k = ns; k > 0; k--) (*slst)[k] = (*slst)[k - 1]; ++ (*slst)[0] = mystrdup(word); ++ return ns + 1; ++} ++ ++int Hunspell::spell(const char * word, int * info, char ** root) ++{ ++ struct hentry * rv=NULL; ++ // need larger vector. For example, Turkish capital letter I converted a ++ // 2-byte UTF-8 character (dotless i) by mkallsmall. ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ w_char unicw[MAXWORDLEN]; ++ int nc = strlen(word); ++ int wl2 = 0; ++ if (utf8) { ++ if (nc >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (nc >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ int wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv); ++ int info2 = 0; ++ if (wl == 0) return 1; ++ if (root) *root = NULL; ++ ++ // allow numbers with dots and commas (but forbid double separators: "..", ",," etc.) ++ enum { NBEGIN, NNUM, NSEP }; ++ int nstate = NBEGIN; ++ int i; ++ ++ for (i = 0; (i < wl); i++) { ++ if ((cw[i] <= '9') && (cw[i] >= '0')) { ++ nstate = NNUM; ++ } else if ((cw[i] == ',') || (cw[i] == '.') || (cw[i] == '-')) { ++ if ((nstate == NSEP) || (i == 0)) break; ++ nstate = NSEP; ++ } else break; ++ } ++ if ((i == wl) && (nstate == NNUM)) return 1; ++ if (!info) info = &info2; else *info = 0; ++ ++ // LANG_hu section: number(s) + (percent or degree) with suffixes ++ if (langnum == LANG_hu) { ++ if ((nstate == NNUM) && ((cw[i] == '%') || ((!utf8 && (cw[i] == '\xB0')) || ++ (utf8 && (strncmp(cw + i, "\xC2\xB0", 2)==0)))) ++ && checkword(cw + i, info, root)) return 1; ++ } ++ // END of LANG_hu section ++ ++ switch(captype) { ++ case HUHCAP: ++ case HUHINITCAP: ++ case NOCAP: { ++ rv = checkword(cw, info, root); ++ if ((abbv) && !(rv)) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ rv = checkword(wspace, info, root); ++ } ++ break; ++ } ++ case ALLCAP: { ++ rv = checkword(cw, info, root); ++ if (rv) break; ++ if (abbv) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ rv = checkword(wspace, info, root); ++ if (rv) break; ++ } ++ // Spec. prefix handling for Catalan, French, Italian: ++ // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia). ++ if (pAMgr && strchr(cw, '\'')) { ++ wl = mkallsmall2(cw, unicw, nc); ++ char * apostrophe = strchr(cw, '\''); ++ if (utf8) { ++ w_char tmpword[MAXWORDLEN]; ++ *apostrophe = '\0'; ++ wl2 = u8_u16(tmpword, MAXWORDLEN, cw); ++ *apostrophe = '\''; ++ if (wl2 < nc) { ++ mkinitcap2(apostrophe + 1, unicw + wl2 + 1, nc - wl2 - 1); ++ rv = checkword(cw, info, root); ++ if (rv) break; ++ } ++ } else { ++ mkinitcap2(apostrophe + 1, unicw, nc); ++ rv = checkword(cw, info, root); ++ if (rv) break; ++ } ++ mkinitcap2(cw, unicw, nc); ++ rv = checkword(cw, info, root); ++ if (rv) break; ++ } ++ if (pAMgr && pAMgr->get_checksharps() && strstr(cw, "SS")) { ++ char tmpword[MAXWORDUTF8LEN]; ++ wl = mkallsmall2(cw, unicw, nc); ++ memcpy(wspace,cw,(wl+1)); ++ rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); ++ if (!rv) { ++ wl2 = mkinitcap2(cw, unicw, nc); ++ rv = spellsharps(cw, cw, 0, 0, tmpword, info, root); ++ } ++ if ((abbv) && !(rv)) { ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); ++ if (!rv) { ++ memcpy(wspace, cw, wl2); ++ *(wspace+wl2) = '.'; ++ *(wspace+wl2+1) = '\0'; ++ rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); ++ } ++ } ++ if (rv) break; ++ } ++ } ++ case INITCAP: { ++ wl = mkallsmall2(cw, unicw, nc); ++ memcpy(wspace,cw,(wl+1)); ++ wl2 = mkinitcap2(cw, unicw, nc); ++ if (captype == INITCAP) *info += SPELL_INITCAP; ++ rv = checkword(cw, info, root); ++ if (captype == INITCAP) *info -= SPELL_INITCAP; ++ // forbid bad capitalization ++ // (for example, ijs -> Ijs instead of IJs in Dutch) ++ // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag) ++ if (*info & SPELL_FORBIDDEN) { ++ rv = NULL; ++ break; ++ } ++ if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; ++ if (rv) break; ++ ++ rv = checkword(wspace, info, root); ++ if (abbv && !rv) { ++ ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ rv = checkword(wspace, info, root); ++ if (!rv) { ++ memcpy(wspace, cw, wl2); ++ *(wspace+wl2) = '.'; ++ *(wspace+wl2+1) = '\0'; ++ if (captype == INITCAP) *info += SPELL_INITCAP; ++ rv = checkword(wspace, info, root); ++ if (captype == INITCAP) *info -= SPELL_INITCAP; ++ if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; ++ break; ++ } ++ } ++ if (rv && is_keepcase(rv) && ++ ((captype == ALLCAP) || ++ // if CHECKSHARPS: KEEPCASE words with \xDF are allowed ++ // in INITCAP form, too. ++ !(pAMgr->get_checksharps() && ++ ((utf8 && strstr(wspace, "\xC3\x9F")) || ++ (!utf8 && strchr(wspace, '\xDF')))))) rv = NULL; ++ break; ++ } ++ } ++ ++ if (rv) return 1; ++ ++ // recursive breaking at break points (not good for morphological analysis) ++ if (wordbreak) { ++ char * s; ++ char r; ++ int corr = 0; ++ // German words beginning with "-" are not accepted ++ if (langnum == LANG_de) corr = 1; ++ int numbreak = pAMgr ? pAMgr->get_numbreak() : 0; ++ for (int j = 0; j < numbreak; j++) { ++ s=(char *) strstr(cw + corr, wordbreak[j]); ++ if (s) { ++ r = *s; ++ *s = '\0'; ++ // examine 2 sides of the break point ++ if (spell(cw) && spell(s + strlen(wordbreak[j]))) { ++ *s = r; ++ return 1; ++ } ++ *s = r; ++ } ++ } ++ } ++ ++ // LANG_hu: compoundings with dashes and n-dashes XXX deprecated! ++ if (langnum == LANG_hu) { ++ int n; ++ // compound word with dash (HU) I18n ++ char * dash; ++ int result = 0; ++ // n-dash ++ dash = (char *) strstr(cw,"\xE2\x80\x93"); ++ if (dash && !wordbreak) { ++ *dash = '\0'; ++ // examine 2 sides of the dash ++ if (spell(cw) && spell(dash + 3)) { ++ *dash = '\xE2'; ++ return 1; ++ } ++ *dash = '\xE2'; ++ } ++ dash = (char *) strchr(cw,'-'); ++ if (dash) { ++ *dash='\0'; ++ // examine 2 sides of the dash ++ if (dash[1] == '\0') { // base word ending with dash ++ if (spell(cw)) return 1; ++ } else { ++ // first word ending with dash: word- ++ char r2 = *(dash + 1); ++ dash[0]='-'; ++ dash[1]='\0'; ++ result = spell(cw); ++ dash[1] = r2; ++ dash[0]='\0'; ++ if (result && spell(dash+1) && ((strlen(dash+1) > 1) || (dash[1] == 'e') || ++ ((dash[1] > '0') && (dash[1] < '9')))) return 1; ++ } ++ // affixed number in correct word ++ if (result && (dash > cw) && (((*(dash-1)<='9') && (*(dash-1)>='0')) || (*(dash-1)>='.'))) { ++ *dash='-'; ++ n = 1; ++ if (*(dash - n) == '.') n++; ++ // search first not a number character to left from dash ++ while (((dash - n)>=cw) && ((*(dash - n)=='0') || (n < 3)) && (n < 6)) { ++ n++; ++ } ++ if ((dash - n) < cw) n--; ++ // numbers: deprecated ++ for(; n >= 1; n--) { ++ if ((*(dash - n) >= '0') && (*(dash - n) <= '9') && ++ checkword(dash - n, info, root)) return 1; ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++struct hentry * Hunspell::checkword(const char * w, int * info, char ** root) ++{ ++ struct hentry * he = NULL; ++ int len; ++ char w2[MAXWORDUTF8LEN]; ++ const char * word; ++ ++ char * ignoredchars = pAMgr->get_ignore(); ++ if (ignoredchars != NULL) { ++ strcpy(w2, w); ++ if (utf8) { ++ int ignoredchars_utf16_len; ++ unsigned short * ignoredchars_utf16 = pAMgr->get_ignore_utf16(&ignoredchars_utf16_len); ++ remove_ignored_chars_utf(w2, ignoredchars_utf16, ignoredchars_utf16_len); ++ } else { ++ remove_ignored_chars(w2,ignoredchars); ++ } ++ word = w2; ++ } else word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ if (word != w2) { ++ strcpy(w2, word); ++ word = w2; ++ } ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ } ++ ++ // look word in hash table ++ if (pHMgr) he = pHMgr->lookup(word); ++ ++ // check forbidden and onlyincompound words ++ if ((he) && (he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { ++ if (info) *info += SPELL_FORBIDDEN; ++ // LANG_hu section: set dash information for suggestions ++ if (langnum == LANG_hu) { ++ if (pAMgr->get_compoundflag() && ++ TESTAFF(he->astr, pAMgr->get_compoundflag(), he->alen)) { ++ if (info) *info += SPELL_COMPOUND; ++ } ++ } ++ return NULL; ++ } ++ ++ // he = next not pseudoroot, onlyincompound homonym or onlyupcase word ++ while (he && (he->astr) && ++ ((pAMgr->get_pseudoroot() && TESTAFF(he->astr, pAMgr->get_pseudoroot(), he->alen)) || ++ (pAMgr->get_onlyincompound() && TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || ++ (info && (*info & SPELL_INITCAP) && TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)) ++ )) he = he->next_homonym; ++ ++ // check with affixes ++ if (!he && pAMgr) { ++ // try stripping off affixes */ ++ len = strlen(word); ++ he = pAMgr->affix_check(word, len, 0); ++ ++ // check compound restriction and onlyupcase ++ if (he && he->astr && ( ++ (pAMgr->get_onlyincompound() && ++ TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || ++ (info && (*info & SPELL_INITCAP) && ++ TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) { ++ he = NULL; ++ } ++ ++ if (he) { ++ if ((he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { ++ if (info) *info += SPELL_FORBIDDEN; ++ return NULL; ++ } ++ if (root) { ++ *root = mystrdup(&(he->word)); ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(*root); else reverseword(*root); ++ } ++ } ++ // try check compound word ++ } else if (pAMgr->get_compound()) { ++ he = pAMgr->compound_check(word, len, ++ 0,0,100,0,NULL,0,NULL,NULL,0); ++ // LANG_hu section: `moving rule' with last dash ++ if ((!he) && (langnum == LANG_hu) && (word[len-1]=='-')) { ++ char * dup = mystrdup(word); ++ dup[len-1] = '\0'; ++ he = pAMgr->compound_check(dup, len-1, ++ -5,0,100,0,NULL,1,NULL,NULL,0); ++ free(dup); ++ } ++ // end of LANG speficic region ++ if (he) { ++ if (root) { ++ *root = mystrdup(&(he->word)); ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(*root); else reverseword(*root); ++ } ++ } ++ if (info) *info += SPELL_COMPOUND; ++ } ++ } ++ ++ } ++ ++ return he; ++} ++ ++int Hunspell::suggest(char*** slst, const char * word) ++{ ++ int onlycmpdsug = 0; ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ w_char unicw[MAXWORDLEN]; ++ int nc = strlen(word); ++ if (utf8) { ++ if (nc >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (nc >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ int wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv); ++ if (wl == 0) return 0; ++ int ns = 0; ++ *slst = NULL; ++ int capwords = 0; ++ ++ switch(captype) { ++ case NOCAP: { ++ ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); ++ break; ++ } ++ ++ case INITCAP: { ++ capwords = 1; ++ ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); ++ if (ns == -1) break; ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ break; ++ } ++ case HUHINITCAP: ++ capwords = 1; ++ case HUHCAP: { ++ ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); ++ if (ns != -1) { ++ int prevns; ++ // something.The -> something. The ++ char * dot = strchr(cw, '.'); ++ if (dot && (dot > cw)) { ++ int captype_; ++ if (utf8) { ++ w_char w_[MAXWORDLEN]; ++ int wl_ = u8_u16(w_, MAXWORDLEN, dot + 1); ++ captype_ = get_captype_utf8(w_, wl_, langnum); ++ } else captype_ = get_captype(dot+1, strlen(dot+1), csconv); ++ if (captype_ == INITCAP) { ++ char * st = mystrdup(cw); ++ st = (char *) realloc(st, wl + 2); ++ if (st) { ++ st[(dot - cw) + 1] = ' '; ++ strcpy(st + (dot - cw) + 2, dot + 1); ++ ns = insert_sug(slst, st, ns); ++ free(st); ++ } ++ } ++ } ++ if (captype == HUHINITCAP) { ++ // TheOpenOffice.org -> The OpenOffice.org ++ memcpy(wspace,cw,(wl+1)); ++ mkinitsmall2(wspace, unicw, nc); ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ } ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ if (spell(wspace)) ns = insert_sug(slst, wspace, ns); ++ prevns = ns; ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ if (captype == HUHINITCAP) { ++ mkinitcap2(wspace, unicw, nc); ++ if (spell(wspace)) ns = insert_sug(slst, wspace, ns); ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ } ++ // aNew -> "a New" (instead of "a new") ++ for (int j = prevns; j < ns; j++) { ++ char * space = strchr((*slst)[j],' '); ++ if (space) { ++ int slen = strlen(space + 1); ++ // different case after space (need capitalisation) ++ if ((slen < wl) && strcmp(cw + wl - slen, space + 1)) { ++ w_char w[MAXWORDLEN]; ++ int wc = 0; ++ char * r = (*slst)[j]; ++ if (utf8) wc = u8_u16(w, MAXWORDLEN, space + 1); ++ mkinitcap2(space + 1, w, wc); ++ // set as first suggestion ++ for (int k = j; k > 0; k--) (*slst)[k] = (*slst)[k - 1]; ++ (*slst)[0] = r; ++ } ++ } ++ } ++ } ++ break; ++ } ++ ++ case ALLCAP: { ++ memcpy(wspace, cw, (wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ if (ns == -1) break; ++ if (pAMgr && pAMgr->get_keepcase() && spell(wspace)) ++ ns = insert_sug(slst, wspace, ns); ++ mkinitcap2(wspace, unicw, nc); ++ ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); ++ for (int j=0; j < ns; j++) { ++ mkallcap((*slst)[j]); ++ if (pAMgr && pAMgr->get_checksharps()) { ++ char * pos; ++ if (utf8) { ++ pos = strstr((*slst)[j], "\xC3\x9F"); ++ while (pos) { ++ *pos = 'S'; ++ *(pos+1) = 'S'; ++ pos = strstr(pos+2, "\xC3\x9F"); ++ } ++ } else { ++ pos = strchr((*slst)[j], '\xDF'); ++ while (pos) { ++ (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 2); ++ mystrrep((*slst)[j], "\xDF", "SS"); ++ pos = strchr((*slst)[j], '\xDF'); ++ } ++ } ++ } ++ } ++ break; ++ } ++ } ++ ++ // LANG_hu section: replace '-' with ' ' in Hungarian ++ if (langnum == LANG_hu) { ++ for (int j=0; j < ns; j++) { ++ char * pos = strchr((*slst)[j],'-'); ++ if (pos) { ++ int info; ++ char w[MAXWORDUTF8LEN]; ++ *pos = '\0'; ++ strcpy(w, (*slst)[j]); ++ strcat(w, pos + 1); ++ spell(w, &info, NULL); ++ if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) { ++ *pos = ' '; ++ } else *pos = '-'; ++ } ++ } ++ } ++ // END OF LANG_hu section ++ ++ // try ngram approach since found nothing ++ if ((ns == 0 || onlycmpdsug) && pAMgr && (pAMgr->get_maxngramsugs() != 0)) { ++ switch(captype) { ++ case NOCAP: { ++ ns = pSMgr->ngsuggest(*slst, cw, ns, pHMgr); ++ break; ++ } ++ case HUHCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); ++ break; ++ } ++ case INITCAP: { ++ capwords = 1; ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); ++ break; ++ } ++ case ALLCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall2(wspace, unicw, nc); ++ int oldns = ns; ++ ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); ++ for (int j = oldns; j < ns; j++) ++ mkallcap((*slst)[j]); ++ break; ++ } ++ } ++ } ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ for (int j = 0; j < ns; j++) { ++ if (utf8) reverseword_utf((*slst)[j]); else reverseword((*slst)[j]); ++ } ++ } ++ ++ // capitalize ++ if (capwords) for (int j=0; j < ns; j++) { ++ mkinitcap((*slst)[j]); ++ } ++ ++ // expand suggestions with dot(s) ++ if (abbv && pAMgr && pAMgr->get_sugswithdots()) { ++ for (int j = 0; j < ns; j++) { ++ (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 1 + abbv); ++ strcat((*slst)[j], word + strlen(word) - abbv); ++ } ++ } ++ ++ // remove bad capitalized and forbidden forms ++ if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) { ++ switch (captype) { ++ case INITCAP: ++ case ALLCAP: { ++ int l = 0; ++ for (int j=0; j < ns; j++) { ++ if (!strchr((*slst)[j],' ') && !spell((*slst)[j])) { ++ char s[MAXSWUTF8L]; ++ w_char w[MAXSWL]; ++ int len; ++ if (utf8) { ++ len = u8_u16(w, MAXSWL, (*slst)[j]); ++ } else { ++ strcpy(s, (*slst)[j]); ++ len = strlen(s); ++ } ++ mkallsmall2(s, w, len); ++ free((*slst)[j]); ++ if (spell(s)) { ++ (*slst)[l] = mystrdup(s); ++ l++; ++ } else { ++ mkinitcap2(s, w, len); ++ if (spell(s)) { ++ (*slst)[l] = mystrdup(s); ++ l++; ++ } ++ } ++ } else { ++ (*slst)[l] = (*slst)[j]; ++ l++; ++ } ++ } ++ ns = l; ++ } ++ } ++ } ++ ++ // remove duplications ++ int l = 0; ++ for (int j = 0; j < ns; j++) { ++ (*slst)[l] = (*slst)[j]; ++ for (int k = 0; k < l; k++) { ++ if (strcmp((*slst)[k], (*slst)[j]) == 0) { ++ free((*slst)[j]); ++ l--; ++ } ++ } ++ l++; ++ } ++ return l; ++} ++ ++char * Hunspell::get_dic_encoding() ++{ ++ return encoding; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// XXX need UTF-8 support ++int Hunspell::suggest_auto(char*** slst, const char * word) ++{ ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ int wl = strlen(word); ++ if (utf8) { ++ if (wl >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (wl >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ wl = cleanword(cw, word, &captype, &abbv); ++ if (wl == 0) return 0; ++ int ns = 0; ++ *slst = NULL; // HU, nsug in pSMgr->suggest ++ ++ switch(captype) { ++ case NOCAP: { ++ ns = pSMgr->suggest_auto(slst, cw, ns); ++ if (ns>0) break; ++ break; ++ } ++ ++ case INITCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_auto(slst, wspace, ns); ++ for (int j=0; j < ns; j++) ++ mkinitcap((*slst)[j]); ++ ns = pSMgr->suggest_auto(slst, cw, ns); ++ break; ++ ++ } ++ ++ case HUHCAP: { ++ ns = pSMgr->suggest_auto(slst, cw, ns); ++ if (ns == 0) { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_auto(slst, wspace, ns); ++ } ++ break; ++ } ++ ++ case ALLCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_auto(slst, wspace, ns); ++ ++ mkinitcap(wspace); ++ ns = pSMgr->suggest_auto(slst, wspace, ns); ++ ++ for (int j=0; j < ns; j++) ++ mkallcap((*slst)[j]); ++ break; ++ } ++ } ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ for (int j = 0; j < ns; j++) { ++ if (utf8) reverseword_utf((*slst)[j]); else reverseword((*slst)[j]); ++ } ++ } ++ ++ // expand suggestions with dot(s) ++ if (abbv && pAMgr && pAMgr->get_sugswithdots()) { ++ for (int j = 0; j < ns; j++) { ++ (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 1 + abbv); ++ strcat((*slst)[j], word + strlen(word) - abbv); ++ } ++ } ++ ++ // LANG_hu section: replace '-' with ' ' in Hungarian ++ if (langnum == LANG_hu) { ++ for (int j=0; j < ns; j++) { ++ char * pos = strchr((*slst)[j],'-'); ++ if (pos) { ++ int info; ++ char w[MAXWORDUTF8LEN]; ++ *pos = '\0'; ++ strcpy(w, (*slst)[j]); ++ strcat(w, pos + 1); ++ spell(w, &info, NULL); ++ if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) { ++ *pos = ' '; ++ } else *pos = '-'; ++ } ++ } ++ } ++ // END OF LANG_hu section ++ return ns; ++} ++ ++// XXX need UTF-8 support ++int Hunspell::stem(char*** slst, const char * word) ++{ ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ int wl = strlen(word); ++ if (utf8) { ++ if (wl >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (wl >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ wl = cleanword(cw, word, &captype, &abbv); ++ if (wl == 0) return 0; ++ ++ int ns = 0; ++ ++ *slst = NULL; // HU, nsug in pSMgr->suggest ++ ++ switch(captype) { ++ case HUHCAP: ++ case NOCAP: { ++ ns = pSMgr->suggest_stems(slst, cw, ns); ++ ++ if ((abbv) && (ns == 0)) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ } ++ ++ break; ++ } ++ ++ case INITCAP: { ++ ++ ns = pSMgr->suggest_stems(slst, cw, ns); ++ ++ if (ns == 0) { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ ++ } ++ ++ if ((abbv) && (ns == 0)) { ++ memcpy(wspace,cw,wl); ++ mkallsmall(wspace); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ } ++ ++ break; ++ ++ } ++ ++ case ALLCAP: { ++ ns = pSMgr->suggest_stems(slst, cw, ns); ++ if (ns != 0) break; ++ ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ ++ if (ns == 0) { ++ mkinitcap(wspace); ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ } ++ ++ if ((abbv) && (ns == 0)) { ++ memcpy(wspace,cw,wl); ++ mkallsmall(wspace); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ ns = pSMgr->suggest_stems(slst, wspace, ns); ++ } ++ ++ ++ break; ++ } ++ } ++ ++ return ns; ++} ++ ++int Hunspell::suggest_pos_stems(char*** slst, const char * word) ++{ ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ int wl = strlen(word); ++ if (utf8) { ++ if (wl >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (wl >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ wl = cleanword(cw, word, &captype, &abbv); ++ if (wl == 0) return 0; ++ ++ int ns = 0; // ns=0 = normalized input ++ ++ *slst = NULL; // HU, nsug in pSMgr->suggest ++ ++ switch(captype) { ++ case HUHCAP: ++ case NOCAP: { ++ ns = pSMgr->suggest_pos_stems(slst, cw, ns); ++ ++ if ((abbv) && (ns == 0)) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ ns = pSMgr->suggest_pos_stems(slst, wspace, ns); ++ } ++ ++ break; ++ } ++ ++ case INITCAP: { ++ ++ ns = pSMgr->suggest_pos_stems(slst, cw, ns); ++ ++ if (ns == 0 || ((*slst)[0][0] == '#')) { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_pos_stems(slst, wspace, ns); ++ } ++ ++ break; ++ ++ } ++ ++ case ALLCAP: { ++ ns = pSMgr->suggest_pos_stems(slst, cw, ns); ++ if (ns != 0) break; ++ ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ ns = pSMgr->suggest_pos_stems(slst, wspace, ns); ++ ++ if (ns == 0) { ++ mkinitcap(wspace); ++ ns = pSMgr->suggest_pos_stems(slst, wspace, ns); ++ } ++ break; ++ } ++ } ++ ++ return ns; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++const char * Hunspell::get_wordchars() ++{ ++ return pAMgr->get_wordchars(); ++} ++ ++unsigned short * Hunspell::get_wordchars_utf16(int * len) ++{ ++ return pAMgr->get_wordchars_utf16(len); ++} ++ ++void Hunspell::mkinitcap(char * p) ++{ ++ if (!utf8) { ++ if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; ++ } else { ++ int len; ++ w_char u[MAXWORDLEN]; ++ len = u8_u16(u, MAXWORDLEN, p); ++ unsigned short i = unicodetoupper((u[0].h << 8) + u[0].l, langnum); ++ u[0].h = (unsigned char) (i >> 8); ++ u[0].l = (unsigned char) (i & 0x00FF); ++ u16_u8(p, MAXWORDUTF8LEN, u, len); ++ } ++} ++ ++int Hunspell::mkinitcap2(char * p, w_char * u, int nc) ++{ ++ if (!utf8) { ++ if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; ++ } else if (nc > 0) { ++ unsigned short i = unicodetoupper((u[0].h << 8) + u[0].l, langnum); ++ u[0].h = (unsigned char) (i >> 8); ++ u[0].l = (unsigned char) (i & 0x00FF); ++ u16_u8(p, MAXWORDUTF8LEN, u, nc); ++ return strlen(p); ++ } ++ return nc; ++} ++ ++int Hunspell::mkinitsmall2(char * p, w_char * u, int nc) ++{ ++ if (!utf8) { ++ if (*p != '\0') *p = csconv[((unsigned char)*p)].clower; ++ } else if (nc > 0) { ++ unsigned short i = unicodetolower((u[0].h << 8) + u[0].l, langnum); ++ u[0].h = (unsigned char) (i >> 8); ++ u[0].l = (unsigned char) (i & 0x00FF); ++ u16_u8(p, MAXWORDUTF8LEN, u, nc); ++ return strlen(p); ++ } ++ return nc; ++} ++ ++int Hunspell::put_word(const char * word) ++{ ++ if (pHMgr) return pHMgr->put_word(word, NULL); ++ return 0; ++} ++ ++int Hunspell::put_word_pattern(const char * word, const char * pattern) ++{ ++ if (pHMgr) return pHMgr->put_word_pattern(word, pattern); ++ return 0; ++} ++ ++const char * Hunspell::get_version() ++{ ++ return pAMgr->get_version(); ++} ++ ++struct cs_info * Hunspell::get_csconv() ++{ ++ return csconv; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// XXX need UTF-8 support ++char * Hunspell::morph(const char * word) ++{ ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ int wl = strlen(word); ++ if (utf8) { ++ if (wl >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (wl >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ wl = cleanword(cw, word, &captype, &abbv); ++ if (wl == 0) { ++ if (abbv) { ++ for (wl = 0; wl < abbv; wl++) cw[wl] = '.'; ++ cw[wl] = '\0'; ++ abbv = 0; ++ } else return 0; ++ } ++ ++ char result[MAXLNLEN]; ++ char * st = NULL; ++ ++ *result = '\0'; ++ ++ int n = 0; ++ int n2 = 0; ++ int n3 = 0; ++ ++ // test numbers ++ // LANG_hu section: set dash information for suggestions ++ if (langnum == LANG_hu) { ++ while ((n < wl) && ++ (((cw[n] <= '9') && (cw[n] >= '0')) || (((cw[n] == '.') || (cw[n] == ',')) && (n > 0)))) { ++ n++; ++ if ((cw[n] == '.') || (cw[n] == ',')) { ++ if (((n2 == 0) && (n > 3)) || ++ ((n2 > 0) && ((cw[n-1] == '.') || (cw[n-1] == ',')))) break; ++ n2++; ++ n3 = n; ++ } ++ } ++ ++ if ((n == wl) && (n3 > 0) && (n - n3 > 3)) return NULL; ++ if ((n == wl) || ((n>0) && ((cw[n]=='%') || (cw[n]=='\xB0')) && checkword(cw+n, NULL, NULL))) { ++ strcat(result, cw); ++ result[n - 1] = '\0'; ++ if (n == wl) { ++ st = pSMgr->suggest_morph(cw + n - 1); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ } else { ++ char sign = cw[n]; ++ cw[n] = '\0'; ++ st = pSMgr->suggest_morph(cw + n - 1); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ strcat(result, "+"); // XXX SPEC. MORPHCODE ++ cw[n] = sign; ++ st = pSMgr->suggest_morph(cw + n); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ } ++ return mystrdup(result); ++ } ++ } ++ // END OF LANG_hu section ++ ++ switch(captype) { ++ case NOCAP: { ++ st = pSMgr->suggest_morph(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ case INITCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ st = pSMgr->suggest_morph(cw); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ case HUHCAP: { ++ st = pSMgr->suggest_morph(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++#if 0 ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++#endif ++ break; ++ } ++ case ALLCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,(wl+1)); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ if (*result) strcat(result, "\n"); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ } ++ ++ if (result && (*result)) { ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ if (utf8) reverseword_utf(result); else reverseword(result); ++ } ++ return mystrdup(result); ++ } ++ ++ // compound word with dash (HU) I18n ++ char * dash = NULL; ++ int nresult = 0; ++ // LANG_hu section: set dash information for suggestions ++ if (langnum == LANG_hu) dash = (char *) strchr(cw,'-'); ++ if ((langnum == LANG_hu) && dash) { ++ *dash='\0'; ++ // examine 2 sides of the dash ++ if (dash[1] == '\0') { // base word ending with dash ++ if (spell(cw)) return pSMgr->suggest_morph(cw); ++ } else if ((dash[1] == 'e') && (dash[2] == '\0')) { // XXX (HU) -e hat. ++ if (spell(cw) && (spell("-e"))) { ++ st = pSMgr->suggest_morph(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ strcat(result,"+"); // XXX spec. separator in MORPHCODE ++ st = pSMgr->suggest_morph("-e"); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ return mystrdup(result); ++ } ++ } else { ++ // first word ending with dash: word- XXX ??? ++ char r2 = *(dash + 1); ++ dash[0]='-'; ++ dash[1]='\0'; ++ nresult = spell(cw); ++ dash[1] = r2; ++ dash[0]='\0'; ++ if (nresult && spell(dash+1) && ((strlen(dash+1) > 1) || ++ ((dash[1] > '0') && (dash[1] < '9')))) { ++ st = morph(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ strcat(result,"+"); // XXX spec. separator in MORPHCODE ++ } ++ st = morph(dash+1); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ return mystrdup(result); ++ } ++ } ++ // affixed number in correct word ++ if (nresult && (dash > cw) && (((*(dash-1)<='9') && ++ (*(dash-1)>='0')) || (*(dash-1)=='.'))) { ++ *dash='-'; ++ n = 1; ++ if (*(dash - n) == '.') n++; ++ // search first not a number character to left from dash ++ while (((dash - n)>=cw) && ((*(dash - n)=='0') || (n < 3)) && (n < 6)) { ++ n++; ++ } ++ if ((dash - n) < cw) n--; ++ // numbers: valami1000000-hoz ++ // examine 100000-hoz, 10000-hoz 1000-hoz, 10-hoz, ++ // 56-hoz, 6-hoz ++ for(; n >= 1; n--) { ++ if ((*(dash - n) >= '0') && (*(dash - n) <= '9') && checkword(dash - n, NULL, NULL)) { ++ strcat(result, cw); ++ result[dash - cw - n] = '\0'; ++ st = pSMgr->suggest_morph(dash - n); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ return mystrdup(result); ++ } ++ } ++ } ++ } ++ return NULL; ++} ++ ++// XXX need UTF-8 support ++char * Hunspell::morph_with_correction(const char * word) ++{ ++ char cw[MAXWORDUTF8LEN]; ++ char wspace[MAXWORDUTF8LEN]; ++ if (! pSMgr) return 0; ++ int wl = strlen(word); ++ if (utf8) { ++ if (wl >= MAXWORDUTF8LEN) return 0; ++ } else { ++ if (wl >= MAXWORDLEN) return 0; ++ } ++ int captype = 0; ++ int abbv = 0; ++ wl = cleanword(cw, word, &captype, &abbv); ++ if (wl == 0) return 0; ++ ++ char result[MAXLNLEN]; ++ char * st = NULL; ++ ++ *result = '\0'; ++ ++ ++ switch(captype) { ++ case NOCAP: { ++ st = pSMgr->suggest_morph_for_spelling_error(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ case INITCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ st = pSMgr->suggest_morph_for_spelling_error(cw); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,wl); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ case HUHCAP: { ++ st = pSMgr->suggest_morph_for_spelling_error(cw); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ memcpy(wspace,cw,(wl+1)); ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ break; ++ } ++ case ALLCAP: { ++ memcpy(wspace,cw,(wl+1)); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ if (abbv) { ++ memcpy(wspace,cw,(wl+1)); ++ *(wspace+wl) = '.'; ++ *(wspace+wl+1) = '\0'; ++ if (*result) strcat(result, "\n"); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ mkallsmall(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ mkinitcap(wspace); ++ st = pSMgr->suggest_morph_for_spelling_error(wspace); ++ if (st) { ++ if (*result) strcat(result, "\n"); ++ strcat(result, st); ++ free(st); ++ } ++ } ++ break; ++ } ++ } ++ ++ if (result) return mystrdup(result); ++ return NULL; ++} ++ ++/* analyze word ++ * return line count ++ * XXX need a better data structure for morphological analysis */ ++int Hunspell::analyze(char ***out, const char *word) { ++ int n = 0; ++ if (!word) return 0; ++ char * m = morph(word); ++ if(!m) return 0; ++ if (!out) ++ { ++ n = line_tok(m, out); ++ free(m); ++ return n; ++ } ++ ++ // without memory allocation ++ /* BUG missing buffer size checking */ ++ int i, p; ++ for(p = 0, i = 0; m[i]; i++) { ++ if(m[i] == '\n' || !m[i+1]) { ++ n++; ++ strncpy((*out)[n++], m + p, i - p + 1); ++ if (m[i] == '\n') (*out)[n++][i - p] = '\0'; ++ if(!m[i+1]) break; ++ p = i + 1; ++ } ++ } ++ free(m); ++ return n; ++} ++ ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++Hunhandle *Hunspell_create(const char * affpath, const char * dpath) ++{ ++ return (Hunhandle*)(new Hunspell(affpath, dpath)); ++} ++ ++void Hunspell_destroy(Hunhandle *pHunspell) ++{ ++ delete (Hunspell*)(pHunspell); ++} ++ ++int Hunspell_spell(Hunhandle *pHunspell, const char *word) ++{ ++ return ((Hunspell*)pHunspell)->spell(word); ++} ++ ++char *Hunspell_get_dic_encoding(Hunhandle *pHunspell) ++{ ++ return ((Hunspell*)pHunspell)->get_dic_encoding(); ++} ++ ++int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word) ++{ ++ return ((Hunspell*)pHunspell)->suggest(slst, word); ++} +Index: mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.h +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.h +@@ -0,0 +1,89 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _MYSPELLMGR_H_ ++#define _MYSPELLMGR_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct Hunhandle Hunhandle; ++ ++Hunhandle *Hunspell_create(const char * affpath, const char * dpath); ++void Hunspell_destroy(Hunhandle *pHunspell); ++ ++/* spell(word) - spellcheck word ++ * output: 0 = bad word, not 0 = good word ++ */ ++int Hunspell_spell(Hunhandle *pHunspell, const char *); ++ ++char *Hunspell_get_dic_encoding(Hunhandle *pHunspell); ++ ++/* suggest(suggestions, word) - search suggestions ++ * input: pointer to an array of strings pointer and the (bad) word ++ * array of strings pointer (here *slst) may not be initialized ++ * output: number of suggestions in string array, and suggestions in ++ * a newly allocated array of strings (*slts will be NULL when number ++ * of suggestion equals 0.) ++ */ ++int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/hunspell.hxx +@@ -0,0 +1,195 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#include "hashmgr.hxx" ++#include "affixmgr.hxx" ++#include "suggestmgr.hxx" ++#include "csutil.hxx" ++#include "langnum.hxx" ++ ++#define SPELL_COMPOUND (1 << 0) ++#define SPELL_FORBIDDEN (1 << 1) ++#define SPELL_ALLCAP (1 << 2) ++#define SPELL_NOCAP (1 << 3) ++#define SPELL_INITCAP (1 << 4) ++ ++#define MAXSUGGESTION 15 ++#define MAXSHARPS 5 ++ ++#ifndef _MYSPELLMGR_HXX_ ++#define _MYSPELLMGR_HXX_ ++ ++#ifdef HUNSPELL_STATIC ++ #define DLLEXPORT ++#else ++ #ifdef HUNSPELL_EXPORTS ++ #define DLLEXPORT __declspec( dllexport ) ++ #else ++ #define DLLEXPORT __declspec( dllimport ) ++ #endif ++#endif ++ ++#ifdef W32 ++class DLLEXPORT Hunspell ++#else ++class Hunspell ++#endif ++{ ++ AffixMgr* pAMgr; ++ HashMgr* pHMgr; ++ SuggestMgr* pSMgr; ++ char * encoding; ++ struct cs_info * csconv; ++ int langnum; ++ int utf8; ++ int complexprefixes; ++ char** wordbreak; ++ ++public: ++ ++ /* Hunspell(aff, dic) - constructor of Hunspell class ++ * input: path of affix file and dictionary file ++ */ ++ ++ Hunspell(const char * affpath, const char * dpath); ++ ++ ~Hunspell(); ++ ++ /* spell(word) - spellcheck word ++ * output: 0 = bad word, not 0 = good word ++ * ++ * plus output: ++ * info: information bit array, fields: ++ * SPELL_COMPOUND = a compound word ++ * SPELL_FORBIDDEN = an explicit forbidden word ++ * root: root (stem), when input is a word with affix(es) ++ */ ++ ++ int spell(const char * word, int * info = NULL, char ** root = NULL); ++ ++ /* suggest(suggestions, word) - search suggestions ++ * input: pointer to an array of strings pointer and the (bad) word ++ * array of strings pointer (here *slst) may not be initialized ++ * output: number of suggestions in string array, and suggestions in ++ * a newly allocated array of strings (*slts will be NULL when number ++ * of suggestion equals 0.) ++ */ ++ ++ int suggest(char*** slst, const char * word); ++ char * get_dic_encoding(); ++ ++ /* handling custom dictionary */ ++ ++ int put_word(const char * word); ++ ++ /* pattern is a sample dictionary word ++ * put word into custom dictionary with affix flags of pattern word ++ */ ++ ++ int put_word_pattern(const char * word, const char * pattern); ++ ++ /* other */ ++ ++ /* get extra word characters definied in affix file for tokenization */ ++ const char * get_wordchars(); ++ unsigned short * get_wordchars_utf16(int * len); ++ ++ struct cs_info * get_csconv(); ++ const char * get_version(); ++ ++ /* experimental functions */ ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++ /* suffix is an affix flag string, similarly in dictionary files */ ++ ++ int put_word_suffix(const char * word, const char * suffix); ++ ++ /* morphological analysis */ ++ ++ char * morph(const char * word); ++ int analyze(char*** out, const char *word); ++ ++ char * morph_with_correction(const char * word); ++ ++ /* stemmer function */ ++ ++ int stem(char*** slst, const char * word); ++ ++ /* spec. suggestions */ ++ int suggest_auto(char*** slst, const char * word); ++ int suggest_pos_stems(char*** slst, const char * word); ++ char * get_possible_root(); ++#endif ++ ++private: ++ int cleanword(char *, const char *, int * pcaptype, int * pabbrev); ++ int cleanword2(char *, const char *, w_char *, int * w_len, int * pcaptype, int * pabbrev); ++ void mkinitcap(char *); ++ int mkinitcap2(char * p, w_char * u, int nc); ++ int mkinitsmall2(char * p, w_char * u, int nc); ++ void mkallcap(char *); ++ int mkallcap2(char * p, w_char * u, int nc); ++ void mkallsmall(char *); ++ int mkallsmall2(char * p, w_char * u, int nc); ++ struct hentry * checkword(const char *, int * info, char **root); ++ char * sharps_u8_l1(char * dest, char * source); ++ hentry * spellsharps(char * base, char *, int, int, char * tmp, int * info, char **root); ++ int is_keepcase(const hentry * rv); ++ int insert_sug(char ***slst, char * word, int ns); ++ ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/langnum.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/langnum.hxx +@@ -0,0 +1,94 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _LANGNUM_HXX_ ++#define _LANGNUM_HXX_ ++ ++/* ++ language numbers for language specific codes ++ see http://l10n.openoffice.org/languages.html ++*/ ++ ++enum { ++LANG_ar=96, ++LANG_az=100, // custom number ++LANG_bg=41, ++LANG_ca=37, ++LANG_cs=42, ++LANG_da=45, ++LANG_de=49, ++LANG_el=30, ++LANG_en=01, ++LANG_es=34, ++LANG_eu=10, ++LANG_fr=02, ++LANG_gl=38, ++LANG_hr=78, ++LANG_hu=36, ++LANG_it=39, ++LANG_la=99, // custom number ++LANG_lv=101, // custom number ++LANG_nl=31, ++LANG_pl=48, ++LANG_pt=03, ++LANG_ru=07, ++LANG_sv=50, ++LANG_tr=90, ++LANG_uk=80, ++LANG_xx=999 ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/phonet.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/phonet.cpp +@@ -0,0 +1,310 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developer of the Original Code is Björn Jacke. Portions created ++ * by the Initial Developers are Copyright (C) 2000-2007 the Initial ++ * Developers. All Rights Reserved. ++ * ++ * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de) ++ * László Németh (nemethl@gyorsposta.hu) ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * Changelog: ++ * 2000-01-05 Björn Jacke ++ * Initial Release insprired by the article about phonetic ++ * transformations out of c't 25/1999 ++ * ++ * 2007-07-26 Björn Jacke ++ * Released under MPL/GPL/LGPL tri-license for Hunspell ++ * ++ * 2007-08-23 László Németh ++ * Porting from Aspell to Hunspell using C-like structs ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "csutil.hxx" ++#include "phonet.hxx" ++ ++void init_phonet_hash(phonetable & parms) ++ { ++ int i, k; ++ ++ for (i = 0; i < parms.hash_size; i++) { ++ parms.hash[i] = -1; ++ } ++ ++ for (i = 0; parms.rules[i][0] != '\0'; i += 2) { ++ /** set hash value **/ ++ k = (unsigned char) parms.rules[i][0]; ++ ++ if (parms.hash[k] < 0) { ++ parms.hash[k] = i; ++ } ++ } ++ } ++ ++ // like strcpy but safe if the strings overlap ++ // but only if dest < src ++ static inline void strmove(char * dest, char * src) { ++ while (*src) ++ *dest++ = *src++; ++ *dest = '\0'; ++ } ++ ++/* phonetic transcription algorithm */ ++/* see: http://aspell.net/man-html/Phonetic-Code.html */ ++/* convert string to uppercase before this call */ ++int phonet (const char * inword, char * target, ++ int len, ++ phonetable & parms) ++ { ++ /** Do phonetic transformation. **/ ++ /** "len" = length of "inword" incl. '\0'. **/ ++ ++ /** result: >= 0: length of "target" **/ ++ /** otherwise: error **/ ++ ++ int i,j,k=0,n,p,z; ++ int k0,n0,p0=-333,z0; ++ char c, c0; ++ const char * s; ++ typedef unsigned char uchar; ++ char word[MAXPHONETUTF8LEN + 1]; ++ if (len == -1) len = strlen(inword); ++ if (len > MAXPHONETUTF8LEN) return 0; ++ strcpy(word, inword); ++ ++ /** check word **/ ++ i = j = z = 0; ++ while ((c = word[i]) != '\0') { ++ n = parms.hash[(uchar) c]; ++ z0 = 0; ++ ++ if (n >= 0) { ++ /** check all rules for the same letter **/ ++ while (parms.rules[n][0] == c) { ++ ++ /** check whole string **/ ++ k = 1; /** number of found letters **/ ++ p = 5; /** default priority **/ ++ s = parms.rules[n]; ++ s++; /** important for (see below) "*(s-1)" **/ ++ ++ while (*s != '\0' && word[i+k] == *s ++ && !isdigit (*s) && strchr ("(-<^$", *s) == NULL) { ++ k++; ++ s++; ++ } ++ if (*s == '(') { ++ /** check letters in "(..)" **/ ++ if (isalpha(word[i+k]) // ...could be implied? ++ && strchr(s+1, word[i+k]) != NULL) { ++ k++; ++ while (*s != ')') ++ s++; ++ s++; ++ } ++ } ++ p0 = (int) *s; ++ k0 = k; ++ while (*s == '-' && k > 1) { ++ k--; ++ s++; ++ } ++ if (*s == '<') ++ s++; ++ if (isdigit (*s)) { ++ /** determine priority **/ ++ p = *s - '0'; ++ s++; ++ } ++ if (*s == '^' && *(s+1) == '^') ++ s++; ++ ++ if (*s == '\0' ++ || (*s == '^' ++ && (i == 0 || ! isalpha(word[i-1])) ++ && (*(s+1) != '$' ++ || (! isalpha(word[i+k0]) ))) ++ || (*s == '$' && i > 0 ++ && isalpha(word[i-1]) ++ && (! isalpha(word[i+k0]) ))) ++ { ++ /** search for followup rules, if: **/ ++ /** parms.followup and k > 1 and NO '-' in searchstring **/ ++ c0 = word[i+k-1]; ++ n0 = parms.hash[(uchar) c0]; ++ ++// if (parms.followup && k > 1 && n0 >= 0 ++ if (k > 1 && n0 >= 0 ++ && p0 != (int) '-' && word[i+k] != '\0') { ++ /** test follow-up rule for "word[i+k]" **/ ++ while (parms.rules[n0][0] == c0) { ++ ++ /** check whole string **/ ++ k0 = k; ++ p0 = 5; ++ s = parms.rules[n0]; ++ s++; ++ while (*s != '\0' && word[i+k0] == *s ++ && ! isdigit(*s) && strchr("(-<^$",*s) == NULL) { ++ k0++; ++ s++; ++ } ++ if (*s == '(') { ++ /** check letters **/ ++ if (isalpha(word[i+k0]) ++ && strchr (s+1, word[i+k0]) != NULL) { ++ k0++; ++ while (*s != ')' && *s != '\0') ++ s++; ++ if (*s == ')') ++ s++; ++ } ++ } ++ while (*s == '-') { ++ /** "k0" gets NOT reduced **/ ++ /** because "if (k0 == k)" **/ ++ s++; ++ } ++ if (*s == '<') ++ s++; ++ if (isdigit (*s)) { ++ p0 = *s - '0'; ++ s++; ++ } ++ ++ if (*s == '\0' ++ /** *s == '^' cuts **/ ++ || (*s == '$' && ! isalpha(word[i+k0]))) ++ { ++ if (k0 == k) { ++ /** this is just a piece of the string **/ ++ n0 += 2; ++ continue; ++ } ++ ++ if (p0 < p) { ++ /** priority too low **/ ++ n0 += 2; ++ continue; ++ } ++ /** rule fits; stop search **/ ++ break; ++ } ++ n0 += 2; ++ } /** End of "while (parms.rules[n0][0] == c0)" **/ ++ ++ if (p0 >= p && parms.rules[n0][0] == c0) { ++ n += 2; ++ continue; ++ } ++ } /** end of follow-up stuff **/ ++ ++ /** replace string **/ ++ s = parms.rules[n+1]; ++ p0 = (parms.rules[n][0] != '\0' ++ && strchr (parms.rules[n]+1,'<') != NULL) ? 1:0; ++ if (p0 == 1 && z == 0) { ++ /** rule with '<' is used **/ ++ if (j > 0 && *s != '\0' ++ && (target[j-1] == c || target[j-1] == *s)) { ++ j--; ++ } ++ z0 = 1; ++ z = 1; ++ k0 = 0; ++ while (*s != '\0' && word[i+k0] != '\0') { ++ word[i+k0] = *s; ++ k0++; ++ s++; ++ } ++ if (k > k0) ++ strmove (&word[0]+i+k0, &word[0]+i+k); ++ ++ /** new "actual letter" **/ ++ c = word[i]; ++ } ++ else { /** no '<' rule used **/ ++ i += k - 1; ++ z = 0; ++ while (*s != '\0' ++ && *(s+1) != '\0' && j < len) { ++ if (j == 0 || target[j-1] != *s) { ++ target[j] = *s; ++ j++; ++ } ++ s++; ++ } ++ /** new "actual letter" **/ ++ c = *s; ++ if (parms.rules[n][0] != '\0' ++ && strstr (parms.rules[n]+1, "^^") != NULL) { ++ if (c != '\0') { ++ target[j] = c; ++ j++; ++ } ++ strmove (&word[0], &word[0]+i+1); ++ i = 0; ++ z0 = 1; ++ } ++ } ++ break; ++ } /** end of follow-up stuff **/ ++ n += 2; ++ } /** end of while (parms.rules[n][0] == c) **/ ++ } /** end of if (n >= 0) **/ ++ if (z0 == 0) { ++// if (k && (assert(p0!=-333),!p0) && j < len && c != '\0' ++// && (!parms.collapse_result || j == 0 || target[j-1] != c)){ ++ if (k && !p0 && j < len && c != '\0' ++ && (1 || j == 0 || target[j-1] != c)){ ++ /** condense only double letters **/ ++ target[j] = c; ++ ///printf("\n setting \n"); ++ j++; ++ } ++ ++ i++; ++ z = 0; ++ k=0; ++ } ++ } /** end of while ((c = word[i]) != '\0') **/ ++ ++ target[j] = '\0'; ++ return (j); ++ ++ } /** end of function "phonet" **/ +Index: mozilla/extensions/spellcheck/hunspell/hunspell/phonet.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/phonet.hxx +@@ -0,0 +1,66 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developer of the Original Code is Björn Jacke. Portions created ++ * by the Initial Developers are Copyright (C) 2000-2007 the Initial ++ * Developers. All Rights Reserved. ++ * ++ * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de) ++ * László Németh (nemethl@gyorsposta.hu) ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * Changelog: ++ * 2000-01-05 Björn Jacke ++ * Initial Release insprired by the article about phonetic ++ * transformations out of c't 25/1999 ++ * ++ * 2007-07-20 Björn Jacke ++ * Released under MPL/GPL/LGPL tri-license for Hunspell ++ * ++ * 2007-08-22 László Németh ++ * Porting from Aspell to Hunspell by little modifications ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef __PHONETHXX__ ++#define __PHONETHXX__ ++ ++#define MAXPHONETLEN 256 ++#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4) ++ ++struct phonetable { ++ char utf8; ++ cs_info * lang; ++ int num; ++ char * * rules; ++ static const int hash_size = 256; ++ int hash[hash_size]; ++}; ++ ++void init_phonet_hash(phonetable & parms); ++ ++int phonet (const char * inword, char * target, ++ int len, phonetable & phone); ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/hunspell/suggestmgr.cpp +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/suggestmgr.cpp +@@ -0,0 +1,2036 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef MOZILLA_CLIENT ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "suggestmgr.hxx" ++ ++#ifndef MOZILLA_CLIENT ++#ifndef W32 ++using namespace std; ++#endif ++#endif ++ ++const w_char W_VLINE = { '\0', '|' }; ++ ++SuggestMgr::SuggestMgr(const char * tryme, int maxn, ++ AffixMgr * aptr) ++{ ++ ++ // register affix manager and check in string of chars to ++ // try when building candidate suggestions ++ pAMgr = aptr; ++ ++ ckeyl = 0; ++ ckey = NULL; ++ ckey_utf = NULL; ++ ++ ctryl = 0; ++ ctry = NULL; ++ ctry_utf = NULL; ++ ++ utf8 = 0; ++ langnum = 0; ++ complexprefixes = 0; ++ ++ maxSug = maxn; ++ nosplitsugs = 0; ++ maxngramsugs = MAXNGRAMSUGS; ++ ++ if (pAMgr) { ++ char * enc = pAMgr->get_encoding(); ++ csconv = get_current_cs(enc); ++ free(enc); ++ langnum = pAMgr->get_langnum(); ++ ckey = pAMgr->get_key_string(); ++ nosplitsugs = pAMgr->get_nosplitsugs(); ++ if (pAMgr->get_maxngramsugs() >= 0) maxngramsugs = pAMgr->get_maxngramsugs(); ++ utf8 = pAMgr->get_utf8(); ++ complexprefixes = pAMgr->get_complexprefixes(); ++ } ++ ++ if (ckey) { ++ if (utf8) { ++ w_char t[MAXSWL]; ++ ckeyl = u8_u16(t, MAXSWL, ckey); ++ ckey_utf = (w_char *) malloc(ckeyl * sizeof(w_char)); ++ if (ckey_utf) memcpy(ckey_utf, t, ckeyl * sizeof(w_char)); ++ } else { ++ ckeyl = strlen(ckey); ++ } ++ } ++ ++ if (tryme) { ++ if (utf8) { ++ w_char t[MAXSWL]; ++ ctryl = u8_u16(t, MAXSWL, tryme); ++ ctry_utf = (w_char *) malloc(ctryl * sizeof(w_char)); ++ if (ctry_utf) memcpy(ctry_utf, t, ctryl * sizeof(w_char)); ++ } else { ++ ctry = mystrdup(tryme); ++ ctryl = strlen(ctry); ++ } ++ } ++} ++ ++ ++SuggestMgr::~SuggestMgr() ++{ ++ pAMgr = NULL; ++ if (ckey) free(ckey); ++ ckey = NULL; ++ if (ckey_utf) free(ckey_utf); ++ ckey_utf = NULL; ++ ckeyl = 0; ++ if (ctry) free(ctry); ++ ctry = NULL; ++ if (ctry_utf) free(ctry_utf); ++ ctry_utf = NULL; ++ ctryl = 0; ++ maxSug = 0; ++} ++ ++int SuggestMgr::testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest, ++ int * timer, clock_t * timelimit) { ++ int cwrd = 1; ++ if (ns == maxSug) return maxSug; ++ for (int k=0; k < ns; k++) { ++ if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; ++ } ++ if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) { ++ wlst[ns] = mystrdup(candidate); ++ if (wlst[ns] == NULL) { ++ for (int j=0; j HTML) ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? capchars_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ capchars(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // perhaps we made a typical fault of spelling ++ if ((nsug < maxSug) && (nsug > -1)) ++ nsug = replchars(wlst, word, nsug, cpdsuggest); ++ ++ // perhaps we made chose the wrong char from a related set ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = mapchars(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we swap the order of chars by mistake ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? swapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ swapchar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we swap the order of non adjacent chars by mistake ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? longswapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ longswapchar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we just hit the wrong key in place of a good char (case and keyboard) ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? badcharkey_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ badcharkey(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we add a char that should not be there ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? extrachar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ extrachar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // only suggest compound words when no other suggestion ++ if ((cpdsuggest == 0) && (nsug > 0)) nocompoundtwowords=1; ++ ++ // did we forgot a char ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? forgotchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ forgotchar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we move a char ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? movechar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ movechar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we just hit the wrong key in place of a good char ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? badchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ badchar(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // did we double two characters ++ if ((nsug < maxSug) && (nsug > -1)) { ++ nsug = (utf8) ? doubletwochars_utf(wlst, word_utf, wl, nsug, cpdsuggest) : ++ doubletwochars(wlst, word, nsug, cpdsuggest); ++ } ++ ++ // perhaps we forgot to hit space and two words ran together ++ if ((!nosplitsugs) && (nsug < maxSug) && (nsug > -1)) { ++ nsug = twowords(wlst, word, nsug, cpdsuggest); ++ } ++ ++ } // repeating ``for'' statement compounding support ++ ++ if (nsug < 0) { ++ // we ran out of memory - we should free up as much as possible ++ for (int i = 0; i < maxSug; i++) ++ if (wlst[i] != NULL) free(wlst[i]); ++ free(wlst); ++ wlst = NULL; ++ } ++ ++ if (!nocompoundtwowords && (nsug > 0) && onlycompoundsug) *onlycompoundsug = 1; ++ ++ *slst = wlst; ++ return nsug; ++} ++ ++// generate suggestions for a word with typical mistake ++// pass in address of array of char * pointers ++#ifdef HUNSPELL_EXPERIMENTAL ++int SuggestMgr::suggest_auto(char*** slst, const char * w, int nsug) ++{ ++ int nocompoundtwowords = 0; ++ char ** wlst; ++ ++ char w2[MAXWORDUTF8LEN]; ++ const char * word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ strcpy(w2, w); ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ word = w2; ++ } ++ ++ if (*slst) { ++ wlst = *slst; ++ } else { ++ wlst = (char **) malloc(maxSug * sizeof(char *)); ++ if (wlst == NULL) return -1; ++ } ++ ++ for (int cpdsuggest=0; (cpdsuggest<2) && (nocompoundtwowords==0); cpdsuggest++) { ++ ++ // perhaps we made a typical fault of spelling ++ if ((nsug < maxSug) && (nsug > -1)) ++ nsug = replchars(wlst, word, nsug, cpdsuggest); ++ ++ // perhaps we made chose the wrong char from a related set ++ if ((nsug < maxSug) && (nsug > -1)) ++ nsug = mapchars(wlst, word, nsug, cpdsuggest); ++ ++ if ((cpdsuggest==0) && (nsug>0)) nocompoundtwowords=1; else * ++ ++ // perhaps we forgot to hit space and two words ran together ++ ++ if ((nsug < maxSug) && (nsug > -1) && check_forbidden(word, strlen(word))) { ++ nsug = twowords(wlst, word, nsug, cpdsuggest); ++ } ++ ++ } // repeating ``for'' statement compounding support ++ ++ if (nsug < 0) { ++ for (int i=0;i HTML) ++int SuggestMgr::capchars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ w_char candidate_utf[MAXSWL]; ++ memcpy(candidate_utf, word, wl * sizeof(w_char)); ++ mkallcap_utf(candidate_utf, wl, langnum); ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++} ++ ++// suggestions for an uppercase word (html -> HTML) ++int SuggestMgr::capchars(char** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ strcpy(candidate, word); ++ mkallcap(candidate, csconv); ++ return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++} ++ ++// suggestions for when chose the wrong char out of a related set ++int SuggestMgr::mapchars(char** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ clock_t timelimit; ++ int timer; ++ ++ int wl = strlen(word); ++ if (wl < 2 || ! pAMgr) return ns; ++ ++ int nummap = pAMgr->get_nummap(); ++ struct mapentry* maptable = pAMgr->get_maptable(); ++ if (maptable==NULL) return ns; ++ ++ timelimit = clock(); ++ timer = MINTIMER; ++ if (utf8) { ++ w_char w[MAXSWL]; ++ int len = u8_u16(w, MAXSWL, word); ++ ns = map_related_utf(w, len, 0, cpdsuggest, wlst, ns, maptable, nummap, &timer, &timelimit); ++ } else ns = map_related(word, 0, wlst, cpdsuggest, ns, maptable, nummap, &timer, &timelimit); ++ return ns; ++} ++ ++int SuggestMgr::map_related(const char * word, int i, char** wlst, ++ int cpdsuggest, int ns, ++ const mapentry* maptable, int nummap, int * timer, clock_t * timelimit) ++{ ++ char c = *(word + i); ++ if (c == 0) { ++ int cwrd = 1; ++ int wl = strlen(word); ++ for (int m=0; m < ns; m++) ++ if (strcmp(word,wlst[m]) == 0) cwrd = 0; ++ if ((cwrd) && checkword(word, wl, cpdsuggest, timer, timelimit)) { ++ if (ns < maxSug) { ++ wlst[ns] = mystrdup(word); ++ if (wlst[ns] == NULL) return -1; ++ ns++; ++ } ++ } ++ return ns; ++ } ++ int in_map = 0; ++ for (int j = 0; j < nummap; j++) { ++ if (strchr(maptable[j].set,c) != 0) { ++ in_map = 1; ++ char * newword = mystrdup(word); ++ for (int k = 0; k < maptable[j].len; k++) { ++ *(newword + i) = *(maptable[j].set + k); ++ ns = map_related(newword, (i+1), wlst, cpdsuggest, ++ ns, maptable, nummap, timer, timelimit); ++ if (!(*timer)) return ns; ++ } ++ free(newword); ++ } ++ } ++ if (!in_map) { ++ i++; ++ ns = map_related(word, i, wlst, cpdsuggest, ++ ns, maptable, nummap, timer, timelimit); ++ } ++ return ns; ++} ++ ++int SuggestMgr::map_related_utf(w_char * word, int len, int i, int cpdsuggest, ++ char** wlst, int ns, const mapentry* maptable, int nummap, ++ int * timer, clock_t * timelimit) ++{ ++ if (i == len) { ++ int cwrd = 1; ++ int wl; ++ char s[MAXSWUTF8L]; ++ u16_u8(s, MAXSWUTF8L, word, len); ++ wl = strlen(s); ++ for (int m=0; m < ns; m++) ++ if (strcmp(s,wlst[m]) == 0) cwrd = 0; ++ if ((cwrd) && checkword(s, wl, cpdsuggest, timer, timelimit)) { ++ if (ns < maxSug) { ++ wlst[ns] = mystrdup(s); ++ if (wlst[ns] == NULL) return -1; ++ ns++; ++ } ++ } ++ return ns; ++ } ++ int in_map = 0; ++ unsigned short c = *((unsigned short *) word + i); ++ for (int j = 0; j < nummap; j++) { ++ if (flag_bsearch((unsigned short *) maptable[j].set_utf16, c, maptable[j].len)) { ++ in_map = 1; ++ for (int k = 0; k < maptable[j].len; k++) { ++ *(word + i) = *(maptable[j].set_utf16 + k); ++ ns = map_related_utf(word, len, i + 1, cpdsuggest, ++ wlst, ns, maptable, nummap, timer, timelimit); ++ if (!(*timer)) return ns; ++ } ++ *((unsigned short *) word + i) = c; ++ } ++ } ++ if (!in_map) { ++ i++; ++ ns = map_related_utf(word, len, i, cpdsuggest, ++ wlst, ns, maptable, nummap, timer, timelimit); ++ } ++ return ns; ++} ++ ++ ++ ++// suggestions for a typical fault of spelling, that ++// differs with more, than 1 letter from the right form. ++int SuggestMgr::replchars(char** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ const char * r; ++ int lenr, lenp; ++ int wl = strlen(word); ++ if (wl < 2 || ! pAMgr) return ns; ++ int numrep = pAMgr->get_numrep(); ++ struct replentry* reptable = pAMgr->get_reptable(); ++ if (reptable==NULL) return ns; ++ for (int i=0; i < numrep; i++ ) { ++ r = word; ++ lenr = strlen(reptable[i].pattern2); ++ lenp = strlen(reptable[i].pattern); ++ // search every occurence of the pattern in the word ++ while ((r=strstr(r, reptable[i].pattern)) != NULL) { ++ strcpy(candidate, word); ++ if (r-word + lenr + strlen(r+lenp) >= MAXSWUTF8L) break; ++ strcpy(candidate+(r-word),reptable[i].pattern2); ++ strcpy(candidate+(r-word)+lenr, r+lenp); ++ ns = testsug(wlst, candidate, wl-lenp+lenr, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ // check REP suggestions with space ++ char * sp = strchr(candidate, ' '); ++ if (sp) { ++ *sp = '\0'; ++ if (checkword(candidate, strlen(candidate), 0, NULL, NULL)) { ++ int oldns = ns; ++ *sp = ' '; ++ ns = testsug(wlst, sp + 1, strlen(sp + 1), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ if (oldns < ns) { ++ free(wlst[ns - 1]); ++ wlst[ns - 1] = mystrdup(candidate); ++ } ++ } ++ *sp = ' '; ++ } ++ r++; // search for the next letter ++ } ++ } ++ return ns; ++} ++ ++// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation) ++int SuggestMgr::doubletwochars(char** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ int state=0; ++ int wl = strlen(word); ++ if (wl < 5 || ! pAMgr) return ns; ++ for (int i=2; i < wl; i++ ) { ++ if (word[i]==word[i-2]) { ++ state++; ++ if (state==3) { ++ strcpy(candidate,word); ++ strcpy(candidate+i-1,word+i+1); ++ ns = testsug(wlst, candidate, wl-2, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ state=0; ++ } ++ } else { ++ state=0; ++ } ++ } ++ return ns; ++} ++ ++// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation) ++int SuggestMgr::doubletwochars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ int state=0; ++ if (wl < 5 || ! pAMgr) return ns; ++ for (int i=2; i < wl; i++) { ++ if (w_char_eq(word[i], word[i-2])) { ++ state++; ++ if (state==3) { ++ memcpy(candidate_utf, word, (i - 1) * sizeof(w_char)); ++ memcpy(candidate_utf+i-1, word+i+1, (wl-i-1) * sizeof(w_char)); ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl-2); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ state=0; ++ } ++ } else { ++ state=0; ++ } ++ } ++ return ns; ++} ++ ++// error is wrong char in place of correct one (case and keyboard related version) ++int SuggestMgr::badcharkey(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char tmpc; ++ char candidate[MAXSWUTF8L]; ++ int wl = strlen(word); ++ strcpy(candidate, word); ++ // swap out each char one by one and try uppercase and neighbor ++ // keyboard chars in its place to see if that makes a good word ++ ++ for (int i=0; i < wl; i++) { ++ tmpc = candidate[i]; ++ // check with uppercase letters ++ candidate[i] = csconv[((unsigned char)tmpc)].cupper; ++ if (tmpc != candidate[i]) { ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ candidate[i] = tmpc; ++ } ++ // check neighbor characters in keyboard string ++ if (!ckey) continue; ++ char * loc = strchr(ckey, tmpc); ++ while (loc) { ++ if ((loc > ckey) && (*(loc - 1) != '|')) { ++ candidate[i] = *(loc - 1); ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ if ((*(loc + 1) != '|') && (*(loc + 1) != '\0')) { ++ candidate[i] = *(loc + 1); ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ loc = strchr(loc + 1, tmpc); ++ } ++ candidate[i] = tmpc; ++ } ++ return ns; ++} ++ ++// error is wrong char in place of correct one (case and keyboard related version) ++int SuggestMgr::badcharkey_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char tmpc; ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ memcpy(candidate_utf, word, wl * sizeof(w_char)); ++ // swap out each char one by one and try all the tryme ++ // chars in its place to see if that makes a good word ++ for (int i=0; i < wl; i++) { ++ tmpc = candidate_utf[i]; ++ // check with uppercase letters ++ mkallcap_utf(candidate_utf + i, 1, langnum); ++ if (!w_char_eq(tmpc, candidate_utf[i])) { ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ candidate_utf[i] = tmpc; ++ } ++ // check neighbor characters in keyboard string ++ if (!ckey) continue; ++ w_char * loc = ckey_utf; ++ while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc)) loc++; ++ while (loc < (ckey_utf + ckeyl)) { ++ if ((loc > ckey_utf) && !w_char_eq(*(loc - 1), W_VLINE)) { ++ candidate_utf[i] = *(loc - 1); ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ if (((loc + 1) < (ckey_utf + ckeyl)) && !w_char_eq(*(loc + 1), W_VLINE)) { ++ candidate_utf[i] = *(loc + 1); ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ do { loc++; } while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc)); ++ } ++ candidate_utf[i] = tmpc; ++ } ++ return ns; ++} ++ ++// error is wrong char in place of correct one ++int SuggestMgr::badchar(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char tmpc; ++ char candidate[MAXSWUTF8L]; ++ clock_t timelimit = clock(); ++ int timer = MINTIMER; ++ int wl = strlen(word); ++ strcpy(candidate, word); ++ // swap out each char one by one and try all the tryme ++ // chars in its place to see if that makes a good word ++ for (int i=0; i < wl; i++) { ++ tmpc = candidate[i]; ++ for (int j=0; j < ctryl; j++) { ++ if (ctry[j] == tmpc) continue; ++ candidate[i] = ctry[j]; ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, &timer, &timelimit); ++ if (ns == -1) return -1; ++ if (!timer) return ns; ++ candidate[i] = tmpc; ++ } ++ } ++ return ns; ++} ++ ++// error is wrong char in place of correct one ++int SuggestMgr::badchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char tmpc; ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ clock_t timelimit = clock(); ++ int timer = MINTIMER; ++ memcpy(candidate_utf, word, wl * sizeof(w_char)); ++ // swap out each char one by one and try all the tryme ++ // chars in its place to see if that makes a good word ++ for (int i=0; i < wl; i++) { ++ tmpc = candidate_utf[i]; ++ for (int j=0; j < ctryl; j++) { ++ if (w_char_eq(tmpc, ctry_utf[j])) continue; ++ candidate_utf[i] = ctry_utf[j]; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit); ++ if (ns == -1) return -1; ++ if (!timer) return ns; ++ candidate_utf[i] = tmpc; ++ } ++ } ++ return ns; ++} ++ ++// error is word has an extra letter it does not need ++int SuggestMgr::extrachar_utf(char** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ w_char candidate_utf[MAXSWL]; ++ const w_char * p; ++ w_char * r; ++ if (wl < 2) return ns; ++ // try omitting one char of word at a time ++ memcpy(candidate_utf, word + 1, (wl - 1) * sizeof(w_char)); ++ for (p = word, r = candidate_utf; p < word + wl; ) { ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl - 1); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ *r++ = *p++; ++ } ++ return ns; ++} ++ ++// error is word has an extra letter it does not need ++int SuggestMgr::extrachar(char** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ const char * p; ++ char * r; ++ int wl = strlen(word); ++ if (wl < 2) return ns; ++ // try omitting one char of word at a time ++ strcpy (candidate, word + 1); ++ for (p = word, r = candidate; *p != 0; ) { ++ ns = testsug(wlst, candidate, wl-1, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ *r++ = *p++; ++ } ++ return ns; ++} ++ ++ ++// error is missing a letter it needs ++int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ const char * p; ++ char * q; ++ clock_t timelimit = clock(); ++ int timer = MINTIMER; ++ int wl = strlen(word); ++ // try inserting a tryme character before every letter ++ strcpy(candidate + 1, word); ++ for (p = word, q = candidate; *p != 0; ) { ++ for (int i = 0; i < ctryl; i++) { ++ *q = ctry[i]; ++ ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, &timer, &timelimit); ++ if (ns == -1) return -1; ++ if (!timer) return ns; ++ } ++ *q++ = *p++; ++ } ++ // now try adding one to end */ ++ for (int i = 0; i < ctryl; i++) { ++ *q = ctry[i]; ++ ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ return ns; ++} ++ ++// error is missing a letter it needs ++int SuggestMgr::forgotchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ const w_char * p; ++ w_char * q; ++ int cwrd; ++ clock_t timelimit = clock(); ++ int timer = MINTIMER; ++ // try inserting a tryme character before every letter ++ memcpy (candidate_utf + 1, word, wl * sizeof(w_char)); ++ for (p = word, q = candidate_utf; p < (word + wl); ) { ++ for (int i = 0; i < ctryl; i++) { ++ *q = ctry_utf[i]; ++ cwrd = 1; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit); ++ if (ns == -1) return -1; ++ if (!timer) return ns; ++ } ++ *q++ = *p++; ++ } ++ // now try adding one to end */ ++ for (int i = 0; i < ctryl; i++) { ++ *q = ctry_utf[i]; ++ cwrd = 1; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ return ns; ++} ++ ++ ++/* error is should have been two words */ ++int SuggestMgr::twowords(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ char * p; ++ int c1, c2; ++ int forbidden = 0; ++ int cwrd; ++ ++ int wl=strlen(word); ++ if (wl < 3) return ns; ++ ++ if (langnum == LANG_hu) forbidden = check_forbidden(word, wl); ++ ++ strcpy(candidate + 1, word); ++ // split the string into two pieces after every char ++ // if both pieces are good words make them a suggestion ++ for (p = candidate + 1; p[1] != '\0'; p++) { ++ p[-1] = *p; ++ // go to end of the UTF-8 character ++ while (utf8 && ((p[1] & 0xc0) == 0x80)) { ++ *p = p[1]; ++ p++; ++ } ++ if (utf8 && p[1] == '\0') break; // last UTF-8 character ++ *p = '\0'; ++ c1 = checkword(candidate,strlen(candidate), cpdsuggest, NULL, NULL); ++ if (c1) { ++ c2 = checkword((p+1),strlen(p+1), cpdsuggest, NULL, NULL); ++ if (c2) { ++ *p = ' '; ++ ++ // spec. Hungarian code (need a better compound word support) ++ if ((langnum == LANG_hu) && !forbidden && ++ // if 3 repeating letter, use - instead of space ++ (((p[-1] == p[1]) && (((p>candidate+1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) || ++ // or multiple compounding, with more, than 6 syllables ++ ((c1 == 3) && (c2 >= 2)))) *p = '-'; ++ ++ cwrd = 1; ++ for (int k=0; k < ns; k++) ++ if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; ++ if (ns < maxSug) { ++ if (cwrd) { ++ wlst[ns] = mystrdup(candidate); ++ if (wlst[ns] == NULL) return -1; ++ ns++; ++ } ++ } else return ns; ++ } ++ } ++ } ++ return ns; ++} ++ ++ ++// error is adjacent letter were swapped ++int SuggestMgr::swapchar(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ char * p; ++ char tmpc; ++ int wl=strlen(word); ++ // try swapping adjacent chars one by one ++ strcpy(candidate, word); ++ for (p = candidate; p[1] != 0; p++) { ++ tmpc = *p; ++ *p = p[1]; ++ p[1] = tmpc; ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ p[1] = *p; ++ *p = tmpc; ++ } ++ // try double swaps for short words ++ // ahev -> have, owudl -> would ++ if (wl == 4 || wl == 5) { ++ candidate[0] = word[1]; ++ candidate[1] = word[0]; ++ candidate[2] = word[2]; ++ candidate[wl - 2] = word[wl - 1]; ++ candidate[wl - 1] = word[wl - 2]; ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ if (wl == 5) { ++ candidate[0] = word[0]; ++ candidate[1] = word[2]; ++ candidate[2] = word[1]; ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ } ++ return ns; ++} ++ ++// error is adjacent letter were swapped ++int SuggestMgr::swapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ w_char * p; ++ w_char tmpc; ++ int len = 0; ++ // try swapping adjacent chars one by one ++ memcpy (candidate_utf, word, wl * sizeof(w_char)); ++ for (p = candidate_utf; p < (candidate_utf + wl - 1); p++) { ++ tmpc = *p; ++ *p = p[1]; ++ p[1] = tmpc; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ if (len == 0) len = strlen(candidate); ++ ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ p[1] = *p; ++ *p = tmpc; ++ } ++ // try double swaps for short words ++ // ahev -> have, owudl -> would, suodn -> sound ++ if (wl == 4 || wl == 5) { ++ candidate_utf[0] = word[1]; ++ candidate_utf[1] = word[0]; ++ candidate_utf[2] = word[2]; ++ candidate_utf[wl - 2] = word[wl - 1]; ++ candidate_utf[wl - 1] = word[wl - 2]; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ if (wl == 5) { ++ candidate_utf[0] = word[0]; ++ candidate_utf[1] = word[2]; ++ candidate_utf[2] = word[1]; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ } ++ return ns; ++} ++ ++// error is not adjacent letter were swapped ++int SuggestMgr::longswapchar(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ char * p; ++ char * q; ++ char tmpc; ++ int wl=strlen(word); ++ // try swapping not adjacent chars one by one ++ strcpy(candidate, word); ++ for (p = candidate; *p != 0; p++) { ++ for (q = candidate; *q != 0; q++) { ++ if (abs(p-q) > 1) { ++ tmpc = *p; ++ *p = *q; ++ *q = tmpc; ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ *q = *p; ++ *p = tmpc; ++ } ++ } ++ } ++ return ns; ++} ++ ++ ++// error is adjacent letter were swapped ++int SuggestMgr::longswapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ w_char * p; ++ w_char * q; ++ w_char tmpc; ++ // try swapping not adjacent chars ++ memcpy (candidate_utf, word, wl * sizeof(w_char)); ++ for (p = candidate_utf; p < (candidate_utf + wl); p++) { ++ for (q = candidate_utf; q < (candidate_utf + wl); q++) { ++ if (abs(p-q) > 1) { ++ tmpc = *p; ++ *p = *q; ++ *q = tmpc; ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ *q = *p; ++ *p = tmpc; ++ } ++ } ++ } ++ return ns; ++} ++ ++// error is a letter was moved ++int SuggestMgr::movechar(char ** wlst, const char * word, int ns, int cpdsuggest) ++{ ++ char candidate[MAXSWUTF8L]; ++ char * p; ++ char * q; ++ char tmpc; ++ ++ int wl=strlen(word); ++ // try moving a char ++ strcpy(candidate, word); ++ for (p = candidate; *p != 0; p++) { ++ for (q = p + 1; (*q != 0) && ((q - p) < 10); q++) { ++ tmpc = *(q-1); ++ *(q-1) = *q; ++ *q = tmpc; ++ if ((q-p) < 2) continue; // omit swap char ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ strcpy(candidate, word); ++ } ++ for (p = candidate + wl - 1; p > candidate; p--) { ++ for (q = p - 1; (q >= candidate) && ((p - q) < 10); q--) { ++ tmpc = *(q+1); ++ *(q+1) = *q; ++ *q = tmpc; ++ if ((p-q) < 2) continue; // omit swap char ++ ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ strcpy(candidate, word); ++ } ++ return ns; ++} ++ ++// error is a letter was moved ++int SuggestMgr::movechar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) ++{ ++ w_char candidate_utf[MAXSWL]; ++ char candidate[MAXSWUTF8L]; ++ w_char * p; ++ w_char * q; ++ w_char tmpc; ++ // try moving a char ++ memcpy (candidate_utf, word, wl * sizeof(w_char)); ++ for (p = candidate_utf; p < (candidate_utf + wl); p++) { ++ for (q = p + 1; (q < (candidate_utf + wl)) && ((q - p) < 10); q++) { ++ tmpc = *(q-1); ++ *(q-1) = *q; ++ *q = tmpc; ++ if ((q-p) < 2) continue; // omit swap char ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ memcpy (candidate_utf, word, wl * sizeof(w_char)); ++ } ++ for (p = candidate_utf + wl - 1; p > candidate_utf; p--) { ++ for (q = p - 1; (q >= candidate_utf) && ((p - q) < 10); q--) { ++ tmpc = *(q+1); ++ *(q+1) = *q; ++ *q = tmpc; ++ if ((p-q) < 2) continue; // omit swap char ++ u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); ++ ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); ++ if (ns == -1) return -1; ++ } ++ memcpy (candidate_utf, word, wl * sizeof(w_char)); ++ } ++ return ns; ++} ++ ++// generate a set of suggestions for very poorly spelled words ++int SuggestMgr::ngsuggest(char** wlst, char * w, int ns, HashMgr* pHMgr) ++{ ++ ++ int i, j; ++ int lval; ++ int sc, scphon; ++ int lp, lpphon; ++ int nonbmp = 0; ++ ++ if (!pHMgr) return ns; ++ ++ // exhaustively search through all root words ++ // keeping track of the MAX_ROOTS most similar root words ++ struct hentry * roots[MAX_ROOTS]; ++ char * rootsphon[MAX_ROOTS]; ++ int scores[MAX_ROOTS]; ++ int scoresphon[MAX_ROOTS]; ++ for (i = 0; i < MAX_ROOTS; i++) { ++ roots[i] = NULL; ++ scores[i] = -100 * i; ++ rootsphon[i] = NULL; ++ scoresphon[i] = -100 * i; ++ } ++ lp = MAX_ROOTS - 1; ++ lpphon = MAX_ROOTS - 1; ++ scphon = scoresphon[MAX_ROOTS-1]; ++ ++ char w2[MAXWORDUTF8LEN]; ++ char * word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ strcpy(w2, w); ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ word = w2; ++ } ++ ++ char mw[MAXSWUTF8L]; ++ w_char u8[MAXSWL]; ++ int nc = strlen(word); ++ int n = (utf8) ? u8_u16(u8, MAXSWL, word) : nc; ++ ++ // set character based ngram suggestion for words with non-BMP Unicode characters ++ if (n == -1) { ++ utf8 = 0; ++ n = nc; ++ nonbmp = 1; ++ } ++ ++ struct hentry* hp = NULL; ++ int col = -1; ++ phonetable * ph = (pAMgr) ? pAMgr->get_phonetable() : NULL; ++ char target[MAXSWUTF8L]; ++ char candidate[MAXSWUTF8L]; ++ if (ph) { ++ strcpy(candidate, word); ++ mkallcap(candidate, csconv); ++ phonet(candidate, target, n, *ph); ++// fprintf(stderr, "Tip: %s->%s\n", candidate, target); ++ } ++ ++ while ((hp = pHMgr->walk_hashtable(col, hp))) { ++ if ((hp->astr) && (pAMgr) && ++ (TESTAFF(hp->astr, pAMgr->get_forbiddenword(), hp->alen) || ++ TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) || ++ TESTAFF(hp->astr, pAMgr->get_nosuggest(), hp->alen) || ++ TESTAFF(hp->astr, pAMgr->get_onlyincompound(), hp->alen))) continue; ++ ++ sc = ngram(3, word, &(hp->word), NGRAM_LONGER_WORSE + NGRAM_LOWERING) + ++ leftcommonsubstring(word, &(hp->word)); ++ ++ // check special pronounciation ++ if (hp->var) { ++ int sc2 = ngram(3, word, &(hp->word) + hp->blen + 1, NGRAM_LONGER_WORSE + NGRAM_LOWERING) + ++ leftcommonsubstring(word, &(hp->word) + hp->blen + 1); ++ if (sc2 > sc) sc = sc2; ++ } ++ ++ if (ph && (sc > 2) && (abs(n - (int) hp->clen) <= 3)) { ++ char target2[MAXSWUTF8L]; ++ strcpy(candidate, &(hp->word)); ++ mkallcap(candidate, csconv); ++ phonet(candidate, target2, -1, *ph); ++ scphon = 2 * ngram(3, target, target2, NGRAM_LONGER_WORSE); ++ } ++ ++ if (sc > scores[lp]) { ++ scores[lp] = sc; ++ roots[lp] = hp; ++ lval = sc; ++ for (j=0; j < MAX_ROOTS; j++) ++ if (scores[j] < lval) { ++ lp = j; ++ lval = scores[j]; ++ } ++ } ++ ++ if (scphon > scoresphon[lpphon]) { ++ scoresphon[lpphon] = scphon; ++ rootsphon[lpphon] = &(hp->word); ++ lval = scphon; ++ for (j=0; j < MAX_ROOTS; j++) ++ if (scoresphon[j] < lval) { ++ lpphon = j; ++ lval = scoresphon[j]; ++ } ++ } ++ } ++ ++ // find minimum threshhold for a passable suggestion ++ // mangle original word three differnt ways ++ // and score them to generate a minimum acceptable score ++ int thresh = 0; ++ for (int sp = 1; sp < 4; sp++) { ++ if (utf8) { ++ for (int k=sp; k < n; k+=4) *((unsigned short *) u8 + k) = '*'; ++ u16_u8(mw, MAXSWUTF8L, u8, n); ++ thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING); ++ } else { ++ strcpy(mw, word); ++ for (int k=sp; k < n; k+=4) *(mw + k) = '*'; ++ thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING); ++ } ++ } ++ thresh = thresh / 3; ++ thresh--; ++ ++ // now expand affixes on each of these root words and ++ // and use length adjusted ngram scores to select ++ // possible suggestions ++ char * guess[MAX_GUESS]; ++ char * guessorig[MAX_GUESS]; ++ int gscore[MAX_GUESS]; ++ for(i=0;iexpand_rootword(glst, MAX_WORDS, &(rp->word), rp->blen, ++ rp->astr, rp->alen, word, nc, ++ ((rp->var) ? &(rp->word) + rp->blen + 1 : NULL)); ++ ++ for (int k = 0; k < nw ; k++) { ++ sc = ngram(n, word, glst[k].word, NGRAM_ANY_MISMATCH + NGRAM_LOWERING) + ++ leftcommonsubstring(word, glst[k].word); ++ ++ if ((sc > thresh)) { ++ if (sc > gscore[lp]) { ++ if (guess[lp]) { ++ free (guess[lp]); ++ if (guessorig[lp]) { ++ free(guessorig[lp]); ++ guessorig[lp] = NULL; ++ } ++ } ++ gscore[lp] = sc; ++ guess[lp] = glst[k].word; ++ guessorig[lp] = glst[k].orig; ++ lval = sc; ++ for (j=0; j < MAX_GUESS; j++) ++ if (gscore[j] < lval) { ++ lp = j; ++ lval = gscore[j]; ++ } ++ } else { ++ free(glst[k].word); ++ if (glst[k].orig) free(glst[k].orig); ++ } ++ } else { ++ free(glst[k].word); ++ if (glst[k].orig) free(glst[k].orig); ++ } ++ } ++ } ++ } ++ free(glst); ++ ++ // now we are done generating guesses ++ // sort in order of decreasing score ++ ++ ++ bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS); ++ if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS); ++ ++ // weight suggestions with a similarity index, based on ++ // the longest common subsequent algorithm and resort ++ ++ int is_swap; ++ for (i=0; i < MAX_GUESS; i++) { ++ if (guess[i]) { ++ // lowering guess[i] ++ char gl[MAXSWUTF8L]; ++ int len; ++ if (utf8) { ++ w_char _w[MAXSWL]; ++ len = u8_u16(_w, MAXSWL, guess[i]); ++ mkallsmall_utf(_w, len, langnum); ++ u16_u8(gl, MAXSWUTF8L, _w, len); ++ } else { ++ strcpy(gl, guess[i]); ++ mkallsmall(gl, csconv); ++ len = strlen(guess[i]); ++ } ++ ++ int _lcs = lcslen(word, gl); ++ ++ // same characters with different casing ++ if ((n == len) && (n == _lcs)) { ++ gscore[i] += 2000; ++ break; ++ } ++ ++ // heuristic weigthing of ngram scores ++ gscore[i] += ++ // length of longest common subsequent minus length difference ++ 2 * _lcs - abs((int) (n - len)) + ++ // weight length of the left common substring ++ leftcommonsubstring(word, gl) + ++ // weight equal character positions ++ ((_lcs == commoncharacterpositions(word, gl, &is_swap)) ? 1: 0) + ++ // swap character (not neighboring) ++ ((is_swap) ? 1000 : 0); ++ } ++ } ++ ++ bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS); ++ ++// phonetic version ++ if (ph) for (i=0; i < MAX_ROOTS; i++) { ++ if (rootsphon[i]) { ++ // lowering rootphon[i] ++ char gl[MAXSWUTF8L]; ++ int len; ++ if (utf8) { ++ w_char _w[MAXSWL]; ++ len = u8_u16(_w, MAXSWL, rootsphon[i]); ++ mkallsmall_utf(_w, len, langnum); ++ u16_u8(gl, MAXSWUTF8L, _w, len); ++ } else { ++ strcpy(gl, rootsphon[i]); ++ mkallsmall(gl, csconv); ++ len = strlen(rootsphon[i]); ++ } ++ ++ // heuristic weigthing of ngram scores ++ scoresphon[i] += 2 * lcslen(word, gl) - abs((int) (n - len)) + ++ // weight length of the left common substring ++ leftcommonsubstring(word, gl); ++ } ++ } ++ ++ if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS); ++ ++ // copy over ++ int oldns = ns; ++ ++ int same = 0; ++ for (i=0; i < MAX_GUESS; i++) { ++ if (guess[i]) { ++ if ((ns < oldns + maxngramsugs) && (ns < maxSug) && (!same || (gscore[i] > 1000))) { ++ int unique = 1; ++ // leave only excellent suggestions, if exists ++ if (gscore[i] > 1000) same = 1; ++ for (j = 0; j < ns; j++) { ++ // don't suggest previous suggestions or a previous suggestion with prefixes or affixes ++ if ((!guessorig[i] && strstr(guess[i], wlst[j])) || ++ (guessorig[i] && strstr(guessorig[i], wlst[j])) || ++ // check forbidden words ++ !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) unique = 0; ++ } ++ if (unique) { ++ wlst[ns++] = guess[i]; ++ if (guessorig[i]) { ++ free(guess[i]); ++ wlst[ns-1] = guessorig[i]; ++ } ++ } else { ++ free(guess[i]); ++ if (guessorig[i]) free(guessorig[i]); ++ } ++ } else { ++ free(guess[i]); ++ if (guessorig[i]) free(guessorig[i]); ++ } ++ } ++ } ++ ++ oldns = ns; ++ if (ph) for (i=0; i < MAX_ROOTS; i++) { ++ if (rootsphon[i]) { ++ if ((ns < oldns + MAXPHONSUGS) && (ns < maxSug)) { ++ int unique = 1; ++ for (j = 0; j < ns; j++) { ++ // don't suggest previous suggestions or a previous suggestion with prefixes or affixes ++ if (strstr(rootsphon[i], wlst[j]) || ++ // check forbidden words ++ !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) unique = 0; ++ } ++ if (unique) wlst[ns++] = mystrdup(rootsphon[i]); ++ } ++ } ++ } ++ ++ if (nonbmp) utf8 = 1; ++ return ns; ++} ++ ++ ++// see if a candidate suggestion is spelled correctly ++// needs to check both root words and words with affixes ++ ++// obsolote MySpell-HU modifications: ++// return value 2 and 3 marks compounding with hyphen (-) ++// `3' marks roots without suffix ++int SuggestMgr::checkword(const char * word, int len, int cpdsuggest, int * timer, clock_t * timelimit) ++{ ++ struct hentry * rv=NULL; ++ int nosuffix = 0; ++ ++ // check time limit ++ if (timer) { ++ (*timer)--; ++ if (!(*timer) && timelimit) { ++ if ((clock() - *timelimit) > TIMELIMIT) return 0; ++ *timer = MAXPLUSTIMER; ++ } ++ } ++ ++ if (pAMgr) { ++ if (cpdsuggest==1) { ++ if (pAMgr->get_compound()) { ++ rv = pAMgr->compound_check(word,len,0,0,0,0,NULL,0,NULL,NULL,1); ++ if (rv) return 3; // XXX obsolote categorisation ++ } ++ return 0; ++ } ++ ++ rv = pAMgr->lookup(word); ++ ++ if (rv) { ++ if ((rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen) ++ || TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen))) return 0; ++ while (rv) { ++ if (rv->astr && (TESTAFF(rv->astr,pAMgr->get_pseudoroot(),rv->alen) || ++ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) || ++ TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) { ++ rv = rv->next_homonym; ++ } else break; ++ } ++ } else rv = pAMgr->prefix_check(word, len, 0); // only prefix, and prefix + suffix XXX ++ ++ if (rv) { ++ nosuffix=1; ++ } else { ++ rv = pAMgr->suffix_check(word, len, 0, NULL, NULL, 0, NULL); // only suffix ++ } ++ ++ if (!rv && pAMgr->have_contclass()) { ++ rv = pAMgr->suffix_check_twosfx(word, len, 0, NULL, FLAG_NULL); ++ if (!rv) rv = pAMgr->prefix_check_twosfx(word, len, 1, FLAG_NULL); ++ } ++ ++ // check forbidden words ++ if ((rv) && (rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen) || ++ TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) || ++ TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen) || ++ TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) return 0; ++ ++ if (rv) { // XXX obsolote ++ if ((pAMgr->get_compoundflag()) && ++ TESTAFF(rv->astr, pAMgr->get_compoundflag(), rv->alen)) return 2 + nosuffix; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int SuggestMgr::check_forbidden(const char * word, int len) ++{ ++ struct hentry * rv = NULL; ++ ++ if (pAMgr) { ++ rv = pAMgr->lookup(word); ++ if (rv && rv->astr && (TESTAFF(rv->astr,pAMgr->get_pseudoroot(),rv->alen) || ++ TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) rv = NULL; ++ if (!(pAMgr->prefix_check(word,len,1))) ++ rv = pAMgr->suffix_check(word,len, 0, NULL, NULL, 0, NULL); // prefix+suffix, suffix ++ // check forbidden words ++ if ((rv) && (rv->astr) && TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen)) return 1; ++ } ++ return 0; ++} ++ ++#ifdef HUNSPELL_EXPERIMENTAL ++// suggest stems, XXX experimental code ++int SuggestMgr::suggest_stems(char*** slst, const char * w, int nsug) ++{ ++ char buf[MAXSWUTF8L]; ++ char ** wlst; ++ int prevnsug = nsug; ++ ++ char w2[MAXWORDUTF8LEN]; ++ const char * word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ strcpy(w2, w); ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ word = w2; ++ } ++ ++ if (*slst) { ++ wlst = *slst; ++ } else { ++ wlst = (char **) calloc(maxSug, sizeof(char *)); ++ if (wlst == NULL) return -1; ++ } ++ // perhaps there are a fix stem in the dictionary ++ if ((nsug < maxSug) && (nsug > -1)) { ++ ++ nsug = fixstems(wlst, word, nsug); ++ if (nsug == prevnsug) { ++ char * s = mystrdup(word); ++ char * p = s + strlen(s); ++ while ((*p != '-') && (p != s)) p--; ++ if (*p == '-') { ++ *p = '\0'; ++ nsug = fixstems(wlst, s, nsug); ++ if ((nsug == prevnsug) && (nsug < maxSug) && (nsug >= 0)) { ++ char * t; ++ buf[0] = '\0'; ++ for (t = s; (t[0] != '\0') && ((t[0] >= '0') || (t[0] <= '9')); t++); // is a number? ++ if (*t != '\0') strcpy(buf, "# "); ++ strcat(buf, s); ++ wlst[nsug] = mystrdup(buf); ++ if (wlst[nsug] == NULL) return -1; ++ nsug++; ++ } ++ p++; ++ nsug = fixstems(wlst, p, nsug); ++ } ++ ++ free(s); ++ } ++ } ++ ++ if (nsug < 0) { ++ for (int i=0;ilookup(word); ++ if (rv) { ++ dicstem = 0; ++ } else { ++ // try stripping off affixes ++ rv = pAMgr->affix_check(word, wl); ++ ++ // else try check compound word ++ if (!rv && pAMgr->get_compound()) { ++ rv = pAMgr->compound_check(word, wl, ++ 0, 0, 100, 0, NULL, 0, &cmpdstemnum, cmpdstem,1); ++ ++ if (rv) { ++ dicstem = 2; ++ for (int j = 0; j < cmpdstemnum; j++) { ++ cpdindex += cmpdstem[j]; ++ } ++ if(! (pAMgr->lookup(word + cpdindex))) ++ pAMgr->affix_check(word + cpdindex, wl - cpdindex); // for prefix ++ } ++ } ++ ++ ++ if (pAMgr->get_prefix()) { ++ strcpy(prefix, pAMgr->get_prefix()); ++ } ++ ++ // XXX obsolete, will be a general solution for stemming ++ if ((prefix) && (strncmp(prefix, "leg", 3)==0)) prefix[0] = '\0'; // (HU) ++ } ++ ++ } ++ ++ ++ ++ if ((rv) && (ns < maxSug)) { ++ ++ // check fixstem flag and not_valid_stem flag ++ // first word ++ if ((ns < maxSug) && (dicstem < 2)) { ++ strcpy(buf, prefix); ++ if ((dicstem > 0) && pAMgr->get_derived()) { ++ // XXX obsolote ++ if (strlen(prefix) == 1) { ++ strcat(buf, (pAMgr->get_derived()) + 1); ++ } else { ++ strcat(buf, pAMgr->get_derived()); ++ } ++ } else { ++ // special stem in affix description ++ const char * wordchars = pAMgr->get_wordchars(); ++ if (rv->description && ++ (strchr(wordchars, *(rv->description)))) { ++ char * desc = (rv->description) + 1; ++ while (strchr(wordchars, *desc)) desc++; ++ strncat(buf, rv->description, desc - (rv->description)); ++ } else { ++ strcat(buf, rv->word); ++ } ++ } ++ wlst[ns] = mystrdup(buf); ++ if (wlst[ns] == NULL) return -1; ++ ns++; ++ } ++ ++ if (dicstem == 2) { ++ ++ // compound stem ++ ++// if (rv->astr && (strchr(rv->astr, '0') == NULL)) { ++ if (rv->astr) { ++ strcpy(buf, word); ++ buf[cpdindex] = '\0'; ++ if (prefix) strcat(buf, prefix); ++ if (pAMgr->get_derived()) { ++ strcat(buf, pAMgr->get_derived()); ++ } else { ++ // special stem in affix description ++ const char * wordchars = pAMgr->get_wordchars(); ++ if (rv->description && ++ (strchr(wordchars, *(rv->description)))) { ++ char * desc = (rv->description) + 1; ++ while (strchr(wordchars, *desc)) desc++; ++ strncat(buf, rv->description, desc - (rv->description)); ++ } else { ++ strcat(buf, rv->word); ++ } ++ } ++ if (ns < maxSug) { ++ wlst[ns] = mystrdup(buf); ++ if (wlst[ns] == NULL) return -1; ++ ns++; ++ } ++ } ++ } ++ } ++ return ns; ++} ++ ++// suggest possible stems ++int SuggestMgr::suggest_pos_stems(char*** slst, const char * w, int nsug) ++{ ++ char ** wlst; ++ ++ struct hentry * rv = NULL; ++ ++ char w2[MAXSWUTF8L]; ++ const char * word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ strcpy(w2, w); ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ word = w2; ++ } ++ ++ int wl = strlen(word); ++ ++ ++ if (*slst) { ++ wlst = *slst; ++ } else { ++ wlst = (char **) calloc(maxSug, sizeof(char *)); ++ if (wlst == NULL) return -1; ++ } ++ ++ rv = pAMgr->suffix_check(word, wl, 0, NULL, wlst, maxSug, &nsug); ++ ++ // delete dash from end of word ++ if (nsug > 0) { ++ for (int j=0; j < nsug; j++) { ++ if (wlst[j][strlen(wlst[j]) - 1] == '-') wlst[j][strlen(wlst[j]) - 1] = '\0'; ++ } ++ } ++ ++ *slst = wlst; ++ return nsug; ++} ++ ++ ++char * SuggestMgr::suggest_morph(const char * w) ++{ ++ char result[MAXLNLEN]; ++ char * r = (char *) result; ++ char * st; ++ ++ struct hentry * rv = NULL; ++ ++ *result = '\0'; ++ ++ if (! pAMgr) return NULL; ++ ++ char w2[MAXSWUTF8L]; ++ const char * word = w; ++ ++ // word reversing wrapper for complex prefixes ++ if (complexprefixes) { ++ strcpy(w2, w); ++ if (utf8) reverseword_utf(w2); else reverseword(w2); ++ word = w2; ++ } ++ ++ rv = pAMgr->lookup(word); ++ ++ while (rv) { ++ if ((!rv->astr) || !(TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) || ++ TESTAFF(rv->astr, pAMgr->get_pseudoroot(), rv->alen) || ++ TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) { ++ if (rv->description && ((!rv->astr) || ++ !TESTAFF(rv->astr, pAMgr->get_lemma_present(), rv->alen))) ++ strcat(result, word); ++ if (rv->description) strcat(result, rv->description); ++ strcat(result, "\n"); ++ } ++ rv = rv->next_homonym; ++ } ++ ++ st = pAMgr->affix_check_morph(word,strlen(word)); ++ if (st) { ++ strcat(result, st); ++ free(st); ++ } ++ ++ if (pAMgr->get_compound() && (*result == '\0')) ++ pAMgr->compound_check_morph(word, strlen(word), ++ 0, 0, 100, 0,NULL, 0, &r, NULL); ++ ++ return (*result) ? mystrdup(line_uniq(delete_zeros(result))) : NULL; ++} ++ ++char * SuggestMgr::suggest_morph_for_spelling_error(const char * word) ++{ ++ char * p = NULL; ++ char ** wlst = (char **) calloc(maxSug, sizeof(char *)); ++ if (!**wlst) return NULL; ++ // we will use only the first suggestion ++ for (int i = 0; i < maxSug - 1; i++) wlst[i] = ""; ++ int ns = suggest(&wlst, word, maxSug - 1); ++ if (ns == maxSug) { ++ p = suggest_morph(wlst[maxSug - 1]); ++ free(wlst[maxSug - 1]); ++ } ++ if (wlst) free(wlst); ++ return p; ++} ++#endif // END OF HUNSPELL_EXPERIMENTAL CODE ++ ++ ++// generate an n-gram score comparing s1 and s2 ++int SuggestMgr::ngram(int n, char * s1, const char * s2, int opt) ++{ ++ int nscore = 0; ++ int ns; ++ int l1; ++ int l2; ++ ++ if (utf8) { ++ w_char su1[MAXSWL]; ++ w_char su2[MAXSWL]; ++ l1 = u8_u16(su1, MAXSWL, s1); ++ l2 = u8_u16(su2, MAXSWL, s2); ++ if ((l2 <= 0) || (l1 == -1)) return 0; ++ // lowering dictionary word ++ if (opt & NGRAM_LOWERING) mkallsmall_utf(su2, l2, langnum); ++ for (int j = 1; j <= n; j++) { ++ ns = 0; ++ for (int i = 0; i <= (l1-j); i++) { ++ for (int l = 0; l <= (l2-j); l++) { ++ int k; ++ for (k = 0; (k < j); k++) { ++ w_char * c1 = su1 + i + k; ++ w_char * c2 = su2 + l + k; ++ if ((c1->l != c2->l) || (c1->h != c2->h)) break; ++ } ++ if (k == j) { ++ ns++; ++ break; ++ } ++ } ++ } ++ nscore = nscore + ns; ++ if (ns < 2) break; ++ } ++ } else { ++ char t[MAXSWUTF8L]; ++ l1 = strlen(s1); ++ l2 = strlen(s2); ++ if (l2 == 0) return 0; ++ strcpy(t, s2); ++ if (opt & NGRAM_LOWERING) mkallsmall(t, csconv); ++ for (int j = 1; j <= n; j++) { ++ ns = 0; ++ for (int i = 0; i <= (l1-j); i++) { ++ char c = *(s1 + i + j); ++ *(s1 + i + j) = '\0'; ++ if (strstr(t,(s1+i))) ns++; ++ *(s1 + i + j ) = c; ++ } ++ nscore = nscore + ns; ++ if (ns < 2) break; ++ } ++ } ++ ++ ns = 0; ++ if (opt & NGRAM_LONGER_WORSE) ns = (l2-l1)-2; ++ if (opt & NGRAM_ANY_MISMATCH) ns = abs(l2-l1)-2; ++ ns = (nscore - ((ns > 0) ? ns : 0)); ++ return ns; ++} ++ ++// length of the left common substring of s1 and (decapitalised) s2 ++int SuggestMgr::leftcommonsubstring(char * s1, const char * s2) { ++ if (utf8) { ++ w_char su1[MAXSWL]; ++ w_char su2[MAXSWL]; ++ // decapitalize dictionary word ++ if (complexprefixes) { ++ int l1 = u8_u16(su1, MAXSWL, s1); ++ int l2 = u8_u16(su2, MAXSWL, s2); ++ if (*((short *)su1+l1-1) == *((short *)su2+l2-1)) return 1; ++ } else { ++ int i; ++ u8_u16(su1, 1, s1); ++ u8_u16(su2, 1, s2); ++ unsigned short idx = (su2->h << 8) + su2->l; ++ if (*((short *)su1) != *((short *)su2) && ++ (*((unsigned short *)su1) != unicodetolower(idx, langnum))) return 0; ++ int l1 = u8_u16(su1, MAXSWL, s1); ++ int l2 = u8_u16(su2, MAXSWL, s2); ++ for(i = 1; (i < l1) && (i < l2) && ++ (*((short *)(su1 + i)) == *((short *)(su2 + i))); i++); ++ return i; ++ } ++ } else { ++ if (complexprefixes) { ++ int l1 = strlen(s1); ++ int l2 = strlen(s2); ++ if (*(s2+l1-1) == *(s2+l2-1)) return 1; ++ } else { ++ char * olds = s1; ++ // decapitalise dictionary word ++ if ((*s1 != *s2) && (*s1 != csconv[((unsigned char)*s2)].clower)) return 0; ++ do { ++ s1++; s2++; ++ } while ((*s1 == *s2) && (*s1 != '\0')); ++ return s1 - olds; ++ } ++ } ++ return 0; ++} ++ ++int SuggestMgr::commoncharacterpositions(char * s1, const char * s2, int * is_swap) { ++ int num = 0; ++ int diff = 0; ++ int diffpos[2]; ++ *is_swap = 0; ++ if (utf8) { ++ w_char su1[MAXSWL]; ++ w_char su2[MAXSWL]; ++ int l1 = u8_u16(su1, MAXSWL, s1); ++ int l2 = u8_u16(su2, MAXSWL, s2); ++ // decapitalize dictionary word ++ if (complexprefixes) { ++ mkallsmall_utf(su2+l2-1, 1, langnum); ++ } else { ++ mkallsmall_utf(su2, 1, langnum); ++ } ++ for (int i = 0; (i < l1) && (i < l2); i++) { ++ if (((short *) su1)[i] == ((short *) su2)[i]) { ++ num++; ++ } else { ++ if (diff < 2) diffpos[diff] = i; ++ diff++; ++ } ++ } ++ if ((diff == 2) && (l1 == l2) && ++ (((short *) su1)[diffpos[0]] == ((short *) su2)[diffpos[1]]) && ++ (((short *) su1)[diffpos[1]] == ((short *) su2)[diffpos[0]])) *is_swap = 1; ++ } else { ++ int i; ++ char t[MAXSWUTF8L]; ++ strcpy(t, s2); ++ // decapitalize dictionary word ++ if (complexprefixes) { ++ int l2 = strlen(t); ++ *(t+l2-1) = csconv[((unsigned char)*(t+l2-1))].clower; ++ } else { ++ mkallsmall(t, csconv); ++ } ++ for (i = 0; (*(s1+i) != 0) && (*(t+i) != 0); i++) { ++ if (*(s1+i) == *(t+i)) { ++ num++; ++ } else { ++ if (diff < 2) diffpos[diff] = i; ++ diff++; ++ } ++ } ++ if ((diff == 2) && (*(s1+i) == 0) && (*(t+i) == 0) && ++ (*(s1+diffpos[0]) == *(t+diffpos[1])) && ++ (*(s1+diffpos[1]) == *(t+diffpos[0]))) *is_swap = 1; ++ } ++ return num; ++} ++ ++int SuggestMgr::mystrlen(const char * word) { ++ if (utf8) { ++ w_char w[MAXSWL]; ++ return u8_u16(w, MAXSWL, word); ++ } else return strlen(word); ++} ++ ++// sort in decreasing order of score ++void SuggestMgr::bubblesort(char** rword, char** rword2, int* rsc, int n ) ++{ ++ int m = 1; ++ while (m < n) { ++ int j = m; ++ while (j > 0) { ++ if (rsc[j-1] < rsc[j]) { ++ int sctmp = rsc[j-1]; ++ char * wdtmp = rword[j-1]; ++ rsc[j-1] = rsc[j]; ++ rword[j-1] = rword[j]; ++ rsc[j] = sctmp; ++ rword[j] = wdtmp; ++ if (rword2) { ++ wdtmp = rword2[j-1]; ++ rword2[j-1] = rword2[j]; ++ rword2[j] = wdtmp; ++ } ++ j--; ++ } else break; ++ } ++ m++; ++ } ++ return; ++} ++ ++// longest common subsequence ++void SuggestMgr::lcs(const char * s, const char * s2, int * l1, int * l2, char ** result) { ++ int n, m; ++ w_char su[MAXSWL]; ++ w_char su2[MAXSWL]; ++ char * b; ++ char * c; ++ int i; ++ int j; ++ if (utf8) { ++ m = u8_u16(su, MAXSWL, s); ++ n = u8_u16(su2, MAXSWL, s2); ++ } else { ++ m = strlen(s); ++ n = strlen(s2); ++ } ++ c = (char *) malloc((m + 1) * (n + 1)); ++ b = (char *) malloc((m + 1) * (n + 1)); ++ if (!c || !b) { ++ if (c) free(c); ++ if (b) free(b); ++ *result = NULL; ++ return; ++ } ++ for (i = 1; i <= m; i++) c[i*(n+1)] = 0; ++ for (j = 0; j <= n; j++) c[j] = 0; ++ for (i = 1; i <= m; i++) { ++ for (j = 1; j <= n; j++) { ++ if ((utf8) && (*((short *) su+i-1) == *((short *)su2+j-1)) ++ || (!utf8) && ((*(s+i-1)) == (*(s2+j-1)))) { ++ c[i*(n+1) + j] = c[(i-1)*(n+1) + j-1]+1; ++ b[i*(n+1) + j] = LCS_UPLEFT; ++ } else if (c[(i-1)*(n+1) + j] >= c[i*(n+1) + j-1]) { ++ c[i*(n+1) + j] = c[(i-1)*(n+1) + j]; ++ b[i*(n+1) + j] = LCS_UP; ++ } else { ++ c[i*(n+1) + j] = c[i*(n+1) + j-1]; ++ b[i*(n+1) + j] = LCS_LEFT; ++ } ++ } ++ } ++ *result = b; ++ free(c); ++ *l1 = m; ++ *l2 = n; ++} ++ ++int SuggestMgr::lcslen(const char * s, const char* s2) { ++ int m; ++ int n; ++ int i; ++ int j; ++ char * result; ++ int len = 0; ++ lcs(s, s2, &m, &n, &result); ++ if (!result) return 0; ++ i = m; ++ j = n; ++ while ((i != 0) && (j != 0)) { ++ if (result[i*(n+1) + j] == LCS_UPLEFT) { ++ len++; ++ i--; ++ j--; ++ } else if (result[i*(n+1) + j] == LCS_UP) { ++ i--; ++ } else j--; ++ } ++ free(result); ++ return len; ++} +Index: mozilla/extensions/spellcheck/hunspell/hunspell/suggestmgr.hxx +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/suggestmgr.hxx +@@ -0,0 +1,160 @@ ++/******* BEGIN LICENSE BLOCK ******* ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++ * and László Németh (Hunspell). Portions created by the Initial Developers ++ * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++ * ++ * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) ++ * David Einstein (deinst@world.std.com) ++ * László Németh (nemethl@gyorsposta.hu) ++ * Davide Prina ++ * Giuseppe Modugno ++ * Gianluca Turconi ++ * Simon Brouwer ++ * Noll Janos ++ * Biro Arpad ++ * Goldman Eleonora ++ * Sarlos Tamas ++ * Bencsath Boldizsar ++ * Halacsy Peter ++ * Dvornik Laszlo ++ * Gefferth Andras ++ * Nagy Viktor ++ * Varga Daniel ++ * Chris Halls ++ * Rene Engelhard ++ * Bram Moolenaar ++ * Dafydd Jones ++ * Harri Pitkanen ++ * Andras Timar ++ * Tor Lillqvist ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ ******* END LICENSE BLOCK *******/ ++ ++#ifndef _SUGGESTMGR_HXX_ ++#define _SUGGESTMGR_HXX_ ++ ++#define MAXSWL 100 ++#define MAXSWUTF8L (MAXSWL * 4) ++#define MAX_ROOTS 100 ++#define MAX_WORDS 100 ++#define MAX_GUESS 200 ++#define MAXNGRAMSUGS 4 ++#define MAXPHONSUGS 2 ++ ++// timelimit: max ~1/4 sec (process time on Linux) for a time consuming function ++#define TIMELIMIT (CLOCKS_PER_SEC >> 2) ++#define MINTIMER 100 ++#define MAXPLUSTIMER 100 ++ ++#define NGRAM_LONGER_WORSE (1 << 0) ++#define NGRAM_ANY_MISMATCH (1 << 1) ++#define NGRAM_LOWERING (1 << 2) ++ ++#include "atypes.hxx" ++#include "affixmgr.hxx" ++#include "hashmgr.hxx" ++#include "langnum.hxx" ++#include ++ ++enum { LCS_UP, LCS_LEFT, LCS_UPLEFT }; ++ ++class SuggestMgr ++{ ++ char * ckey; ++ int ckeyl; ++ w_char * ckey_utf; ++ ++ char * ctry; ++ int ctryl; ++ w_char * ctry_utf; ++ ++ AffixMgr* pAMgr; ++ int maxSug; ++ struct cs_info * csconv; ++ int utf8; ++ int langnum; ++ int nosplitsugs; ++ int maxngramsugs; ++ int complexprefixes; ++ ++ ++public: ++ SuggestMgr(const char * tryme, int maxn, AffixMgr *aptr); ++ ~SuggestMgr(); ++ ++ int suggest(char*** slst, const char * word, int nsug, int * onlycmpdsug); ++ int ngsuggest(char ** wlst, char * word, int ns, HashMgr* pHMgr); ++ int suggest_auto(char*** slst, const char * word, int nsug); ++ int suggest_stems(char*** slst, const char * word, int nsug); ++ int suggest_pos_stems(char*** slst, const char * word, int nsug); ++ ++ char * suggest_morph(const char * word); ++ char * suggest_morph_for_spelling_error(const char * word); ++ ++private: ++ int testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest, ++ int * timer, clock_t * timelimit); ++ int checkword(const char *, int, int, int *, clock_t *); ++ int check_forbidden(const char *, int); ++ ++ int capchars(char **, const char *, int, int); ++ int replchars(char**, const char *, int, int); ++ int doubletwochars(char**, const char *, int, int); ++ int forgotchar(char **, const char *, int, int); ++ int swapchar(char **, const char *, int, int); ++ int longswapchar(char **, const char *, int, int); ++ int movechar(char **, const char *, int, int); ++ int extrachar(char **, const char *, int, int); ++ int badcharkey(char **, const char *, int, int); ++ int badchar(char **, const char *, int, int); ++ int twowords(char **, const char *, int, int); ++ int fixstems(char **, const char *, int); ++ ++ int capchars_utf(char **, const w_char *, int wl, int, int); ++ int doubletwochars_utf(char**, const w_char *, int wl, int, int); ++ int forgotchar_utf(char**, const w_char *, int wl, int, int); ++ int extrachar_utf(char**, const w_char *, int wl, int, int); ++ int badcharkey_utf(char **, const w_char *, int wl, int, int); ++ int badchar_utf(char **, const w_char *, int wl, int, int); ++ int swapchar_utf(char **, const w_char *, int wl, int, int); ++ int longswapchar_utf(char **, const w_char *, int, int, int); ++ int movechar_utf(char **, const w_char *, int, int, int); ++ ++ int mapchars(char**, const char *, int, int); ++ int map_related(const char *, int, char ** wlst, int, int, const mapentry*, int, int *, clock_t *); ++ int map_related_utf(w_char *, int, int, int, char ** wlst, int, const mapentry*, int, int *, clock_t *); ++ int ngram(int n, char * s1, const char * s2, int opt); ++ int mystrlen(const char * word); ++ int leftcommonsubstring(char * s1, const char * s2); ++ int commoncharacterpositions(char * s1, const char * s2, int * is_swap); ++ void bubblesort( char ** rwd, char ** rwd2, int * rsc, int n); ++ void lcs(const char * s, const char * s2, int * l1, int * l2, char ** result); ++ int lcslen(const char * s, const char* s2); ++ ++}; ++ ++#endif +Index: mozilla/extensions/spellcheck/hunspell/src/Makefile.in +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/Makefile.in ++++ mozilla/extensions/spellcheck/hunspell/src/Makefile.in +@@ -51,36 +51,27 @@ + unicharutil \ + spellchecker \ + xulapp \ + $(NULL) + + CPPSRCS = mozHunspell.cpp \ + $(NULL) + +-ifndef MOZ_NATIVE_HUNSPELL +-CPPSRCS += affentry.cpp \ +- affixmgr.cpp \ +- csutil.cpp \ +- hashmgr.cpp \ +- hunspell.cpp \ +- phonet.cpp \ +- suggestmgr.cpp \ +- $(NULL) +-endif +- + ifdef MOZ_XUL_APP + CPPSRCS += mozHunspellDirProvider.cpp + endif + + EXTRA_DSO_LDOPTS = \ + $(LIBS_DIR) \ + $(XPCOM_LIBS) \ + $(NSPR_LIBS) \ + $(MOZ_UNICHARUTIL_LIBS) \ + $(MOZ_HUNSPELL_LIBS) \ + $(NULL) + + include $(topsrcdir)/config/rules.mk + + ifdef MOZ_NATIVE_HUNSPELL + CXXFLAGS += $(MOZ_HUNSPELL_CFLAGS) ++else ++CXXFLAGS += -I$(srcdir)/../hunspell + endif +Index: mozilla/extensions/spellcheck/hunspell/src/README.hunspell +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/README.hunspell ++++ /dev/null +@@ -1,59 +0,0 @@ +-******* BEGIN LICENSE BLOCK ******* +-* Version: MPL 1.1/GPL 2.0/LGPL 2.1 +-* +-* The contents of this file are subject to the Mozilla Public License Version +-* 1.1 (the "License"); you may not use this file except in compliance with +-* the License. You may obtain a copy of the License at +-* http://www.mozilla.org/MPL/ +-* +-* Software distributed under the License is distributed on an "AS IS" basis, +-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +-* for the specific language governing rights and limitations under the +-* License. +-* +-* The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +-* and László Németh (Hunspell). Portions created by the Initial Developers +-* are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +-* +-* Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +-* David Einstein (deinst@world.std.com) +-* László Németh (nemethl@gyorsposta.hu) +-* Ryan VanderMeulen (ryanvm@gmail.com) +-* +-* Alternatively, the contents of this file may be used under the terms of +-* either the GNU General Public License Version 2 or later (the "GPL"), or +-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +-* in which case the provisions of the GPL or the LGPL are applicable instead +-* of those above. If you wish to allow use of your version of this file only +-* under the terms of either the GPL or the LGPL, and not to allow others to +-* use your version of this file under the terms of the MPL, indicate your +-* decision by deleting the provisions above and replace them with the notice +-* and other provisions required by the GPL or the LGPL. If you do not delete +-* the provisions above, a recipient may use your version of this file under +-* the terms of any one of the MPL, the GPL or the LGPL. +-* +-******* END LICENSE BLOCK ******* +- +-Hunspell Version: 1.1.12 +- +-Hunspell Author: László Németh +-MySpell Author: Kevin Hendricks & David Einstein +- +-Hunspell is a spell checker and morphological analyser library. Hunspell +-is based on OpenOffice.org's Myspell. Documentation, tests, and examples +-are available at http://hunspell.sourceforge.net. +- +-A special thanks and credit goes to Geoff Kuenning, the creator of Ispell. +-MySpell's affix algorithms were based on those of Ispell, which should be +-noted is copyright Geoff Kuenning et al and now available under a BSD-style +-license. For more information on Ispell and affix compression in general, +-please see: http://lasr.cs.ucla.edu/geoff/ispell.html (Ispell homepage) +- +-An almost complete rewrite of MySpell for use by the Mozilla project was +-developed by David Einstein. David was a significant help in improving MySpell. +- +-Special thanks also goes to László Németh, who is the author of the Hungarian +-dictionary and who developed and contributed the code to support compound words +-in MySpell and fixed numerous problems with the encoding case conversion tables +-along with rewriting MySpell as Hunspell and ensuring compatibility with the +-Mozilla codebase. +Index: mozilla/extensions/spellcheck/hunspell/src/affentry.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/affentry.cpp ++++ /dev/null +@@ -1,924 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "affentry.hxx" +-#include "csutil.hxx" +- +-#ifndef MOZILLA_CLIENT +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +- +-PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp) +-{ +- // register affix manager +- pmyMgr = pmgr; +- +- // set up its intial values +- +- aflag = dp->aflag; // flag +- strip = dp->strip; // string to strip +- appnd = dp->appnd; // string to append +- stripl = dp->stripl; // length of strip string +- appndl = dp->appndl; // length of append string +- numconds = dp->numconds; // number of conditions to match +- opts = dp->opts; // cross product flag +- // then copy over all of the conditions +- memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0])); +- next = NULL; +- nextne = NULL; +- nexteq = NULL; +-#ifdef HUNSPELL_EXPERIMENTAL +- morphcode = dp->morphcode; +-#endif +- contclass = dp->contclass; +- contclasslen = dp->contclasslen; +-} +- +- +-PfxEntry::~PfxEntry() +-{ +- aflag = 0; +- if (appnd) free(appnd); +- if (strip) free(strip); +- pmyMgr = NULL; +- appnd = NULL; +- strip = NULL; +- if (opts & aeUTF8) { +- for (int i = 0; i < numconds; i++) { +- if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]); +- } +- } +-#ifdef HUNSPELL_EXPERIMENTAL +- if (morphcode && !(opts & aeALIASM)) free(morphcode); +-#endif +- if (contclass && !(opts & aeALIASF)) free(contclass); +-} +- +-// add prefix to this word assuming conditions hold +-char * PfxEntry::add(const char * word, int len) +-{ +- char tword[MAXWORDUTF8LEN + 4]; +- +- if ((len > stripl) && (len >= numconds) && test_condition(word) && +- (!stripl || (strncmp(word, strip, stripl) == 0)) && +- ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) { +- /* we have a match so add prefix */ +- char * pp = tword; +- if (appndl) { +- strcpy(tword,appnd); +- pp += appndl; +- } +- strcpy(pp, (word + stripl)); +- return mystrdup(tword); +- } +- return NULL; +-} +- +- +-inline int PfxEntry::test_condition(const char * st) +-{ +- int cond; +- unsigned char * cp = (unsigned char *)st; +- if (!(opts & aeUTF8)) { // 256-character codepage +- for (cond = 0; cond < numconds; cond++) { +- if ((conds.base[*cp++] & (1 << cond)) == 0) return 0; +- } +- } else { // UTF-8 encoding +- unsigned short wc; +- for (cond = 0; cond < numconds; cond++) { +- // a simple 7-bit ASCII character in UTF-8 +- if ((*cp >> 7) == 0) { +- // also check limit (end of word) +- if ((!*cp) || ((conds.utf8.ascii[*cp++] & (1 << cond)) == 0)) return 0; +- // UTF-8 multibyte character +- } else { +- // not dot wildcard in rule +- if (!conds.utf8.all[cond]) { +- if (conds.utf8.neg[cond]) { +- u8_u16((w_char *) &wc, 1, (char *) cp); +- if (conds.utf8.wchars[cond] && +- flag_bsearch((unsigned short *)conds.utf8.wchars[cond], +- wc, (short) conds.utf8.wlen[cond])) return 0; +- } else { +- if (!conds.utf8.wchars[cond]) return 0; +- u8_u16((w_char *) &wc, 1, (char *) cp); +- if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond], +- wc, (short)conds.utf8.wlen[cond])) return 0; +- } +- } +- // jump to next UTF-8 character +- for(cp++; (*cp & 0xc0) == 0x80; cp++); +- } +- } +- } +- return 1; +-} +- +- +-// check if this prefix entry matches +-struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- struct hentry * he; // hash entry of root word or NULL +- char tmpword[MAXWORDUTF8LEN + 4]; +- +- // on entry prefix is 0 length or already matches the beginning of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing prefix and adding +- // back any characters that would have been stripped +- +- if (stripl) strcpy (tmpword, strip); +- strcpy ((tmpword + stripl), (word + appndl)); +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then check if resulting +- // root word in the dictionary +- +- if (test_condition(tmpword)) { +- tmpl += stripl; +- if ((he = pmyMgr->lookup(tmpword)) != NULL) { +- do { +- if (TESTAFF(he->astr, aflag, he->alen) && +- // forbid single prefixes with pseudoroot flag +- ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) && +- // needflag +- ((!needflag) || TESTAFF(he->astr, needflag, he->alen) || +- (contclass && TESTAFF(contclass, needflag, contclasslen)))) +- return he; +- he = he->next_homonym; // check homonyms +- } while (he); +- } +- +- // prefix matched but no root word was found +- // if aeXPRODUCT is allowed, try again but now +- // ross checked combined with a suffix +- +- //if ((opts & aeXPRODUCT) && in_compound) { +- if ((opts & aeXPRODUCT)) { +- he = pmyMgr->suffix_check(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, NULL, +- 0, NULL, FLAG_NULL, needflag, in_compound); +- if (he) return he; +- } +- } +- } +- return NULL; +-} +- +-// check if this prefix entry matches +-struct hentry * PfxEntry::check_twosfx(const char * word, int len, +- char in_compound, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- struct hentry * he; // hash entry of root word or NULL +- char tmpword[MAXWORDUTF8LEN + 4]; +- +- // on entry prefix is 0 length or already matches the beginning of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing prefix and adding +- // back any characters that would have been stripped +- +- if (stripl) strcpy (tmpword, strip); +- strcpy ((tmpword + stripl), (word + appndl)); +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then check if resulting +- // root word in the dictionary +- +- if (test_condition(tmpword)) { +- tmpl += stripl; +- +- // prefix matched but no root word was found +- // if aeXPRODUCT is allowed, try again but now +- // cross checked combined with a suffix +- +- if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { +- he = pmyMgr->suffix_check_twosfx(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, needflag); +- if (he) return he; +- } +- } +- } +- return NULL; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// check if this prefix entry matches +-char * PfxEntry::check_twosfx_morph(const char * word, int len, +- char in_compound, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- char tmpword[MAXWORDUTF8LEN + 4]; +- +- // on entry prefix is 0 length or already matches the beginning of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing prefix and adding +- // back any characters that would have been stripped +- +- if (stripl) strcpy (tmpword, strip); +- strcpy ((tmpword + stripl), (word + appndl)); +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then check if resulting +- // root word in the dictionary +- +- if (test_condition(tmpword)) { +- tmpl += stripl; +- +- // prefix matched but no root word was found +- // if aeXPRODUCT is allowed, try again but now +- // ross checked combined with a suffix +- +- if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { +- return pmyMgr->suffix_check_twosfx_morph(tmpword, tmpl, +- aeXPRODUCT, (AffEntry *)this, needflag); +- } +- } +- } +- return NULL; +-} +- +-// check if this prefix entry matches +-char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- struct hentry * he; // hash entry of root word or NULL +- char tmpword[MAXWORDUTF8LEN + 4]; +- char result[MAXLNLEN]; +- char * st; +- +- *result = '\0'; +- +- // on entry prefix is 0 length or already matches the beginning of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing prefix and adding +- // back any characters that would have been stripped +- +- if (stripl) strcpy (tmpword, strip); +- strcpy ((tmpword + stripl), (word + appndl)); +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then check if resulting +- // root word in the dictionary +- +- if (test_condition(tmpword)) { +- tmpl += stripl; +- if ((he = pmyMgr->lookup(tmpword)) != NULL) { +- do { +- if (TESTAFF(he->astr, aflag, he->alen) && +- // forbid single prefixes with pseudoroot flag +- ! TESTAFF(contclass, pmyMgr->get_pseudoroot(), contclasslen) && +- // needflag +- ((!needflag) || TESTAFF(he->astr, needflag, he->alen) || +- (contclass && TESTAFF(contclass, needflag, contclasslen)))) { +- if (morphcode) strcat(result, morphcode); else strcat(result,getKey()); +- if (he->description) { +- if ((*(he->description)=='[')||(*(he->description)=='<')) strcat(result,he->word); +- strcat(result,he->description); +- } +- strcat(result, "\n"); +- } +- he = he->next_homonym; +- } while (he); +- } +- +- // prefix matched but no root word was found +- // if aeXPRODUCT is allowed, try again but now +- // ross checked combined with a suffix +- +- if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) { +- st = pmyMgr->suffix_check_morph(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, +- FLAG_NULL, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- } +- } +- } +- } +- +- if (*result) return mystrdup(result); +- return NULL; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +-SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp) +-{ +- // register affix manager +- pmyMgr = pmgr; +- +- // set up its intial values +- aflag = dp->aflag; // char flag +- strip = dp->strip; // string to strip +- appnd = dp->appnd; // string to append +- stripl = dp->stripl; // length of strip string +- appndl = dp->appndl; // length of append string +- numconds = dp->numconds; // number of conditions to match +- opts = dp->opts; // cross product flag +- +- // then copy over all of the conditions +- memcpy(&conds.base[0],&dp->conds.base[0],SETSIZE*sizeof(conds.base[0])); +- +- rappnd = myrevstrdup(appnd); +- +-#ifdef HUNSPELL_EXPERIMENTAL +- morphcode = dp->morphcode; +-#endif +- contclass = dp->contclass; +- contclasslen = dp->contclasslen; +-} +- +- +-SfxEntry::~SfxEntry() +-{ +- aflag = 0; +- if (appnd) free(appnd); +- if (rappnd) free(rappnd); +- if (strip) free(strip); +- pmyMgr = NULL; +- appnd = NULL; +- strip = NULL; +- if (opts & aeUTF8) { +- for (int i = 0; i < numconds; i++) { +- if (conds.utf8.wchars[i]) free(conds.utf8.wchars[i]); +- } +- } +-#ifdef HUNSPELL_EXPERIMENTAL +- if (morphcode && !(opts & aeALIASM)) free(morphcode); +-#endif +- if (contclass && !(opts & aeALIASF)) free(contclass); +-} +- +-// add suffix to this word assuming conditions hold +-char * SfxEntry::add(const char * word, int len) +-{ +- char tword[MAXWORDUTF8LEN + 4]; +- +- /* make sure all conditions match */ +- if ((len > stripl) && (len >= numconds) && test_condition(word + len, word) && +- (!stripl || (strcmp(word + len - stripl, strip) == 0)) && +- ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) { +- /* we have a match so add suffix */ +- strcpy(tword,word); +- if (appndl) { +- strcpy(tword + len - stripl, appnd); +- } else { +- *(tword + len - stripl) = '\0'; +- } +- return mystrdup(tword); +- } +- return NULL; +-} +- +- +-inline int SfxEntry::test_condition(const char * st, const char * beg) +-{ +- int cond; +- unsigned char * cp = (unsigned char *) st; +- if (!(opts & aeUTF8)) { // 256-character codepage +- // Domolki affix algorithm +- for (cond = numconds; --cond >= 0; ) { +- if ((conds.base[*--cp] & (1 << cond)) == 0) return 0; +- } +- } else { // UTF-8 encoding +- unsigned short wc; +- for (cond = numconds; --cond >= 0; ) { +- // go to next character position and check limit +- if ((char *) --cp < beg) return 0; +- // a simple 7-bit ASCII character in UTF-8 +- if ((*cp >> 7) == 0) { +- if ((conds.utf8.ascii[*cp] & (1 << cond)) == 0) return 0; +- // UTF-8 multibyte character +- } else { +- // go to first character of UTF-8 multibyte character +- for (; (*cp & 0xc0) == 0x80; cp--); +- // not dot wildcard in rule +- if (!conds.utf8.all[cond]) { +- if (conds.utf8.neg[cond]) { +- u8_u16((w_char *) &wc, 1, (char *) cp); +- if (conds.utf8.wchars[cond] && +- flag_bsearch((unsigned short *)conds.utf8.wchars[cond], +- wc, (short) conds.utf8.wlen[cond])) return 0; +- } else { +- if (!conds.utf8.wchars[cond]) return 0; +- u8_u16((w_char *) &wc, 1, (char *) cp); +- if (!flag_bsearch((unsigned short *)conds.utf8.wchars[cond], +- wc, (short)conds.utf8.wlen[cond])) return 0; +- } +- } +- } +- } +- } +- return 1; +-} +- +- +- +-// see if this suffix is present in the word +-struct hentry * SfxEntry::checkword(const char * word, int len, int optflags, +- AffEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag, +- const FLAG badflag) +-{ +- int tmpl; // length of tmpword +- struct hentry * he; // hash entry pointer +- unsigned char * cp; +- char tmpword[MAXWORDUTF8LEN + 4]; +- PfxEntry* ep = (PfxEntry *) ppfx; +- +- // if this suffix is being cross checked with a prefix +- // but it does not support cross products skip it +- +- if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0)) +- return NULL; +- +- // upon entry suffix is 0 length or already matches the end of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- // the second condition is not enough for UTF-8 strings +- // it checked in test_condition() +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing suffix and adding +- // back any characters that would have been stripped or +- // or null terminating the shorter string +- +- strcpy (tmpword, word); +- cp = (unsigned char *)(tmpword + tmpl); +- if (stripl) { +- strcpy ((char *)cp, strip); +- tmpl += stripl; +- cp = (unsigned char *)(tmpword + tmpl); +- } else *cp = '\0'; +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being // tested +- +- // if all conditions are met then check if resulting +- // root word in the dictionary +- +- if (test_condition((char *) cp, (char *) tmpword)) { +- +-#ifdef SZOSZABLYA_POSSIBLE_ROOTS +- fprintf(stdout,"%s %s %c\n", word, tmpword, aflag); +-#endif +- if ((he = pmyMgr->lookup(tmpword)) != NULL) { +- do { +- // check conditional suffix (enabled by prefix) +- if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && +- TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && +- (((optflags & aeXPRODUCT) == 0) || +- TESTAFF(he->astr, ep->getFlag(), he->alen) || +- // enabled by prefix +- ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) +- ) && +- // handle cont. class +- ((!cclass) || +- ((contclass) && TESTAFF(contclass, cclass, contclasslen)) +- ) && +- // check only in compound homonyms (bad flags) +- (!badflag || !TESTAFF(he->astr, badflag, he->alen) +- ) && +- // handle required flag +- ((!needflag) || +- (TESTAFF(he->astr, needflag, he->alen) || +- ((contclass) && TESTAFF(contclass, needflag, contclasslen))) +- ) +- ) return he; +- he = he->next_homonym; // check homonyms +- } while (he); +- +- // obsolote stemming code (used only by the +- // experimental SuffixMgr:suggest_pos_stems) +- // store resulting root in wlst +- } else if (wlst && (*ns < maxSug)) { +- int cwrd = 1; +- for (int k=0; k < *ns; k++) +- if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0; +- if (cwrd) { +- wlst[*ns] = mystrdup(tmpword); +- if (wlst[*ns] == NULL) { +- for (int j=0; j<*ns; j++) free(wlst[j]); +- *ns = -1; +- return NULL; +- } +- (*ns)++; +- } +- } +- } +- } +- return NULL; +-} +- +-// see if two-level suffix is present in the word +-struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags, +- AffEntry* ppfx, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- struct hentry * he; // hash entry pointer +- unsigned char * cp; +- char tmpword[MAXWORDUTF8LEN + 4]; +- PfxEntry* ep = (PfxEntry *) ppfx; +- +- +- // if this suffix is being cross checked with a prefix +- // but it does not support cross products skip it +- +- if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0) +- return NULL; +- +- // upon entry suffix is 0 length or already matches the end of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing suffix and adding +- // back any characters that would have been stripped or +- // or null terminating the shorter string +- +- strcpy (tmpword, word); +- cp = (unsigned char *)(tmpword + tmpl); +- if (stripl) { +- strcpy ((char *)cp, strip); +- tmpl += stripl; +- cp = (unsigned char *)(tmpword + tmpl); +- } else *cp = '\0'; +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then recall suffix_check +- +- if (test_condition((char *) cp, (char *) tmpword)) { +- if (ppfx) { +- // handle conditional suffix +- if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) +- he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag); +- else +- he = pmyMgr->suffix_check(tmpword, tmpl, optflags, ppfx, NULL, 0, NULL, (FLAG) aflag, needflag); +- } else { +- he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag); +- } +- if (he) return he; +- } +- } +- return NULL; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// see if two-level suffix is present in the word +-char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags, +- AffEntry* ppfx, const FLAG needflag) +-{ +- int tmpl; // length of tmpword +- unsigned char * cp; +- char tmpword[MAXWORDUTF8LEN + 4]; +- PfxEntry* ep = (PfxEntry *) ppfx; +- char * st; +- +- char result[MAXLNLEN]; +- +- *result = '\0'; +- +- // if this suffix is being cross checked with a prefix +- // but it does not support cross products skip it +- +- if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0) +- return NULL; +- +- // upon entry suffix is 0 length or already matches the end of the word. +- // So if the remaining root word has positive length +- // and if there are enough chars in root word and added back strip chars +- // to meet the number of characters conditions, then test it +- +- tmpl = len - appndl; +- +- if ((tmpl > 0) && (tmpl + stripl >= numconds)) { +- +- // generate new root word by removing suffix and adding +- // back any characters that would have been stripped or +- // or null terminating the shorter string +- +- strcpy (tmpword, word); +- cp = (unsigned char *)(tmpword + tmpl); +- if (stripl) { +- strcpy ((char *)cp, strip); +- tmpl += stripl; +- cp = (unsigned char *)(tmpword + tmpl); +- } else *cp = '\0'; +- +- // now make sure all of the conditions on characters +- // are met. Please see the appendix at the end of +- // this file for more info on exactly what is being +- // tested +- +- // if all conditions are met then recall suffix_check +- +- if (test_condition((char *) cp, (char *) tmpword)) { +- if (ppfx) { +- // handle conditional suffix +- if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) { +- st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag); +- if (st) { +- if (((PfxEntry *) ppfx)->getMorph()) { +- strcat(result, ((PfxEntry *) ppfx)->getMorph()); +- } +- strcat(result,st); +- free(st); +- mychomp(result); +- } +- } else { +- st = pmyMgr->suffix_check_morph(tmpword, tmpl, optflags, ppfx, aflag, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- mychomp(result); +- } +- } +- } else { +- st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- mychomp(result); +- } +- } +- if (*result) return mystrdup(result); +- } +- } +- return NULL; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +-// get next homonym with same affix +-struct hentry * SfxEntry::get_next_homonym(struct hentry * he, int optflags, AffEntry* ppfx, +- const FLAG cclass, const FLAG needflag) +-{ +- PfxEntry* ep = (PfxEntry *) ppfx; +- FLAG eFlag = ep ? ep->getFlag() : FLAG_NULL; +- +- while (he->next_homonym) { +- he = he->next_homonym; +- if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && +- ((optflags & aeXPRODUCT) == 0 || +- TESTAFF(he->astr, eFlag, he->alen) || +- // handle conditional suffix +- ((contclass) && TESTAFF(contclass, eFlag, contclasslen)) +- ) && +- // handle cont. class +- ((!cclass) || +- ((contclass) && TESTAFF(contclass, cclass, contclasslen)) +- ) && +- // handle required flag +- ((!needflag) || +- (TESTAFF(he->astr, needflag, he->alen) || +- ((contclass) && TESTAFF(contclass, needflag, contclasslen))) +- ) +- ) return he; +- } +- return NULL; +-} +- +- +-#if 0 +- +-Appendix: Understanding Affix Code +- +- +-An affix is either a prefix or a suffix attached to root words to make +-other words. +- +-Basically a Prefix or a Suffix is set of AffEntry objects +-which store information about the prefix or suffix along +-with supporting routines to check if a word has a particular +-prefix or suffix or a combination. +- +-The structure affentry is defined as follows: +- +-struct affentry +-{ +- unsigned short aflag; // ID used to represent the affix +- char * strip; // string to strip before adding affix +- char * appnd; // the affix string to add +- unsigned char stripl; // length of the strip string +- unsigned char appndl; // length of the affix string +- char numconds; // the number of conditions that must be met +- char opts; // flag: aeXPRODUCT- combine both prefix and suffix +- char conds[SETSIZE]; // array which encodes the conditions to be met +-}; +- +- +-Here is a suffix borrowed from the en_US.aff file. This file +-is whitespace delimited. +- +-SFX D Y 4 +-SFX D 0 e d +-SFX D y ied [^aeiou]y +-SFX D 0 ed [^ey] +-SFX D 0 ed [aeiou]y +- +-This information can be interpreted as follows: +- +-In the first line has 4 fields +- +-Field +------ +-1 SFX - indicates this is a suffix +-2 D - is the name of the character flag which represents this suffix +-3 Y - indicates it can be combined with prefixes (cross product) +-4 4 - indicates that sequence of 4 affentry structures are needed to +- properly store the affix information +- +-The remaining lines describe the unique information for the 4 SfxEntry +-objects that make up this affix. Each line can be interpreted +-as follows: (note fields 1 and 2 are as a check against line 1 info) +- +-Field +------ +-1 SFX - indicates this is a suffix +-2 D - is the name of the character flag for this affix +-3 y - the string of chars to strip off before adding affix +- (a 0 here indicates the NULL string) +-4 ied - the string of affix characters to add +-5 [^aeiou]y - the conditions which must be met before the affix +- can be applied +- +-Field 5 is interesting. Since this is a suffix, field 5 tells us that +-there are 2 conditions that must be met. The first condition is that +-the next to the last character in the word must *NOT* be any of the +-following "a", "e", "i", "o" or "u". The second condition is that +-the last character of the word must end in "y". +- +-So how can we encode this information concisely and be able to +-test for both conditions in a fast manner? The answer is found +-but studying the wonderful ispell code of Geoff Kuenning, et.al. +-(now available under a normal BSD license). +- +-If we set up a conds array of 256 bytes indexed (0 to 255) and access it +-using a character (cast to an unsigned char) of a string, we have 8 bits +-of information we can store about that character. Specifically we +-could use each bit to say if that character is allowed in any of the +-last (or first for prefixes) 8 characters of the word. +- +-Basically, each character at one end of the word (up to the number +-of conditions) is used to index into the conds array and the resulting +-value found there says whether the that character is valid for a +-specific character position in the word. +- +-For prefixes, it does this by setting bit 0 if that char is valid +-in the first position, bit 1 if valid in the second position, and so on. +- +-If a bit is not set, then that char is not valid for that postion in the +-word. +- +-If working with suffixes bit 0 is used for the character closest +-to the front, bit 1 for the next character towards the end, ..., +-with bit numconds-1 representing the last char at the end of the string. +- +-Note: since entries in the conds[] are 8 bits, only 8 conditions +-(read that only 8 character positions) can be examined at one +-end of a word (the beginning for prefixes and the end for suffixes. +- +-So to make this clearer, lets encode the conds array values for the +-first two affentries for the suffix D described earlier. +- +- +- For the first affentry: +- numconds = 1 (only examine the last character) +- +- conds['e'] = (1 << 0) (the word must end in an E) +- all others are all 0 +- +- For the second affentry: +- numconds = 2 (only examine the last two characters) +- +- conds[X] = conds[X] | (1 << 0) (aeiou are not allowed) +- where X is all characters *but* a, e, i, o, or u +- +- +- conds['y'] = (1 << 1) (the last char must be a y) +- all other bits for all other entries in the conds array are zero +- +- +-#endif +- +Index: mozilla/extensions/spellcheck/hunspell/src/affentry.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/affentry.hxx ++++ /dev/null +@@ -1,187 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _AFFIX_HXX_ +-#define _AFFIX_HXX_ +- +-#include "atypes.hxx" +-#include "baseaffix.hxx" +-#include "affixmgr.hxx" +- +-/* A Prefix Entry */ +- +-class PfxEntry : public AffEntry +-{ +- AffixMgr* pmyMgr; +- +- PfxEntry * next; +- PfxEntry * nexteq; +- PfxEntry * nextne; +- PfxEntry * flgnxt; +- +-public: +- +- PfxEntry(AffixMgr* pmgr, affentry* dp ); +- ~PfxEntry(); +- +- inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); } +- struct hentry * checkword(const char * word, int len, char in_compound, +- const FLAG needflag = FLAG_NULL); +- +- struct hentry * check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL); +- +- char * check_morph(const char * word, int len, char in_compound, +- const FLAG needflag = FLAG_NULL); +- +- char * check_twosfx_morph(const char * word, int len, +- char in_compound, const FLAG needflag = FLAG_NULL); +- +- inline FLAG getFlag() { return aflag; } +- inline const char * getKey() { return appnd; } +- char * add(const char * word, int len); +- +- inline short getKeyLen() { return appndl; } +- +- inline const char * getMorph() { return morphcode; } +- +- inline const unsigned short * getCont() { return contclass; } +- inline short getContLen() { return contclasslen; } +- +- inline PfxEntry * getNext() { return next; } +- inline PfxEntry * getNextNE() { return nextne; } +- inline PfxEntry * getNextEQ() { return nexteq; } +- inline PfxEntry * getFlgNxt() { return flgnxt; } +- +- inline void setNext(PfxEntry * ptr) { next = ptr; } +- inline void setNextNE(PfxEntry * ptr) { nextne = ptr; } +- inline void setNextEQ(PfxEntry * ptr) { nexteq = ptr; } +- inline void setFlgNxt(PfxEntry * ptr) { flgnxt = ptr; } +- +- inline int test_condition(const char * st); +-}; +- +- +- +- +-/* A Suffix Entry */ +- +-class SfxEntry : public AffEntry +-{ +- AffixMgr* pmyMgr; +- char * rappnd; +- +- SfxEntry * next; +- SfxEntry * nexteq; +- SfxEntry * nextne; +- SfxEntry * flgnxt; +- +- SfxEntry * l_morph; +- SfxEntry * r_morph; +- SfxEntry * eq_morph; +- +-public: +- +- SfxEntry(AffixMgr* pmgr, affentry* dp ); +- ~SfxEntry(); +- +- inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); } +- struct hentry * checkword(const char * word, int len, int optflags, +- AffEntry* ppfx, char ** wlst, int maxSug, int * ns, +-// const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT); +- const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0); +- +- struct hentry * check_twosfx(const char * word, int len, int optflags, AffEntry* ppfx, const FLAG needflag = NULL); +- +- char * check_twosfx_morph(const char * word, int len, int optflags, +- AffEntry* ppfx, const FLAG needflag = FLAG_NULL); +- struct hentry * get_next_homonym(struct hentry * he); +- struct hentry * get_next_homonym(struct hentry * word, int optflags, AffEntry* ppfx, +- const FLAG cclass, const FLAG needflag); +- +- +- inline FLAG getFlag() { return aflag; } +- inline const char * getKey() { return rappnd; } +- char * add(const char * word, int len); +- +- +- inline const char * getMorph() { return morphcode; } +- +- inline const unsigned short * getCont() { return contclass; } +- inline short getContLen() { return contclasslen; } +- inline const char * getAffix() { return appnd; } +- +- inline short getKeyLen() { return appndl; } +- +- inline SfxEntry * getNext() { return next; } +- inline SfxEntry * getNextNE() { return nextne; } +- inline SfxEntry * getNextEQ() { return nexteq; } +- +- inline SfxEntry * getLM() { return l_morph; } +- inline SfxEntry * getRM() { return r_morph; } +- inline SfxEntry * getEQM() { return eq_morph; } +- inline SfxEntry * getFlgNxt() { return flgnxt; } +- +- inline void setNext(SfxEntry * ptr) { next = ptr; } +- inline void setNextNE(SfxEntry * ptr) { nextne = ptr; } +- inline void setNextEQ(SfxEntry * ptr) { nexteq = ptr; } +- inline void setFlgNxt(SfxEntry * ptr) { flgnxt = ptr; } +- +- inline int test_condition(const char * st, const char * begin); +-}; +- +-#endif +- +- +Index: mozilla/extensions/spellcheck/hunspell/src/affixmgr.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/affixmgr.cpp ++++ /dev/null +@@ -1,4155 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "affixmgr.hxx" +-#include "affentry.hxx" +-#include "langnum.hxx" +- +-#include "csutil.hxx" +- +-#ifndef MOZILLA_CLIENT +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +-AffixMgr::AffixMgr(const char * affpath, HashMgr* ptr) +-{ +- // register hash manager and load affix data from aff file +- pHMgr = ptr; +- keystring = NULL; +- trystring = NULL; +- encoding=NULL; +- utf8 = 0; +- complexprefixes = 0; +- maptable = NULL; +- nummap = 0; +- breaktable = NULL; +- numbreak = 0; +- reptable = NULL; +- numrep = 0; +- checkcpdtable = NULL; +- numcheckcpd = 0; +- defcpdtable = NULL; +- numdefcpd = 0; +- phone = NULL; +- compoundflag = FLAG_NULL; // permits word in compound forms +- compoundbegin = FLAG_NULL; // may be first word in compound forms +- compoundmiddle = FLAG_NULL; // may be middle word in compound forms +- compoundend = FLAG_NULL; // may be last word in compound forms +- compoundroot = FLAG_NULL; // compound word signing flag +- compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word +- compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word +- checkcompounddup = 0; // forbid double words in compounds +- checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution) +- checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds +- checkcompoundtriple = 0; // forbid compounds with triple letters +- forbiddenword = FLAG_NULL; // forbidden word signing flag +- nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag +- lang = NULL; // language +- langnum = 0; // language code (see http://l10n.openoffice.org/languages.html) +- pseudoroot = FLAG_NULL; // forbidden root, allowed only with suffixes +- cpdwordmax = -1; // default: unlimited wordcount in compound words +- cpdmin = -1; // undefined +- cpdmaxsyllable = 0; // default: unlimited syllablecount in compound words +- cpdvowels=NULL; // vowels (for calculating of Hungarian compounding limit, O(n) search! XXX) +- cpdvowels_utf16=NULL; // vowels for UTF-8 encoding (bsearch instead of O(n) search) +- cpdvowels_utf16_len=0; // vowels +- pfxappnd=NULL; // previous prefix for counting the syllables of prefix BUG +- sfxappnd=NULL; // previous suffix for counting a special syllables BUG +- cpdsyllablenum=NULL; // syllable count incrementing flag +- checknum=0; // checking numbers, and word with numbers +- wordchars=NULL; // letters + spec. word characters +- wordchars_utf16=NULL; // letters + spec. word characters +- wordchars_utf16_len=0; // letters + spec. word characters +- ignorechars=NULL; // letters + spec. word characters +- ignorechars_utf16=NULL; // letters + spec. word characters +- ignorechars_utf16_len=0; // letters + spec. word characters +- version=NULL; // affix and dictionary file version string +- havecontclass=0; // flags of possible continuing classes (double affix) +- // LEMMA_PRESENT: not put root into the morphological output. Lemma presents +- // in morhological description in dictionary file. It's often combined with PSEUDOROOT. +- lemma_present = FLAG_NULL; +- circumfix = FLAG_NULL; +- onlyincompound = FLAG_NULL; +- flag_mode = FLAG_CHAR; // default one-character flags in affix and dic file +- maxngramsugs = -1; // undefined +- nosplitsugs = 0; +- sugswithdots = 0; +- keepcase = 0; +- checksharps = 0; +- +- derived = NULL; // XXX not threadsafe variable for experimental stemming +- sfx = NULL; +- pfx = NULL; +- +- for (int i=0; i < SETSIZE; i++) { +- pStart[i] = NULL; +- sStart[i] = NULL; +- pFlag[i] = NULL; +- sFlag[i] = NULL; +- } +- +- for (int j=0; j < CONTSIZE; j++) { +- contclasses[j] = 0; +- } +- +- if (parse_file(affpath)) { +- HUNSPELL_WARNING(stderr, "Failure loading aff file %s\n",affpath); +- } +- +- if (cpdmin == -1) cpdmin = MINCPDLEN; +- +-} +- +- +-AffixMgr::~AffixMgr() +-{ +- +- // pass through linked prefix entries and clean up +- for (int i=0; i < SETSIZE ;i++) { +- pFlag[i] = NULL; +- PfxEntry * ptr = (PfxEntry *)pStart[i]; +- PfxEntry * nptr = NULL; +- while (ptr) { +- nptr = ptr->getNext(); +- delete(ptr); +- ptr = nptr; +- nptr = NULL; +- } +- } +- +- // pass through linked suffix entries and clean up +- for (int j=0; j < SETSIZE ; j++) { +- sFlag[j] = NULL; +- SfxEntry * ptr = (SfxEntry *)sStart[j]; +- SfxEntry * nptr = NULL; +- while (ptr) { +- nptr = ptr->getNext(); +- delete(ptr); +- ptr = nptr; +- nptr = NULL; +- } +- sStart[j] = NULL; +- } +- +- if (keystring) free(keystring); +- keystring=NULL; +- if (trystring) free(trystring); +- trystring=NULL; +- if (encoding) free(encoding); +- encoding=NULL; +- if (maptable) { +- for (int j=0; j < nummap; j++) { +- if (maptable[j].set) free(maptable[j].set); +- if (maptable[j].set_utf16) free(maptable[j].set_utf16); +- maptable[j].set = NULL; +- maptable[j].len = 0; +- } +- free(maptable); +- maptable = NULL; +- } +- nummap = 0; +- if (breaktable) { +- for (int j=0; j < numbreak; j++) { +- if (breaktable[j]) free(breaktable[j]); +- breaktable[j] = NULL; +- } +- free(breaktable); +- breaktable = NULL; +- } +- numbreak = 0; +- if (reptable) { +- for (int j=0; j < numrep; j++) { +- free(reptable[j].pattern); +- free(reptable[j].pattern2); +- } +- free(reptable); +- reptable = NULL; +- } +- if (phone && phone->rules) { +- for (int j=0; j < phone->num + 1; j++) { +- free(phone->rules[j * 2]); +- free(phone->rules[j * 2 + 1]); +- } +- free(phone->rules); +- free(phone); +- phone = NULL; +- } +- +- if (defcpdtable) { +- for (int j=0; j < numdefcpd; j++) { +- free(defcpdtable[j].def); +- defcpdtable[j].def = NULL; +- } +- free(defcpdtable); +- defcpdtable = NULL; +- } +- numrep = 0; +- if (checkcpdtable) { +- for (int j=0; j < numcheckcpd; j++) { +- free(checkcpdtable[j].pattern); +- free(checkcpdtable[j].pattern2); +- checkcpdtable[j].pattern = NULL; +- checkcpdtable[j].pattern2 = NULL; +- } +- free(checkcpdtable); +- checkcpdtable = NULL; +- } +- numcheckcpd = 0; +- FREE_FLAG(compoundflag); +- FREE_FLAG(compoundbegin); +- FREE_FLAG(compoundmiddle); +- FREE_FLAG(compoundend); +- FREE_FLAG(compoundpermitflag); +- FREE_FLAG(compoundforbidflag); +- FREE_FLAG(compoundroot); +- FREE_FLAG(forbiddenword); +- FREE_FLAG(nosuggest); +- FREE_FLAG(pseudoroot); +- FREE_FLAG(lemma_present); +- FREE_FLAG(circumfix); +- FREE_FLAG(onlyincompound); +- +- cpdwordmax = 0; +- pHMgr = NULL; +- cpdmin = 0; +- cpdmaxsyllable = 0; +- if (cpdvowels) free(cpdvowels); +- if (cpdvowels_utf16) free(cpdvowels_utf16); +- if (cpdsyllablenum) free(cpdsyllablenum); +- free_utf_tbl(); +- if (lang) free(lang); +- if (wordchars) free(wordchars); +- if (wordchars_utf16) free(wordchars_utf16); +- if (ignorechars) free(ignorechars); +- if (ignorechars_utf16) free(ignorechars_utf16); +- if (version) free(version); +- if (derived) free(derived); +- checknum=0; +-} +- +- +-// read in aff file and build up prefix and suffix entry objects +-int AffixMgr::parse_file(const char * affpath) +-{ +- +- // io buffers +- char line[MAXLNLEN+1]; +- +- // affix type +- char ft; +- +- // checking flag duplication +- char dupflags[CONTSIZE]; +- char dupflags_ini = 1; +- +- // first line indicator for removing byte order mark +- int firstline = 1; +- +- // open the affix file +- FILE * afflst; +- afflst = fopen(affpath,"r"); +- if (!afflst) { +- HUNSPELL_WARNING(stderr, "error: could not open affix description file %s\n",affpath); +- return 1; +- } +- +- // step one is to parse the affix file building up the internal +- // affix data structures +- +- +- // read in each line ignoring any that do not +- // start with a known line type indicator +- while (fgets(line,MAXLNLEN,afflst)) { +- mychomp(line); +- +- /* remove byte order mark */ +- if (firstline) { +- firstline = 0; +- if (strncmp(line,"\xEF\xBB\xBF",3) == 0) { +- memmove(line, line+3, strlen(line+3)+1); +- HUNSPELL_WARNING(stderr, "warning: affix file begins with byte order mark: possible incompatibility with old Hunspell versions\n"); +- } +- } +- +- /* parse in the keyboard string */ +- if (strncmp(line,"KEY",3) == 0) { +- if (parse_string(line, &keystring, "KEY")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the try string */ +- if (strncmp(line,"TRY",3) == 0) { +- if (parse_string(line, &trystring, "TRY")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the name of the character set used by the .dict and .aff */ +- if (strncmp(line,"SET",3) == 0) { +- if (parse_string(line, &encoding, "SET")) { +- fclose(afflst); +- return 1; +- } +- if (strcmp(encoding, "UTF-8") == 0) { +- utf8 = 1; +-#ifndef OPENOFFICEORG +-#ifndef MOZILLA_CLIENT +- if (initialize_utf_tbl()) return 1; +-#endif +-#endif +- } +- } +- +- /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left writing system */ +- if (strncmp(line,"COMPLEXPREFIXES",15) == 0) +- complexprefixes = 1; +- +- /* parse in the flag used by the controlled compound words */ +- if (strncmp(line,"COMPOUNDFLAG",12) == 0) { +- if (parse_flag(line, &compoundflag, "COMPOUNDFLAG")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by compound words */ +- if (strncmp(line,"COMPOUNDBEGIN",13) == 0) { +- if (complexprefixes) { +- if (parse_flag(line, &compoundend, "COMPOUNDBEGIN")) { +- fclose(afflst); +- return 1; +- } +- } else { +- if (parse_flag(line, &compoundbegin, "COMPOUNDBEGIN")) { +- fclose(afflst); +- return 1; +- } +- } +- } +- +- /* parse in the flag used by compound words */ +- if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) { +- if (parse_flag(line, &compoundmiddle, "COMPOUNDMIDDLE")) { +- fclose(afflst); +- return 1; +- } +- } +- /* parse in the flag used by compound words */ +- if (strncmp(line,"COMPOUNDEND",11) == 0) { +- if (complexprefixes) { +- if (parse_flag(line, &compoundbegin, "COMPOUNDEND")) { +- fclose(afflst); +- return 1; +- } +- } else { +- if (parse_flag(line, &compoundend, "COMPOUNDEND")) { +- fclose(afflst); +- return 1; +- } +- } +- } +- +- /* parse in the data used by compound_check() method */ +- if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) { +- if (parse_num(line, &cpdwordmax, "COMPOUNDWORDMAX")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag sign compounds in dictionary */ +- if (strncmp(line,"COMPOUNDROOT",12) == 0) { +- if (parse_flag(line, &compoundroot, "COMPOUNDROOT")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by compound_check() method */ +- if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) { +- if (parse_flag(line, &compoundpermitflag, "COMPOUNDPERMITFLAG")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by compound_check() method */ +- if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) { +- if (parse_flag(line, &compoundforbidflag, "COMPOUNDFORBIDFLAG")) { +- fclose(afflst); +- return 1; +- } +- } +- +- if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) { +- checkcompounddup = 1; +- } +- +- if (strncmp(line,"CHECKCOMPOUNDREP",16) == 0) { +- checkcompoundrep = 1; +- } +- +- if (strncmp(line,"CHECKCOMPOUNDTRIPLE",19) == 0) { +- checkcompoundtriple = 1; +- } +- +- if (strncmp(line,"CHECKCOMPOUNDCASE",17) == 0) { +- checkcompoundcase = 1; +- } +- +- if (strncmp(line,"NOSUGGEST",9) == 0) { +- if (parse_flag(line, &nosuggest, "NOSUGGEST")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by forbidden words */ +- if (strncmp(line,"FORBIDDENWORD",13) == 0) { +- if (parse_flag(line, &forbiddenword, "FORBIDDENWORD")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by forbidden words */ +- if (strncmp(line,"LEMMA_PRESENT",13) == 0) { +- if (parse_flag(line, &lemma_present, "LEMMA_PRESENT")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by circumfixes */ +- if (strncmp(line,"CIRCUMFIX",9) == 0) { +- if (parse_flag(line, &circumfix, "CIRCUMFIX")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by fogemorphemes */ +- if (strncmp(line,"ONLYINCOMPOUND",14) == 0) { +- if (parse_flag(line, &onlyincompound, "ONLYINCOMPOUND")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by `pseudoroots' */ +- if (strncmp(line,"PSEUDOROOT",10) == 0) { +- if (parse_flag(line, &pseudoroot, "PSEUDOROOT")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by `pseudoroots' */ +- if (strncmp(line,"NEEDAFFIX",9) == 0) { +- if (parse_flag(line, &pseudoroot, "NEEDAFFIX")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the minimal length for words in compounds */ +- if (strncmp(line,"COMPOUNDMIN",11) == 0) { +- if (parse_num(line, &cpdmin, "COMPOUNDMIN")) { +- fclose(afflst); +- return 1; +- } +- if (cpdmin < 1) cpdmin = 1; +- } +- +- /* parse in the max. words and syllables in compounds */ +- if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) { +- if (parse_cpdsyllable(line)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by compound_check() method */ +- if (strncmp(line,"SYLLABLENUM",11) == 0) { +- if (parse_string(line, &cpdsyllablenum, "SYLLABLENUM")) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the flag used by the controlled compound words */ +- if (strncmp(line,"CHECKNUM",8) == 0) { +- checknum=1; +- } +- +- /* parse in the extra word characters */ +- if (strncmp(line,"WORDCHARS",9) == 0) { +- if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, "WORDCHARS", utf8)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the ignored characters (for example, Arabic optional diacretics charachters */ +- if (strncmp(line,"IGNORE",6) == 0) { +- if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the typical fault correcting table */ +- if (strncmp(line,"REP",3) == 0) { +- if (parse_reptable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the phonetic translation table */ +- if (strncmp(line,"PHONE",5) == 0) { +- if (parse_phonetable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the checkcompoundpattern table */ +- if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) { +- if (parse_checkcpdtable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the defcompound table */ +- if (strncmp(line,"COMPOUNDRULE",12) == 0) { +- if (parse_defcpdtable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the related character map table */ +- if (strncmp(line,"MAP",3) == 0) { +- if (parse_maptable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the word breakpoints table */ +- if (strncmp(line,"BREAK",5) == 0) { +- if (parse_breaktable(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +- /* parse in the language for language specific codes */ +- if (strncmp(line,"LANG",4) == 0) { +- if (parse_string(line, &lang, "LANG")) { +- fclose(afflst); +- return 1; +- } +- langnum = get_lang_num(lang); +- } +- +- if (strncmp(line,"VERSION",7) == 0) { +- if (parse_string(line, &version, "VERSION")) { +- fclose(afflst); +- return 1; +- } +- } +- +- if (strncmp(line,"MAXNGRAMSUGS",12) == 0) { +- if (parse_num(line, &maxngramsugs, "MAXNGRAMSUGS")) { +- fclose(afflst); +- return 1; +- } +- } +- +- if (strncmp(line,"NOSPLITSUGS",11) == 0) { +- nosplitsugs=1; +- } +- +- if (strncmp(line,"SUGSWITHDOTS",12) == 0) { +- sugswithdots=1; +- } +- +- /* parse in the flag used by forbidden words */ +- if (strncmp(line,"KEEPCASE",8) == 0) { +- if (parse_flag(line, &keepcase, "KEEPCASE")) { +- fclose(afflst); +- return 1; +- } +- } +- +- if (strncmp(line,"CHECKSHARPS",11) == 0) { +- checksharps=1; +- } +- +- /* parse this affix: P - prefix, S - suffix */ +- ft = ' '; +- if (strncmp(line,"PFX",3) == 0) ft = complexprefixes ? 'S' : 'P'; +- if (strncmp(line,"SFX",3) == 0) ft = complexprefixes ? 'P' : 'S'; +- if (ft != ' ') { +- if (dupflags_ini) { +- for (int i = 0; i < CONTSIZE; i++) dupflags[i] = 0; +- dupflags_ini = 0; +- } +- if (parse_affix(line, ft, afflst, dupflags)) { +- fclose(afflst); +- process_pfx_tree_to_list(); +- process_sfx_tree_to_list(); +- return 1; +- } +- } +- +- } +- fclose(afflst); +- +- // convert affix trees to sorted list +- process_pfx_tree_to_list(); +- process_sfx_tree_to_list(); +- +- // now we can speed up performance greatly taking advantage of the +- // relationship between the affixes and the idea of "subsets". +- +- // View each prefix as a potential leading subset of another and view +- // each suffix (reversed) as a potential trailing subset of another. +- +- // To illustrate this relationship if we know the prefix "ab" is found in the +- // word to examine, only prefixes that "ab" is a leading subset of need be examined. +- // Furthermore is "ab" is not present then none of the prefixes that "ab" is +- // is a subset need be examined. +- // The same argument goes for suffix string that are reversed. +- +- // Then to top this off why not examine the first char of the word to quickly +- // limit the set of prefixes to examine (i.e. the prefixes to examine must +- // be leading supersets of the first character of the word (if they exist) +- +- // To take advantage of this "subset" relationship, we need to add two links +- // from entry. One to take next if the current prefix is found (call it nexteq) +- // and one to take next if the current prefix is not found (call it nextne). +- +- // Since we have built ordered lists, all that remains is to properly intialize +- // the nextne and nexteq pointers that relate them +- +- process_pfx_order(); +- process_sfx_order(); +- +- /* get encoding for CHECKCOMPOUNDCASE */ +- char * enc = get_encoding(); +- csconv = get_current_cs(enc); +- free(enc); +- enc = NULL; +- +- // temporary BREAK definition for German dash handling (OOo issue 64400) +- if ((langnum == LANG_de) && (!breaktable)) { +- breaktable = (char **) malloc(sizeof(char *)); +- if (!breaktable) return 1; +- breaktable[0] = mystrdup("-"); +- numbreak = 1; +- } +- return 0; +-} +- +- +-// we want to be able to quickly access prefix information +-// both by prefix flag, and sorted by prefix string itself +-// so we need to set up two indexes +- +-int AffixMgr::build_pfxtree(AffEntry* pfxptr) +-{ +- PfxEntry * ptr; +- PfxEntry * pptr; +- PfxEntry * ep = (PfxEntry*) pfxptr; +- +- // get the right starting points +- const char * key = ep->getKey(); +- const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF); +- +- // first index by flag which must exist +- ptr = (PfxEntry*)pFlag[flg]; +- ep->setFlgNxt(ptr); +- pFlag[flg] = (AffEntry *) ep; +- +- +- // handle the special case of null affix string +- if (strlen(key) == 0) { +- // always inset them at head of list at element 0 +- ptr = (PfxEntry*)pStart[0]; +- ep->setNext(ptr); +- pStart[0] = (AffEntry*)ep; +- return 0; +- } +- +- // now handle the normal case +- ep->setNextEQ(NULL); +- ep->setNextNE(NULL); +- +- unsigned char sp = *((const unsigned char *)key); +- ptr = (PfxEntry*)pStart[sp]; +- +- // handle the first insert +- if (!ptr) { +- pStart[sp] = (AffEntry*)ep; +- return 0; +- } +- +- +- // otherwise use binary tree insertion so that a sorted +- // list can easily be generated later +- pptr = NULL; +- for (;;) { +- pptr = ptr; +- if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) { +- ptr = ptr->getNextEQ(); +- if (!ptr) { +- pptr->setNextEQ(ep); +- break; +- } +- } else { +- ptr = ptr->getNextNE(); +- if (!ptr) { +- pptr->setNextNE(ep); +- break; +- } +- } +- } +- return 0; +-} +- +-// we want to be able to quickly access suffix information +-// both by suffix flag, and sorted by the reverse of the +-// suffix string itself; so we need to set up two indexes +-int AffixMgr::build_sfxtree(AffEntry* sfxptr) +-{ +- SfxEntry * ptr; +- SfxEntry * pptr; +- SfxEntry * ep = (SfxEntry *) sfxptr; +- +- /* get the right starting point */ +- const char * key = ep->getKey(); +- const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF); +- +- // first index by flag which must exist +- ptr = (SfxEntry*)sFlag[flg]; +- ep->setFlgNxt(ptr); +- sFlag[flg] = (AffEntry *) ep; +- +- // next index by affix string +- +- // handle the special case of null affix string +- if (strlen(key) == 0) { +- // always inset them at head of list at element 0 +- ptr = (SfxEntry*)sStart[0]; +- ep->setNext(ptr); +- sStart[0] = (AffEntry*)ep; +- return 0; +- } +- +- // now handle the normal case +- ep->setNextEQ(NULL); +- ep->setNextNE(NULL); +- +- unsigned char sp = *((const unsigned char *)key); +- ptr = (SfxEntry*)sStart[sp]; +- +- // handle the first insert +- if (!ptr) { +- sStart[sp] = (AffEntry*)ep; +- return 0; +- } +- +- // otherwise use binary tree insertion so that a sorted +- // list can easily be generated later +- pptr = NULL; +- for (;;) { +- pptr = ptr; +- if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) { +- ptr = ptr->getNextEQ(); +- if (!ptr) { +- pptr->setNextEQ(ep); +- break; +- } +- } else { +- ptr = ptr->getNextNE(); +- if (!ptr) { +- pptr->setNextNE(ep); +- break; +- } +- } +- } +- return 0; +-} +- +-// convert from binary tree to sorted list +-int AffixMgr::process_pfx_tree_to_list() +-{ +- for (int i=1; i< SETSIZE; i++) { +- pStart[i] = process_pfx_in_order(pStart[i],NULL); +- } +- return 0; +-} +- +- +-AffEntry* AffixMgr::process_pfx_in_order(AffEntry* ptr, AffEntry* nptr) +-{ +- if (ptr) { +- nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextNE(), nptr); +- ((PfxEntry*) ptr)->setNext((PfxEntry*) nptr); +- nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextEQ(), ptr); +- } +- return nptr; +-} +- +- +-// convert from binary tree to sorted list +-int AffixMgr:: process_sfx_tree_to_list() +-{ +- for (int i=1; i< SETSIZE; i++) { +- sStart[i] = process_sfx_in_order(sStart[i],NULL); +- } +- return 0; +-} +- +-AffEntry* AffixMgr::process_sfx_in_order(AffEntry* ptr, AffEntry* nptr) +-{ +- if (ptr) { +- nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextNE(), nptr); +- ((SfxEntry*) ptr)->setNext((SfxEntry*) nptr); +- nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextEQ(), ptr); +- } +- return nptr; +-} +- +- +-// reinitialize the PfxEntry links NextEQ and NextNE to speed searching +-// using the idea of leading subsets this time +-int AffixMgr::process_pfx_order() +-{ +- PfxEntry* ptr; +- +- // loop through each prefix list starting point +- for (int i=1; i < SETSIZE; i++) { +- +- ptr = (PfxEntry*)pStart[i]; +- +- // look through the remainder of the list +- // and find next entry with affix that +- // the current one is not a subset of +- // mark that as destination for NextNE +- // use next in list that you are a subset +- // of as NextEQ +- +- for (; ptr != NULL; ptr = ptr->getNext()) { +- +- PfxEntry * nptr = ptr->getNext(); +- for (; nptr != NULL; nptr = nptr->getNext()) { +- if (! isSubset( ptr->getKey() , nptr->getKey() )) break; +- } +- ptr->setNextNE(nptr); +- ptr->setNextEQ(NULL); +- if ((ptr->getNext()) && isSubset(ptr->getKey() , (ptr->getNext())->getKey())) +- ptr->setNextEQ(ptr->getNext()); +- } +- +- // now clean up by adding smart search termination strings: +- // if you are already a superset of the previous prefix +- // but not a subset of the next, search can end here +- // so set NextNE properly +- +- ptr = (PfxEntry *) pStart[i]; +- for (; ptr != NULL; ptr = ptr->getNext()) { +- PfxEntry * nptr = ptr->getNext(); +- PfxEntry * mptr = NULL; +- for (; nptr != NULL; nptr = nptr->getNext()) { +- if (! isSubset(ptr->getKey(),nptr->getKey())) break; +- mptr = nptr; +- } +- if (mptr) mptr->setNextNE(NULL); +- } +- } +- return 0; +-} +- +-// initialize the SfxEntry links NextEQ and NextNE to speed searching +-// using the idea of leading subsets this time +-int AffixMgr::process_sfx_order() +-{ +- SfxEntry* ptr; +- +- // loop through each prefix list starting point +- for (int i=1; i < SETSIZE; i++) { +- +- ptr = (SfxEntry *) sStart[i]; +- +- // look through the remainder of the list +- // and find next entry with affix that +- // the current one is not a subset of +- // mark that as destination for NextNE +- // use next in list that you are a subset +- // of as NextEQ +- +- for (; ptr != NULL; ptr = ptr->getNext()) { +- SfxEntry * nptr = ptr->getNext(); +- for (; nptr != NULL; nptr = nptr->getNext()) { +- if (! isSubset(ptr->getKey(),nptr->getKey())) break; +- } +- ptr->setNextNE(nptr); +- ptr->setNextEQ(NULL); +- if ((ptr->getNext()) && isSubset(ptr->getKey(),(ptr->getNext())->getKey())) +- ptr->setNextEQ(ptr->getNext()); +- } +- +- +- // now clean up by adding smart search termination strings: +- // if you are already a superset of the previous suffix +- // but not a subset of the next, search can end here +- // so set NextNE properly +- +- ptr = (SfxEntry *) sStart[i]; +- for (; ptr != NULL; ptr = ptr->getNext()) { +- SfxEntry * nptr = ptr->getNext(); +- SfxEntry * mptr = NULL; +- for (; nptr != NULL; nptr = nptr->getNext()) { +- if (! isSubset(ptr->getKey(),nptr->getKey())) break; +- mptr = nptr; +- } +- if (mptr) mptr->setNextNE(NULL); +- } +- } +- return 0; +-} +- +- +- +-// takes aff file condition string and creates the +-// conds array - please see the appendix at the end of the +-// file affentry.cpp which describes what is going on here +-// in much more detail +- +-int AffixMgr::encodeit(struct affentry * ptr, char * cs) +-{ +- unsigned char c; +- int i, j, k; +- unsigned char mbr[MAXLNLEN]; +- w_char wmbr[MAXLNLEN]; +- w_char * wpos = wmbr; +- +- // now clear the conditions array */ +- for (i=0;iconds.base[i] = (unsigned char) 0; +- +- // now parse the string to create the conds array */ +- int nc = strlen(cs); +- unsigned char neg = 0; // complement indicator +- int grp = 0; // group indicator +- unsigned char n = 0; // number of conditions +- int ec = 0; // end condition indicator +- int nm = 0; // number of member in group +- +- // if no condition just return +- if (strcmp(cs,".")==0) { +- ptr->numconds = 0; +- return 0; +- } +- +- i = 0; +- while (i < nc) { +- c = *((unsigned char *)(cs + i)); +- +- // start group indicator +- if (c == '[') { +- grp = 1; +- c = 0; +- } +- +- // complement flag +- if ((grp == 1) && (c == '^')) { +- neg = 1; +- c = 0; +- } +- +- // end goup indicator +- if (c == ']') { +- ec = 1; +- c = 0; +- } +- +- // add character of group to list +- if ((grp == 1) && (c != 0)) { +- *(mbr + nm) = c; +- nm++; +- c = 0; +- } +- +- // end of condition +- if (c != 0) { +- ec = 1; +- } +- +- if (ec) { +- if (!utf8) { +- if (grp == 1) { +- if (neg == 0) { +- // set the proper bits in the condition array vals for those chars +- for (j=0;jconds.base[k] = ptr->conds.base[k] | ((unsigned char)1 << n); +- } +- } else { +- // complement so set all of them and then unset indicated ones +- for (j=0;jconds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n); +- for (j=0;jconds.base[k] = ptr->conds.base[k] & ~((unsigned char)1 << n); +- } +- } +- neg = 0; +- grp = 0; +- nm = 0; +- } else { +- // not a group so just set the proper bit for this char +- // but first handle special case of . inside condition +- if (c == '.') { +- // wild card character so set them all +- for (j=0;jconds.base[j] = ptr->conds.base[j] | ((unsigned char)1 << n); +- } else { +- ptr->conds.base[(unsigned int) c] = ptr->conds.base[(unsigned int)c] | ((unsigned char)1 << n); +- } +- } +- n++; +- ec = 0; +- } else { // UTF-8 character set +- if (grp == 1) { +- ptr->conds.utf8.neg[n] = neg; +- if (neg == 0) { +- // set the proper bits in the condition array vals for those chars +- for (j=0;j> 7) { +- u8_u16(wpos, 1, (char *) mbr + j); +- wpos++; +- if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character +- } else { +- ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] | ((unsigned char)1 << n); +- } +- } +- } else { // neg == 1 +- // complement so set all of them and then unset indicated ones +- for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n); +- for (j=0;j> 7) { +- u8_u16(wpos, 1, (char *) mbr + j); +- wpos++; +- if ((k & 0xe0) == 0xe0) j+=2; else j++; // 3-byte UTF-8 character +- } else { +- ptr->conds.utf8.ascii[k] = ptr->conds.utf8.ascii[k] & ~((unsigned char)1 << n); +- } +- } +- } +- neg = 0; +- grp = 0; +- nm = 0; +- ptr->conds.utf8.wlen[n] = wpos - wmbr; +- if ((wpos - wmbr) != 0) { +- ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char) * (wpos - wmbr)); +- if (!ptr->conds.utf8.wchars[n]) return 1; +- memcpy(ptr->conds.utf8.wchars[n], wmbr, sizeof(w_char) * (wpos - wmbr)); +- flag_qsort((unsigned short *) ptr->conds.utf8.wchars[n], 0, ptr->conds.utf8.wlen[n]); +- wpos = wmbr; +- } +- } else { // grp == 0 +- // is UTF-8 character? +- if (c >> 7) { +- ptr->conds.utf8.wchars[n] = (w_char *) malloc(sizeof(w_char)); +- if (!ptr->conds.utf8.wchars[n]) return 1; +- ptr->conds.utf8.wlen[n] = 1; +- u8_u16(ptr->conds.utf8.wchars[n], 1, cs + i); +- if ((c & 0xe0) == 0xe0) i+=2; else i++; // 3-byte UFT-8 character +- } else { +- ptr->conds.utf8.wchars[n] = NULL; +- // not a group so just set the proper bit for this char +- // but first handle special case of . inside condition +- if (c == '.') { +- ptr->conds.utf8.all[n] = 1; +- // wild card character so set them all +- for (j=0;j<(SETSIZE/2);j++) ptr->conds.utf8.ascii[j] = ptr->conds.utf8.ascii[j] | ((unsigned char)1 << n); +- } else { +- ptr->conds.utf8.all[n] = 0; +- ptr->conds.utf8.ascii[(unsigned int) c] = ptr->conds.utf8.ascii[(unsigned int)c] | ((unsigned char)1 << n); +- } +- } +- neg = 0; +- } +- n++; +- ec = 0; +- neg = 0; +- } +- } +- +- i++; +- } +- ptr->numconds = n; +- return 0; +-} +- +- // return 1 if s1 is a leading subset of s2 +-/* inline int AffixMgr::isSubset(const char * s1, const char * s2) +- { +- while ((*s1 == *s2) && *s1) { +- s1++; +- s2++; +- } +- return (*s1 == '\0'); +- } +-*/ +- +- // return 1 if s1 is a leading subset of s2 (dots are for infixes) +-inline int AffixMgr::isSubset(const char * s1, const char * s2) +- { +- while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0')) { +- s1++; +- s2++; +- } +- return (*s1 == '\0'); +- } +- +- +-// check word for prefixes +-struct hentry * AffixMgr::prefix_check(const char * word, int len, char in_compound, +- const FLAG needflag) +-{ +- struct hentry * rv= NULL; +- +- pfx = NULL; +- pfxappnd = NULL; +- sfxappnd = NULL; +- +- // first handle the special case of 0 length prefixes +- PfxEntry * pe = (PfxEntry *) pStart[0]; +- while (pe) { +- if ( +- // fogemorpheme +- ((in_compound != IN_CPD_NOT) || !(pe->getCont() && +- (TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) && +- // permit prefixes in compounds +- ((in_compound != IN_CPD_END) || (pe->getCont() && +- (TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen())))) +- ) { +- // check prefix +- rv = pe->checkword(word, len, in_compound, needflag); +- if (rv) { +- pfx=(AffEntry *)pe; // BUG: pfx not stateless +- return rv; +- } +- } +- pe = pe->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)word); +- PfxEntry * pptr = (PfxEntry *)pStart[sp]; +- +- while (pptr) { +- if (isSubset(pptr->getKey(),word)) { +- if ( +- // fogemorpheme +- ((in_compound != IN_CPD_NOT) || !(pptr->getCont() && +- (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) && +- // permit prefixes in compounds +- ((in_compound != IN_CPD_END) || (pptr->getCont() && +- (TESTAFF(pptr->getCont(), compoundpermitflag, pptr->getContLen())))) +- ) { +- // check prefix +- rv = pptr->checkword(word, len, in_compound, needflag); +- if (rv) { +- pfx=(AffEntry *)pptr; // BUG: pfx not stateless +- return rv; +- } +- } +- pptr = pptr->getNextEQ(); +- } else { +- pptr = pptr->getNextNE(); +- } +- } +- +- return NULL; +-} +- +-// check word for prefixes +-struct hentry * AffixMgr::prefix_check_twosfx(const char * word, int len, +- char in_compound, const FLAG needflag) +-{ +- struct hentry * rv= NULL; +- +- pfx = NULL; +- sfxappnd = NULL; +- +- // first handle the special case of 0 length prefixes +- PfxEntry * pe = (PfxEntry *) pStart[0]; +- +- while (pe) { +- rv = pe->check_twosfx(word, len, in_compound, needflag); +- if (rv) return rv; +- pe = pe->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)word); +- PfxEntry * pptr = (PfxEntry *)pStart[sp]; +- +- while (pptr) { +- if (isSubset(pptr->getKey(),word)) { +- rv = pptr->check_twosfx(word, len, in_compound, needflag); +- if (rv) { +- pfx = (AffEntry *)pptr; +- return rv; +- } +- pptr = pptr->getNextEQ(); +- } else { +- pptr = pptr->getNextNE(); +- } +- } +- +- return NULL; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// check word for prefixes +-char * AffixMgr::prefix_check_morph(const char * word, int len, char in_compound, +- const FLAG needflag) +-{ +- char * st; +- +- char result[MAXLNLEN]; +- result[0] = '\0'; +- +- pfx = NULL; +- sfxappnd = NULL; +- +- // first handle the special case of 0 length prefixes +- PfxEntry * pe = (PfxEntry *) pStart[0]; +- while (pe) { +- st = pe->check_morph(word,len,in_compound, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- } +- // if (rv) return rv; +- pe = pe->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)word); +- PfxEntry * pptr = (PfxEntry *)pStart[sp]; +- +- while (pptr) { +- if (isSubset(pptr->getKey(),word)) { +- st = pptr->check_morph(word,len,in_compound, needflag); +- if (st) { +- // fogemorpheme +- if ((in_compound != IN_CPD_NOT) || !((pptr->getCont() && +- (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen()))))) { +- strcat(result, st); +- pfx = (AffEntry *)pptr; +- } +- free(st); +- } +- pptr = pptr->getNextEQ(); +- } else { +- pptr = pptr->getNextNE(); +- } +- } +- +- if (*result) return mystrdup(result); +- return NULL; +-} +- +- +-// check word for prefixes +-char * AffixMgr::prefix_check_twosfx_morph(const char * word, int len, +- char in_compound, const FLAG needflag) +-{ +- char * st; +- +- char result[MAXLNLEN]; +- result[0] = '\0'; +- +- pfx = NULL; +- sfxappnd = NULL; +- +- // first handle the special case of 0 length prefixes +- PfxEntry * pe = (PfxEntry *) pStart[0]; +- while (pe) { +- st = pe->check_twosfx_morph(word,len,in_compound, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- } +- pe = pe->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)word); +- PfxEntry * pptr = (PfxEntry *)pStart[sp]; +- +- while (pptr) { +- if (isSubset(pptr->getKey(),word)) { +- st = pptr->check_twosfx_morph(word, len, in_compound, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- pfx = (AffEntry *)pptr; +- } +- pptr = pptr->getNextEQ(); +- } else { +- pptr = pptr->getNextNE(); +- } +- } +- +- if (*result) return mystrdup(result); +- return NULL; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +- +-// Is word a non compound with a REP substitution (see checkcompoundrep)? +-int AffixMgr::cpdrep_check(const char * word, int wl) +-{ +- char candidate[MAXLNLEN]; +- const char * r; +- int lenr, lenp; +- +- if ((wl < 2) || !numrep) return 0; +- +- for (int i=0; i < numrep; i++ ) { +- r = word; +- lenr = strlen(reptable[i].pattern2); +- lenp = strlen(reptable[i].pattern); +- // search every occurence of the pattern in the word +- while ((r=strstr(r, reptable[i].pattern)) != NULL) { +- strcpy(candidate, word); +- if (r-word + lenr + strlen(r+lenp) >= MAXLNLEN) break; +- strcpy(candidate+(r-word),reptable[i].pattern2); +- strcpy(candidate+(r-word)+lenr, r+lenp); +- if (candidate_check(candidate,strlen(candidate))) return 1; +- r++; // search for the next letter +- } +- } +- return 0; +-} +- +-// forbid compoundings when there are special patterns at word bound +-int AffixMgr::cpdpat_check(const char * word, int pos) +-{ +- int len; +- for (int i = 0; i < numcheckcpd; i++) { +- if (isSubset(checkcpdtable[i].pattern2, word + pos) && +- (len = strlen(checkcpdtable[i].pattern)) && (pos > len) && +- (strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)) return 1; +- } +- return 0; +-} +- +-// forbid compounding with neighbouring upper and lower case characters at word bounds +-int AffixMgr::cpdcase_check(const char * word, int pos) +-{ +- if (utf8) { +- w_char u, w; +- const char * p; +- u8_u16(&u, 1, word + pos); +- for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--); +- u8_u16(&w, 1, p); +- unsigned short a = (u.h << 8) + u.l; +- unsigned short b = (w.h << 8) + w.l; +- if (((unicodetoupper(a, langnum) == a) || (unicodetoupper(b, langnum) == b))) return 1; +- } else { +- unsigned char a = *(word + pos - 1); +- unsigned char b = *(word + pos); +- if ((csconv[a].ccase || csconv[b].ccase) && (a != '-') && (b != '-')) return 1; +- } +- return 0; +-} +- +-// check compound patterns +-int AffixMgr::defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** def, char all) +-{ +- signed short btpp[MAXWORDLEN]; // metacharacter (*, ?) positions for backtracking +- signed short btwp[MAXWORDLEN]; // word positions for metacharacters +- int btnum[MAXWORDLEN]; // number of matched characters in metacharacter positions +- short bt = 0; +- int i; +- int ok; +- int w = 0; +- if (!*words) { +- w = 1; +- *words = def; +- } +- (*words)[wnum] = rv; +- +- for (i = 0; i < numdefcpd; i++) { +- signed short pp = 0; // pattern position +- signed short wp = 0; // "words" position +- int ok2; +- ok = 1; +- ok2 = 1; +- do { +- while ((pp < defcpdtable[i].len) && (wp <= wnum)) { +- if (((pp+1) < defcpdtable[i].len) && +- ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) { +- int wend = (defcpdtable[i].def[pp+1] == '?') ? wp : wnum; +- ok2 = 1; +- pp+=2; +- btpp[bt] = pp; +- btwp[bt] = wp; +- while (wp <= wend) { +- if (!(*words)[wp]->alen || +- !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp-2], (*words)[wp]->alen)) { +- ok2 = 0; +- break; +- } +- wp++; +- } +- if (wp <= wnum) ok2 = 0; +- btnum[bt] = wp - btwp[bt]; +- if (btnum[bt] > 0) bt++; +- if (ok2) break; +- } else { +- ok2 = 1; +- if (!(*words)[wp] || !(*words)[wp]->alen || +- !TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp], (*words)[wp]->alen)) { +- ok = 0; +- break; +- } +- pp++; +- wp++; +- if ((defcpdtable[i].len == pp) && !(wp > wnum)) ok = 0; +- } +- } +- if (ok && ok2) { +- int r = pp; +- while ((defcpdtable[i].len > r) && ((r+1) < defcpdtable[i].len) && +- ((defcpdtable[i].def[r+1] == '*') || (defcpdtable[i].def[r+1] == '?'))) r+=2; +- if (defcpdtable[i].len <= r) return 1; +- } +- // backtrack +- if (bt) do { +- ok = 1; +- btnum[bt - 1]--; +- pp = btpp[bt - 1]; +- wp = btwp[bt - 1] + btnum[bt - 1]; +- } while ((btnum[bt - 1] < 0) && --bt); +- } while (bt); +- +- if (ok && ok2 && (!all || (defcpdtable[i].len <= pp))) return 1; +- // check zero ending +- while (ok && ok2 && (defcpdtable[i].len > pp) && ((pp+1) < defcpdtable[i].len) && +- ((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) pp+=2; +- if (ok && ok2 && (defcpdtable[i].len <= pp)) return 1; +- } +- (*words)[wnum] = NULL; +- if (w) *words = NULL; +- return 0; +-} +- +-inline int AffixMgr::candidate_check(const char * word, int len) +-{ +- struct hentry * rv=NULL; +- +- rv = lookup(word); +- if (rv) return 1; +- +-// rv = prefix_check(word,len,1); +-// if (rv) return 1; +- +- rv = affix_check(word,len); +- if (rv) return 1; +- return 0; +-} +- +-// calculate number of syllable for compound-checking +-short AffixMgr::get_syllable(const char * word, int wlen) +-{ +- if (cpdmaxsyllable==0) return 0; +- +- short num=0; +- +- if (!utf8) { +- for (int i=0; i 0; i--) { +- if (flag_bsearch((unsigned short *) cpdvowels_utf16, +- ((unsigned short *) w)[i - 1], cpdvowels_utf16_len)) num++; +- } +- } +- return num; +-} +- +-// check if compound word is correctly spelled +-// hu_mov_rule = spec. Hungarian rule (XXX) +-struct hentry * AffixMgr::compound_check(const char * word, int len, +- short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words = NULL, +- char hu_mov_rule = 0, int * cmpdstemnum = NULL, int * cmpdstem = NULL, char is_sug = 0) +-{ +- int i; +- short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; +- int oldcmpdstemnum = 0; +- struct hentry * rv = NULL; +- struct hentry * rv_first; +- struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking +- char st [MAXWORDUTF8LEN + 4]; +- char ch; +- int cmin; +- int cmax; +- +- int checked_prefix; +- +-#ifdef HUNSTEM +- if (cmpdstemnum) { +- if (wordnum == 0) { +- *cmpdstemnum = 1; +- } else { +- (*cmpdstemnum)++; +- } +- } +-#endif +- if (utf8) { +- for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) { +- cmin++; +- for (; (word[cmin] & 0xc0) == 0x80; cmin++); +- } +- for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) { +- cmax--; +- for (; (word[cmax] & 0xc0) == 0x80; cmax--); +- } +- } else { +- cmin = cpdmin; +- cmax = len - cpdmin + 1; +- } +- +- strcpy(st, word); +- +- for (i = cmin; i < cmax; i++) { +- +- oldnumsyllable = numsyllable; +- oldwordnum = wordnum; +- checked_prefix = 0; +- +- // go to end of the UTF-8 character +- if (utf8) { +- for (; (st[i] & 0xc0) == 0x80; i++); +- if (i >= cmax) return NULL; +- } +- +- +- ch = st[i]; +- st[i] = '\0'; +- +- sfx = NULL; +- pfx = NULL; +- +- // FIRST WORD +- +- rv = lookup(st); // perhaps without prefix +- +- // search homonym with compound flag +- while ((rv) && !hu_mov_rule && +- ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || +- !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundbegin && !wordnum && +- TESTAFF(rv->astr, compoundbegin, rv->alen)) || +- (compoundmiddle && wordnum && !words && +- TESTAFF(rv->astr, compoundmiddle, rv->alen)) || +- (numdefcpd && +- ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) || +- (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)))) +- ))) { +- rv = rv->next_homonym; +- } +- +- if (!rv) { +- if (compoundflag && +- !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { +- if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, +- FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule && +- ((SfxEntry*)sfx)->getCont() && +- ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())) || (compoundend && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- } +- if (rv || +- (((wordnum == 0) && compoundbegin && +- ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || +- (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || +- ((wordnum > 0) && compoundmiddle && +- ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || +- (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle))))) +- ) checked_prefix = 1; +- // else check forbiddenwords and pseudoroot +- } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) || +- TESTAFF(rv->astr, pseudoroot, rv->alen) || +- (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)) +- )) { +- st[i] = ch; +- continue; +- } +- +- // check non_compound flag in suffix and prefix +- if ((rv) && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check compoundend flag in suffix and prefix +- if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check compoundmiddle flag in suffix and prefix +- if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || +- (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) { +- return NULL; +- } +- +- // increment word number, if the second root has a compoundroot flag +- if ((rv) && compoundroot && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- +- // first word is acceptable in compound words? +- if (((rv) && +- ( checked_prefix || (words && words[wnum]) || +- (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) || +- ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))// || +-// (numdefcpd && ) +- +-// LANG_hu section: spec. Hungarian rule +- || ((langnum == LANG_hu) && hu_mov_rule && ( +- TESTAFF(rv->astr, 'F', rv->alen) || // XXX hardwired Hungarian dictionary codes +- TESTAFF(rv->astr, 'G', rv->alen) || +- TESTAFF(rv->astr, 'H', rv->alen) +- ) +- ) +-// END of LANG_hu section +- ) +- && ! (( checkcompoundtriple && // test triple letters +- (word[i-1]==word[i]) && ( +- ((i>1) && (word[i-1]==word[i-2])) || +- ((word[i-1]==word[i+1])) // may be word[i+1] == '\0' +- ) +- ) || +- ( +- // test CHECKCOMPOUNDPATTERN +- numcheckcpd && cpdpat_check(word, i) +- ) || +- ( +- checkcompoundcase && cpdcase_check(word, i) +- )) +- ) +-// LANG_hu section: spec. Hungarian rule +- || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) && +- (sfx && ((SfxEntry*)sfx)->getCont() && ( // XXX hardwired Hungarian dic. codes +- TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) || +- TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen()) +- ) +- ) +- ) +-// END of LANG_hu section +- ) { +- +-// LANG_hu section: spec. Hungarian rule +- if (langnum == LANG_hu) { +- // calculate syllable number of the word +- numsyllable += get_syllable(st, i); +- +- // + 1 word, if syllable number of the prefix > 1 (hungarian convention) +- if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; +- } +-// END of LANG_hu section +- +-#ifdef HUNSTEM +- if (cmpdstem) cmpdstem[*cmpdstemnum - 1] = i; +-#endif +- +- // NEXT WORD(S) +- rv_first = rv; +- rv = lookup((word+i)); // perhaps without prefix +- +- // search homonym with compound flag +- while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || +- !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) || +- (numdefcpd && words && defcpd_check(&words, wnum + 1, rv, NULL,1))))) { +- rv = rv->next_homonym; +- } +- +- if (rv && words && words[wnum + 1]) return rv; +- +- oldnumsyllable2 = numsyllable; +- oldwordnum2 = wordnum; +- +-// LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary code +- if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) { +- numsyllable--; +- } +-// END of LANG_hu section +- +- // increment word number, if the second root has a compoundroot flag +- if ((rv) && (compoundroot) && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || +- (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL; +- +- // second word is acceptable, as a root? +- // hungarian conventions: compounding is acceptable, +- // when compound forms consist of 2 words, or if more, +- // then the syllable number of root words must be 6, or lesser. +- +- if ((rv) && ( +- (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundend && TESTAFF(rv->astr, compoundend, rv->alen)) +- ) +- && ( +- ((cpdwordmax==-1) || (wordnum+1word), rv->clen)<=cpdmaxsyllable)) +- ) +- && ( +- (!checkcompounddup || (rv != rv_first)) +- ) +- ) +- { +- // forbid compound word, if it is a non compound word with typical fault +- if (checkcompoundrep && cpdrep_check(word,len)) return NULL; +- return rv; +- } +- +- numsyllable = oldnumsyllable2 ; +- wordnum = oldwordnum2; +- +- // perhaps second word has prefix or/and suffix +- sfx = NULL; +- sfxflag = FLAG_NULL; +- rv = (compoundflag) ? affix_check((word+i),strlen(word+i), compoundflag, IN_CPD_END) : NULL; +- if (!rv && compoundend) { +- sfx = NULL; +- pfx = NULL; +- rv = affix_check((word+i),strlen(word+i), compoundend, IN_CPD_END); +- } +- +- if (!rv && numdefcpd && words) { +- rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END); +- if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1)) return rv; +- rv = NULL; +- } +- +- // check non_compound flag in suffix and prefix +- if ((rv) && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || +- (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL; +- +- // pfxappnd = prefix of word+i, or NULL +- // calculate syllable number of prefix. +- // hungarian convention: when syllable number of prefix is more, +- // than 1, the prefix+word counts as two words. +- +- if (langnum == LANG_hu) { +- // calculate syllable number of the word +- numsyllable += get_syllable(word + i, strlen(word + i)); +- +- // - affix syllable num. +- // XXX only second suffix (inflections, not derivations) +- if (sfxappnd) { +- char * tmp = myrevstrdup(sfxappnd); +- numsyllable -= get_syllable(tmp, strlen(tmp)); +- free(tmp); +- } +- +- // + 1 word, if syllable number of the prefix > 1 (hungarian convention) +- if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; +- +- // increment syllable num, if last word has a SYLLABLENUM flag +- // and the suffix is beginning `s' +- +- if (cpdsyllablenum) { +- switch (sfxflag) { +- case 'c': { numsyllable+=2; break; } +- case 'J': { numsyllable += 1; break; } +- case 'I': { if (TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; } +- } +- } +- } +- +- // increment word number, if the second word has a compoundroot flag +- if ((rv) && (compoundroot) && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- +- // second word is acceptable, as a word with prefix or/and suffix? +- // hungarian conventions: compounding is acceptable, +- // when compound forms consist 2 word, otherwise +- // the syllable number of root words is 6, or lesser. +- if ((rv) && +- ( +- ((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) || +- ((cpdmaxsyllable == 0) || +- (numsyllable <= cpdmaxsyllable)) +- ) +- && ( +- (!checkcompounddup || (rv != rv_first)) +- )) { +- // forbid compound word, if it is a non compound word with typical fault +- if (checkcompoundrep && cpdrep_check(word, len)) return NULL; +- return rv; +- } +- +- numsyllable = oldnumsyllable2; +- wordnum = oldwordnum2; +-#ifdef HUNSTEM +- if (cmpdstemnum) oldcmpdstemnum = *cmpdstemnum; +-#endif +- // perhaps second word is a compound word (recursive call) +- if (wordnum < maxwordnum) { +- rv = compound_check((word+i),strlen(word+i), wordnum+1, +- numsyllable, maxwordnum, wnum + 1, words, +- 0, cmpdstemnum, cmpdstem, is_sug); +- } else { +- rv=NULL; +- } +- if (rv) { +- // forbid compound word, if it is a non compound word with typical fault +- if (checkcompoundrep && cpdrep_check(word, len)) return NULL; +- return rv; +- } else { +-#ifdef HUNSTEM +- if (cmpdstemnum) *cmpdstemnum = oldcmpdstemnum; +-#endif +- } +- } +- st[i] = ch; +- wordnum = oldwordnum; +- numsyllable = oldnumsyllable; +- } +- +- return NULL; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// check if compound word is correctly spelled +-// hu_mov_rule = spec. Hungarian rule (XXX) +-int AffixMgr::compound_check_morph(const char * word, int len, +- short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, +- char hu_mov_rule = 0, char ** result = NULL, char * partresult = NULL) +-{ +- int i; +- short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; +- int ok = 0; +- +- struct hentry * rv = NULL; +- struct hentry * rv_first; +- struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking +- char st [MAXWORDUTF8LEN + 4]; +- char ch; +- +- int checked_prefix; +- char presult[MAXLNLEN]; +- +- int cmin; +- int cmax; +- +- if (utf8) { +- for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) { +- cmin++; +- for (; (word[cmin] & 0xc0) == 0x80; cmin++); +- } +- for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) { +- cmax--; +- for (; (word[cmax] & 0xc0) == 0x80; cmax--); +- } +- } else { +- cmin = cpdmin; +- cmax = len - cpdmin + 1; +- } +- +- strcpy(st, word); +- +- for (i = cmin; i < cmax; i++) { +- oldnumsyllable = numsyllable; +- oldwordnum = wordnum; +- checked_prefix = 0; +- +- // go to end of the UTF-8 character +- if (utf8) { +- for (; (st[i] & 0xc0) == 0x80; i++); +- if (i >= cmax) return 0; +- } +- +- ch = st[i]; +- st[i] = '\0'; +- sfx = NULL; +- +- // FIRST WORD +- *presult = '\0'; +- if (partresult) strcat(presult, partresult); +- +- rv = lookup(st); // perhaps without prefix +- +- // search homonym with compound flag +- while ((rv) && !hu_mov_rule && +- ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || +- !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundbegin && !wordnum && +- TESTAFF(rv->astr, compoundbegin, rv->alen)) || +- (compoundmiddle && wordnum && !words && +- TESTAFF(rv->astr, compoundmiddle, rv->alen)) || +- (numdefcpd && +- ((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) || +- (words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)))) +- ))) { +- rv = rv->next_homonym; +- } +- +- if (rv) { +- if (rv->description) { +- if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen)) +- strcat(presult, st); +- strcat(presult, rv->description); +- } +- } +- +- if (!rv) { +- if (compoundflag && +- !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { +- if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, +- FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule && +- ((SfxEntry*)sfx)->getCont() && +- ((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())) || (compoundend && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- } +- +- if (rv || +- (((wordnum == 0) && compoundbegin && +- ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || +- (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || +- ((wordnum > 0) && compoundmiddle && +- ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || +- (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle))))) +- ) { +- //char * p = prefix_check_morph(st, i, 0, compound); +- char * p = NULL; +- if (compoundflag) p = affix_check_morph(st, i, compoundflag); +- if (!p || (*p == '\0')) { +- if ((wordnum == 0) && compoundbegin) { +- p = affix_check_morph(st, i, compoundbegin); +- } else if ((wordnum > 0) && compoundmiddle) { +- p = affix_check_morph(st, i, compoundmiddle); +- } +- } +- if (*p != '\0') { +- line_uniq(p); +- if (strchr(p, '\n')) { +- strcat(presult, "("); +- strcat(presult, line_join(p, '|')); +- strcat(presult, ")"); +- } else { +- strcat(presult, p); +- } +- } +- if (presult[strlen(presult) - 1] == '\n') { +- presult[strlen(presult) - 1] = '\0'; +- } +- checked_prefix = 1; +- //strcat(presult, "+"); +- } +- // else check forbiddenwords +- } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) || +- TESTAFF(rv->astr, pseudoroot, rv->alen))) { +- st[i] = ch; +- continue; +- } +- +- // check non_compound flag in suffix and prefix +- if ((rv) && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())))) { +- continue; +- } +- +- // check compoundend flag in suffix and prefix +- if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend, +- ((SfxEntry*)sfx)->getContLen())))) { +- continue; +- } +- +- // check compoundmiddle flag in suffix and prefix +- if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) continue; +- +- // increment word number, if the second root has a compoundroot flag +- if ((rv) && (compoundroot) && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- +- // first word is acceptable in compound words? +- if (((rv) && +- ( checked_prefix || (words && words[wnum]) || +- (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- ((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) || +- ((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen)) +-// LANG_hu section: spec. Hungarian rule +- || ((langnum == LANG_hu) && // hu_mov_rule +- hu_mov_rule && ( +- TESTAFF(rv->astr, 'F', rv->alen) || +- TESTAFF(rv->astr, 'G', rv->alen) || +- TESTAFF(rv->astr, 'H', rv->alen) +- ) +- ) +-// END of LANG_hu section +- ) +- && ! (( checkcompoundtriple && // test triple letters +- (word[i-1]==word[i]) && ( +- ((i>1) && (word[i-1]==word[i-2])) || +- ((word[i-1]==word[i+1])) // may be word[i+1] == '\0' +- ) +- ) || +- ( +- // test CHECKCOMPOUNDPATTERN +- numcheckcpd && cpdpat_check(word, i) +- ) || +- ( +- checkcompoundcase && cpdcase_check(word, i) +- )) +- ) +-// LANG_hu section: spec. Hungarian rule +- || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) && +- (sfx && ((SfxEntry*)sfx)->getCont() && ( +- TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) || +- TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen()) +- ) +- ) +- ) +-// END of LANG_hu section +- ) { +- +-// LANG_hu section: spec. Hungarian rule +- if (langnum == LANG_hu) { +- // calculate syllable number of the word +- numsyllable += get_syllable(st, i); +- +- // + 1 word, if syllable number of the prefix > 1 (hungarian convention) +- if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; +- } +-// END of LANG_hu section +- +- // NEXT WORD(S) +- rv_first = rv; +- rv = lookup((word+i)); // perhaps without prefix +- +- // search homonym with compound flag +- while ((rv) && ((pseudoroot && TESTAFF(rv->astr, pseudoroot, rv->alen)) || +- !((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) || +- (numdefcpd && defcpd_check(&words, wnum + 1, rv, NULL,1))))) { +- rv = rv->next_homonym; +- } +- +- if (rv && words && words[wnum + 1]) { +- strcat(*result, presult); +- if (complexprefixes && rv->description) strcat(*result, rv->description); +- if (rv->description && ((!rv->astr) || +- !TESTAFF(rv->astr, lemma_present, rv->alen))) +- strcat(*result, &(rv->word)); +- if (!complexprefixes && rv->description) strcat(*result, rv->description); +- strcat(*result, "\n"); +- ok = 1; +- return 0; +- } +- +- oldnumsyllable2 = numsyllable; +- oldwordnum2 = wordnum; +- +-// LANG_hu section: spec. Hungarian rule +- if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) { +- numsyllable--; +- } +-// END of LANG_hu section +- // increment word number, if the second root has a compoundroot flag +- if ((rv) && (compoundroot) && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) { +- st[i] = ch; +- continue; +- } +- +- // second word is acceptable, as a root? +- // hungarian conventions: compounding is acceptable, +- // when compound forms consist of 2 words, or if more, +- // then the syllable number of root words must be 6, or lesser. +- if ((rv) && ( +- (compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) || +- (compoundend && TESTAFF(rv->astr, compoundend, rv->alen)) +- ) +- && ( +- ((cpdwordmax==-1) || (wordnum+1word),rv->wlen)<=cpdmaxsyllable)) +- ) +- && ( +- (!checkcompounddup || (rv != rv_first)) +- ) +- ) +- { +- // bad compound word +- strcat(*result, presult); +- +- if (rv->description) { +- if (complexprefixes) strcat(*result, rv->description); +- if ((!rv->astr) || !TESTAFF(rv->astr, lemma_present, rv->alen)) +- strcat(*result, &(rv->word)); +- if (!complexprefixes) strcat(*result, rv->description); +- } +- strcat(*result, "\n"); +- ok = 1; +- } +- +- numsyllable = oldnumsyllable2 ; +- wordnum = oldwordnum2; +- +- // perhaps second word has prefix or/and suffix +- sfx = NULL; +- sfxflag = FLAG_NULL; +- +- if (compoundflag) rv = affix_check((word+i),strlen(word+i), compoundflag); else rv = NULL; +- +- if (!rv && compoundend) { +- sfx = NULL; +- pfx = NULL; +- rv = affix_check((word+i),strlen(word+i), compoundend); +- } +- +- if (!rv && numdefcpd && words) { +- rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END); +- if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) { +- char * m = NULL; +- if (compoundflag) m = affix_check_morph((word+i),strlen(word+i), compoundflag); +- if ((!m || *m == '\0') && compoundend) +- m = affix_check_morph((word+i),strlen(word+i), compoundend); +- strcat(*result, presult); +- if (m) { +- line_uniq(m); +- if (strchr(m, '\n')) { +- strcat(*result, "("); +- strcat(*result, line_join(m, '|')); +- strcat(*result, ")"); +- } else { +- strcat(*result, m); +- } +- free(m); +- } +- strcat(*result, "\n"); +- ok = 1; +- } +- } +- +- // check non_compound flag in suffix and prefix +- if ((rv) && +- ((pfx && ((PfxEntry*)pfx)->getCont() && +- TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag, +- ((PfxEntry*)pfx)->getContLen())) || +- (sfx && ((SfxEntry*)sfx)->getCont() && +- TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag, +- ((SfxEntry*)sfx)->getContLen())))) { +- rv = NULL; +- } +- +- // check forbiddenwords +- if ((rv) && (rv->astr) && (TESTAFF(rv->astr,forbiddenword,rv->alen)) +- && (! TESTAFF(rv->astr, pseudoroot, rv->alen))) { +- st[i] = ch; +- continue; +- } +- +- if (langnum == LANG_hu) { +- // calculate syllable number of the word +- numsyllable += get_syllable(word + i, strlen(word + i)); +- +- // - affix syllable num. +- // XXX only second suffix (inflections, not derivations) +- if (sfxappnd) { +- char * tmp = myrevstrdup(sfxappnd); +- numsyllable -= get_syllable(tmp, strlen(tmp)); +- free(tmp); +- } +- +- // + 1 word, if syllable number of the prefix > 1 (hungarian convention) +- if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++; +- +- // increment syllable num, if last word has a SYLLABLENUM flag +- // and the suffix is beginning `s' +- +- if (cpdsyllablenum) { +- switch (sfxflag) { +- case 'c': { numsyllable+=2; break; } +- case 'J': { numsyllable += 1; break; } +- case 'I': { if (rv && TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; } +- } +- } +- } +- +- // increment word number, if the second word has a compoundroot flag +- if ((rv) && (compoundroot) && +- (TESTAFF(rv->astr, compoundroot, rv->alen))) { +- wordnum++; +- } +- // second word is acceptable, as a word with prefix or/and suffix? +- // hungarian conventions: compounding is acceptable, +- // when compound forms consist 2 word, otherwise +- // the syllable number of root words is 6, or lesser. +- if ((rv) && +- ( +- ((cpdwordmax==-1) || (wordnum+1 0) && *s1 && (*s1 == *end_of_s2)) { +- s1++; +- end_of_s2--; +- len--; +- } +- return (*s1 == '\0'); +- } +- */ +- +-inline int AffixMgr::isRevSubset(const char * s1, const char * end_of_s2, int len) +- { +- while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) { +- s1++; +- end_of_s2--; +- len--; +- } +- return (*s1 == '\0'); +- } +- +-// check word for suffixes +- +-struct hentry * AffixMgr::suffix_check (const char * word, int len, +- int sfxopts, AffEntry * ppfx, char ** wlst, int maxSug, int * ns, +- const FLAG cclass, const FLAG needflag, char in_compound) +-{ +- struct hentry * rv = NULL; +- char result[MAXLNLEN]; +- +- PfxEntry* ep = (PfxEntry *) ppfx; +- +- // first handle the special case of 0 length suffixes +- SfxEntry * se = (SfxEntry *) sStart[0]; +- +- while (se) { +- if (!cclass || se->getCont()) { +- // suffixes are not allowed in beginning of compounds +- if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass +- // except when signed with compoundpermitflag flag +- (se->getCont() && compoundpermitflag && +- TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix || +- // no circumfix flag in prefix and suffix +- ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) || +- // circumfix flag in prefix AND suffix +- ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) && +- // fogemorpheme +- (in_compound || +- !((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) && +- // pseudoroot on prefix or first suffix +- (cclass || +- !(se->getCont() && TESTAFF(se->getCont(), pseudoroot, se->getContLen())) || +- (ppfx && !((ep->getCont()) && +- TESTAFF(ep->getCont(), pseudoroot, +- ep->getContLen()))) +- ) +- ) { +- rv = se->checkword(word,len, sfxopts, ppfx, wlst, maxSug, ns, (FLAG) cclass, +- needflag, (in_compound ? 0 : onlyincompound)); +- if (rv) { +- sfx=(AffEntry *)se; // BUG: sfx not stateless +- return rv; +- } +- } +- } +- se = se->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)(word + len - 1)); +- SfxEntry * sptr = (SfxEntry *) sStart[sp]; +- +- while (sptr) { +- if (isRevSubset(sptr->getKey(), word + len - 1, len) +- ) { +- // suffixes are not allowed in beginning of compounds +- if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass +- // except when signed with compoundpermitflag flag +- (sptr->getCont() && compoundpermitflag && +- TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix || +- // no circumfix flag in prefix and suffix +- ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) || +- // circumfix flag in prefix AND suffix +- ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) && +- // fogemorpheme +- (in_compound || +- !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) && +- // pseudoroot on prefix or first suffix +- (cclass || +- !(sptr->getCont() && TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen())) || +- (ppfx && !((ep->getCont()) && +- TESTAFF(ep->getCont(), pseudoroot, +- ep->getContLen()))) +- ) +- ) { +- rv = sptr->checkword(word,len, sfxopts, ppfx, wlst, +- maxSug, ns, cclass, needflag, (in_compound ? 0 : onlyincompound)); +- if (rv) { +- sfx=(AffEntry *)sptr; // BUG: sfx not stateless +- sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless +- if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless +- if (cclass || sptr->getCont()) { +- if (!derived) { +- derived = mystrdup(word); +- } else { +- strcpy(result, derived); // XXX check size +- strcat(result, "\n"); +- strcat(result, word); +- free(derived); +- derived = mystrdup(result); +- } +- } +- return rv; +- } +- } +- sptr = sptr->getNextEQ(); +- } else { +- sptr = sptr->getNextNE(); +- } +- } +- +- return NULL; +-} +- +-// check word for two-level suffixes +- +-struct hentry * AffixMgr::suffix_check_twosfx(const char * word, int len, +- int sfxopts, AffEntry * ppfx, const FLAG needflag) +-{ +- struct hentry * rv = NULL; +- +- // first handle the special case of 0 length suffixes +- SfxEntry * se = (SfxEntry *) sStart[0]; +- while (se) { +- if (contclasses[se->getFlag()]) +- { +- rv = se->check_twosfx(word,len, sfxopts, ppfx, needflag); +- if (rv) return rv; +- } +- se = se->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)(word + len - 1)); +- SfxEntry * sptr = (SfxEntry *) sStart[sp]; +- +- while (sptr) { +- if (isRevSubset(sptr->getKey(), word + len - 1, len)) { +- if (contclasses[sptr->getFlag()]) +- { +- rv = sptr->check_twosfx(word,len, sfxopts, ppfx, needflag); +- if (rv) { +- sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless +- if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless +- return rv; +- } +- } +- sptr = sptr->getNextEQ(); +- } else { +- sptr = sptr->getNextNE(); +- } +- } +- +- return NULL; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-char * AffixMgr::suffix_check_twosfx_morph(const char * word, int len, +- int sfxopts, AffEntry * ppfx, const FLAG needflag) +-{ +- char result[MAXLNLEN]; +- char result2[MAXLNLEN]; +- char result3[MAXLNLEN]; +- +- char * st; +- +- result[0] = '\0'; +- result2[0] = '\0'; +- result3[0] = '\0'; +- +- // first handle the special case of 0 length suffixes +- SfxEntry * se = (SfxEntry *) sStart[0]; +- while (se) { +- if (contclasses[se->getFlag()]) +- { +- st = se->check_twosfx_morph(word,len, sfxopts, ppfx, needflag); +- if (st) { +- if (ppfx) { +- if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); +- } +- strcat(result, st); +- free(st); +- if (se->getMorph()) strcat(result, se->getMorph()); +- strcat(result, "\n"); +- } +- } +- se = se->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)(word + len - 1)); +- SfxEntry * sptr = (SfxEntry *) sStart[sp]; +- +- while (sptr) { +- if (isRevSubset(sptr->getKey(), word + len - 1, len)) { +- if (contclasses[sptr->getFlag()]) +- { +- st = sptr->check_twosfx_morph(word,len, sfxopts, ppfx, needflag); +- if (st) { +- sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless +- if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless +- strcpy(result2, st); +- free(st); +- +- result3[0] = '\0'; +-#ifdef DEBUG +- unsigned short flag = sptr->getFlag(); +- if (flag_mode == FLAG_NUM) { +- sprintf(result3, "<%d>", sptr->getKey()); +- } else if (flag_mode == FLAG_LONG) { +- sprintf(result3, "<%c%c>", flag >> 8, (flag << 8) >>8); +- } else sprintf(result3, "<%c>", flag); +- strcat(result3, ":"); +-#endif +- if (sptr->getMorph()) strcat(result3, sptr->getMorph()); +- strlinecat(result2, result3); +- strcat(result2, "\n"); +- strcat(result, result2); +- } +- } +- sptr = sptr->getNextEQ(); +- } else { +- sptr = sptr->getNextNE(); +- } +- } +- if (result) return mystrdup(result); +- return NULL; +-} +- +-char * AffixMgr::suffix_check_morph(const char * word, int len, +- int sfxopts, AffEntry * ppfx, const FLAG cclass, const FLAG needflag, char in_compound) +-{ +- char result[MAXLNLEN]; +- +- struct hentry * rv = NULL; +- +- result[0] = '\0'; +- +- PfxEntry* ep = (PfxEntry *) ppfx; +- +- // first handle the special case of 0 length suffixes +- SfxEntry * se = (SfxEntry *) sStart[0]; +- while (se) { +- if (!cclass || se->getCont()) { +- // suffixes are not allowed in beginning of compounds +- if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass +- // except when signed with compoundpermitflag flag +- (se->getCont() && compoundpermitflag && +- TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix || +- // no circumfix flag in prefix and suffix +- ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) || +- // circumfix flag in prefix AND suffix +- ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) && +- // fogemorpheme +- (in_compound || +- !((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) && +- // pseudoroot on prefix or first suffix +- (cclass || +- !(se->getCont() && TESTAFF(se->getCont(), pseudoroot, se->getContLen())) || +- (ppfx && !((ep->getCont()) && +- TESTAFF(ep->getCont(), pseudoroot, +- ep->getContLen()))) +- ) +- )) +- rv = se->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag); +- while (rv) { +- if (ppfx) { +- if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); +- } +- if (complexprefixes && rv->description) strcat(result, rv->description); +- if (rv->description && ((!rv->astr) || +- !TESTAFF(rv->astr, lemma_present, rv->alen))) +- strcat(result, &(rv->word)); +- if (!complexprefixes && rv->description) strcat(result, rv->description); +- if (se->getMorph()) strcat(result, se->getMorph()); +- strcat(result, "\n"); +- rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); +- } +- } +- se = se->getNext(); +- } +- +- // now handle the general case +- unsigned char sp = *((const unsigned char *)(word + len - 1)); +- SfxEntry * sptr = (SfxEntry *) sStart[sp]; +- +- while (sptr) { +- if (isRevSubset(sptr->getKey(), word + len - 1, len) +- ) { +- // suffixes are not allowed in beginning of compounds +- if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass +- // except when signed with compoundpermitflag flag +- (sptr->getCont() && compoundpermitflag && +- TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix || +- // no circumfix flag in prefix and suffix +- ((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) || +- // circumfix flag in prefix AND suffix +- ((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(), +- circumfix, ep->getContLen())) && +- (sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) && +- // fogemorpheme +- (in_compound || +- !((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) && +- // pseudoroot on first suffix +- (cclass || !(sptr->getCont() && +- TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen()))) +- )) rv = sptr->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag); +- while (rv) { +- if (ppfx) { +- if (((PfxEntry *) ppfx)->getMorph()) strcat(result, ((PfxEntry *) ppfx)->getMorph()); +- } +- if (complexprefixes && rv->description) strcat(result, rv->description); +- if (rv->description && ((!rv->astr) || +- !TESTAFF(rv->astr, lemma_present, rv->alen))) strcat(result, &(rv->word)); +- if (!complexprefixes && rv->description) strcat(result, rv->description); +-#ifdef DEBUG +- unsigned short flag = sptr->getFlag(); +- if (flag_mode == FLAG_NUM) { +- sprintf(result, "<%d>", sptr->getKey()); +- } else if (flag_mode == FLAG_LONG) { +- sprintf(result, "<%c%c>", flag >> 8, (flag << 8) >>8); +- } else sprintf(result, "<%c>", flag); +- strcat(result, ":"); +-#endif +- +- if (sptr->getMorph()) strcat(result, sptr->getMorph()); +- strcat(result, "\n"); +- rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); +- } +- sptr = sptr->getNextEQ(); +- } else { +- sptr = sptr->getNextNE(); +- } +- } +- +- if (*result) return mystrdup(result); +- return NULL; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +- +-// check if word with affixes is correctly spelled +-struct hentry * AffixMgr::affix_check (const char * word, int len, const FLAG needflag, char in_compound) +-{ +- struct hentry * rv= NULL; +- if (derived) free(derived); +- derived = NULL; +- +- // check all prefixes (also crossed with suffixes if allowed) +- rv = prefix_check(word, len, in_compound, needflag); +- if (rv) return rv; +- +- // if still not found check all suffixes +- rv = suffix_check(word, len, 0, NULL, NULL, 0, NULL, FLAG_NULL, needflag, in_compound); +- +- if (havecontclass) { +- sfx = NULL; +- pfx = NULL; +- if (rv) return rv; +- // if still not found check all two-level suffixes +- rv = suffix_check_twosfx(word, len, 0, NULL, needflag); +- if (rv) return rv; +- // if still not found check all two-level suffixes +- rv = prefix_check_twosfx(word, len, IN_CPD_NOT, needflag); +- } +- return rv; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// check if word with affixes is correctly spelled +-char * AffixMgr::affix_check_morph(const char * word, int len, const FLAG needflag, char in_compound) +-{ +- char result[MAXLNLEN]; +- char * st = NULL; +- +- *result = '\0'; +- +- // check all prefixes (also crossed with suffixes if allowed) +- st = prefix_check_morph(word, len, in_compound); +- if (st) { +- strcat(result, st); +- free(st); +- } +- +- // if still not found check all suffixes +- st = suffix_check_morph(word, len, 0, NULL, '\0', needflag, in_compound); +- if (st) { +- strcat(result, st); +- free(st); +- } +- +- if (havecontclass) { +- sfx = NULL; +- pfx = NULL; +- // if still not found check all two-level suffixes +- st = suffix_check_twosfx_morph(word, len, 0, NULL, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- } +- +- // if still not found check all two-level suffixes +- st = prefix_check_twosfx_morph(word, len, IN_CPD_NOT, needflag); +- if (st) { +- strcat(result, st); +- free(st); +- } +- } +- +- return mystrdup(result); +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +- +-int AffixMgr::expand_rootword(struct guessword * wlst, int maxn, const char * ts, +- int wl, const unsigned short * ap, unsigned short al, char * bad, int badl, +- char * phone) +-{ +- +- int nh=0; +- // first add root word to list +- if ((nh < maxn) && !(al && ((pseudoroot && TESTAFF(ap, pseudoroot, al)) || +- (onlyincompound && TESTAFF(ap, onlyincompound, al))))) { +- wlst[nh].word = mystrdup(ts); +- wlst[nh].allow = (1 == 0); +- wlst[nh].orig = NULL; +- nh++; +- // add special phonetic version +- if (phone && (nh < maxn)) { +- wlst[nh].word = mystrdup(phone); +- wlst[nh].allow = (1 == 0); +- wlst[nh].orig = mystrdup(ts); +- nh++; +- } +- } +- +- // handle suffixes +- for (int i = 0; i < al; i++) { +- const unsigned char c = (unsigned char) (ap[i] & 0x00FF); +- SfxEntry * sptr = (SfxEntry *)sFlag[c]; +- while (sptr) { +- if ((sptr->getFlag() == ap[i]) && (!sptr->getKeyLen() || ((badl > sptr->getKeyLen()) && +- (strcmp(sptr->getAffix(), bad + badl - sptr->getKeyLen()) == 0))) && +- // check pseudoroot flag +- !(sptr->getCont() && ((pseudoroot && +- TESTAFF(sptr->getCont(), pseudoroot, sptr->getContLen())) || +- (circumfix && +- TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())) || +- (onlyincompound && +- TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen())))) +- ) { +- char * newword = sptr->add(ts, wl); +- if (newword) { +- if (nh < maxn) { +- wlst[nh].word = newword; +- wlst[nh].allow = sptr->allowCross(); +- wlst[nh].orig = NULL; +- nh++; +- // add special phonetic version +- if (phone && (nh < maxn)) { +- char st[MAXWORDUTF8LEN]; +- strcpy(st, phone); +- strcat(st, sptr->getKey()); +- reverseword(st + strlen(phone)); +- wlst[nh].word = mystrdup(st); +- wlst[nh].allow = (1 == 0); +- wlst[nh].orig = mystrdup(newword); +- nh++; +- } +- } else { +- free(newword); +- } +- } +- } +- sptr = (SfxEntry *)sptr ->getFlgNxt(); +- } +- } +- +- int n = nh; +- +- // handle cross products of prefixes and suffixes +- for (int j=1;jgetFlag() == ap[k]) && cptr->allowCross() && (!cptr->getKeyLen() || ((badl > cptr->getKeyLen()) && +- (strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) { +- int l1 = strlen(wlst[j].word); +- char * newword = cptr->add(wlst[j].word, l1); +- if (newword) { +- if (nh < maxn) { +- wlst[nh].word = newword; +- wlst[nh].allow = cptr->allowCross(); +- wlst[nh].orig = NULL; +- nh++; +- } else { +- free(newword); +- } +- } +- } +- cptr = (PfxEntry *)cptr ->getFlgNxt(); +- } +- } +- } +- +- +- // now handle pure prefixes +- for (int m = 0; m < al; m ++) { +- const unsigned char c = (unsigned char) (ap[m] & 0x00FF); +- PfxEntry * ptr = (PfxEntry *) pFlag[c]; +- while (ptr) { +- if ((ptr->getFlag() == ap[m]) && (!ptr->getKeyLen() || ((badl > ptr->getKeyLen()) && +- (strncmp(ptr->getKey(), bad, ptr->getKeyLen()) == 0))) && +- // check pseudoroot flag +- !(ptr->getCont() && ((pseudoroot && +- TESTAFF(ptr->getCont(), pseudoroot, ptr->getContLen())) || +- (circumfix && +- TESTAFF(ptr->getCont(), circumfix, ptr->getContLen())) || +- (onlyincompound && +- TESTAFF(ptr->getCont(), onlyincompound, ptr->getContLen())))) +- ) { +- char * newword = ptr->add(ts, wl); +- if (newword) { +- if (nh < maxn) { +- wlst[nh].word = newword; +- wlst[nh].allow = ptr->allowCross(); +- wlst[nh].orig = NULL; +- nh++; +- } else { +- free(newword); +- } +- } +- } +- ptr = (PfxEntry *)ptr ->getFlgNxt(); +- } +- } +- +- return nh; +-} +- +- +- +-// return length of replacing table +-int AffixMgr::get_numrep() +-{ +- return numrep; +-} +- +-// return replacing table +-struct replentry * AffixMgr::get_reptable() +-{ +- if (! reptable ) return NULL; +- return reptable; +-} +- +-// return replacing table +-struct phonetable * AffixMgr::get_phonetable() +-{ +- if (! phone ) return NULL; +- return phone; +-} +- +-// return length of character map table +-int AffixMgr::get_nummap() +-{ +- return nummap; +-} +- +-// return character map table +-struct mapentry * AffixMgr::get_maptable() +-{ +- if (! maptable ) return NULL; +- return maptable; +-} +- +-// return length of word break table +-int AffixMgr::get_numbreak() +-{ +- return numbreak; +-} +- +-// return character map table +-char ** AffixMgr::get_breaktable() +-{ +- if (! breaktable ) return NULL; +- return breaktable; +-} +- +-// return text encoding of dictionary +-char * AffixMgr::get_encoding() +-{ +- if (! encoding ) { +- encoding = mystrdup("ISO8859-1"); +- } +- return mystrdup(encoding); +-} +- +-// return text encoding of dictionary +-int AffixMgr::get_langnum() +-{ +- return langnum; +-} +- +-// return double prefix option +-int AffixMgr::get_complexprefixes() +-{ +- return complexprefixes; +-} +- +-FLAG AffixMgr::get_keepcase() +-{ +- return keepcase; +-} +- +-int AffixMgr::get_checksharps() +-{ +- return checksharps; +-} +- +-// return the preferred ignore string for suggestions +-char * AffixMgr::get_ignore() +-{ +- if (!ignorechars) return NULL; +- return ignorechars; +-} +- +-// return the preferred ignore string for suggestions +-unsigned short * AffixMgr::get_ignore_utf16(int * len) +-{ +- *len = ignorechars_utf16_len; +- return ignorechars_utf16; +-} +- +-// return the keyboard string for suggestions +-char * AffixMgr::get_key_string() +-{ +- if (! keystring ) return NULL; +- return mystrdup(keystring); +-} +- +-// return the preferred try string for suggestions +-char * AffixMgr::get_try_string() +-{ +- if (! trystring ) return NULL; +- return mystrdup(trystring); +-} +- +-// return the preferred try string for suggestions +-const char * AffixMgr::get_wordchars() +-{ +- return wordchars; +-} +- +-unsigned short * AffixMgr::get_wordchars_utf16(int * len) +-{ +- *len = wordchars_utf16_len; +- return wordchars_utf16; +-} +- +-// is there compounding? +-int AffixMgr::get_compound() +-{ +- return compoundflag || compoundbegin || numdefcpd; +-} +- +-// return the compound words control flag +-FLAG AffixMgr::get_compoundflag() +-{ +- return compoundflag; +-} +- +-// return the forbidden words control flag +-FLAG AffixMgr::get_forbiddenword() +-{ +- return forbiddenword; +-} +- +-// return the forbidden words control flag +-FLAG AffixMgr::get_nosuggest() +-{ +- return nosuggest; +-} +- +-// return the forbidden words flag modify flag +-FLAG AffixMgr::get_pseudoroot() +-{ +- return pseudoroot; +-} +- +-// return the onlyincompound flag +-FLAG AffixMgr::get_onlyincompound() +-{ +- return onlyincompound; +-} +- +-// return the compound word signal flag +-FLAG AffixMgr::get_compoundroot() +-{ +- return compoundroot; +-} +- +-// return the compound begin signal flag +-FLAG AffixMgr::get_compoundbegin() +-{ +- return compoundbegin; +-} +- +-// return the value of checknum +-int AffixMgr::get_checknum() +-{ +- return checknum; +-} +- +-// return the value of prefix +-const char * AffixMgr::get_prefix() +-{ +- if (pfx) return ((PfxEntry *)pfx)->getKey(); +- return NULL; +-} +- +-// return the value of suffix +-const char * AffixMgr::get_suffix() +-{ +- return sfxappnd; +-} +- +-// return the value of derived form (base word with first suffix). +-const char * AffixMgr::get_derived() +-{ +- return derived; +-} +- +-// return the value of suffix +-const char * AffixMgr::get_version() +-{ +- return version; +-} +- +-// return lemma_present flag +-FLAG AffixMgr::get_lemma_present() +-{ +- return lemma_present; +-} +- +-// utility method to look up root words in hash table +-struct hentry * AffixMgr::lookup(const char * word) +-{ +- if (! pHMgr) return NULL; +- return pHMgr->lookup(word); +-} +- +-// return the value of suffix +-const int AffixMgr::have_contclass() +-{ +- return havecontclass; +-} +- +-// return utf8 +-int AffixMgr::get_utf8() +-{ +- return utf8; +-} +- +-// return nosplitsugs +-int AffixMgr::get_maxngramsugs(void) +-{ +- return maxngramsugs; +-} +- +-// return nosplitsugs +-int AffixMgr::get_nosplitsugs(void) +-{ +- return nosplitsugs; +-} +- +-// return sugswithdots +-int AffixMgr::get_sugswithdots(void) +-{ +- return sugswithdots; +-} +- +-/* parse flag */ +-int AffixMgr::parse_flag(char * line, unsigned short * out, const char * name) { +- char * s = NULL; +- if (*out != FLAG_NULL) { +- HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name); +- return 1; +- } +- if (parse_string(line, &s, name)) return 1; +- *out = pHMgr->decode_flag(s); +- free(s); +- return 0; +-} +- +-/* parse num */ +-int AffixMgr::parse_num(char * line, int * out, const char * name) { +- char * s = NULL; +- if (*out != -1) { +- HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name); +- return 1; +- } +- if (parse_string(line, &s, name)) return 1; +- *out = atoi(s); +- free(s); +- return 0; +-} +- +-/* parse in the max syllablecount of compound words and */ +-int AffixMgr::parse_cpdsyllable(char * line) +-{ +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- w_char w[MAXWORDLEN]; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { cpdmaxsyllable = atoi(piece); np++; break; } +- case 2: { +- if (!utf8) { +- cpdvowels = mystrdup(piece); +- } else { +- int n = u8_u16(w, MAXWORDLEN, piece); +- if (n > 0) { +- flag_qsort((unsigned short *) w, 0, n); +- cpdvowels_utf16 = (w_char *) malloc(n * sizeof(w_char)); +- if (!cpdvowels_utf16) return 1; +- memcpy(cpdvowels_utf16, w, n * sizeof(w_char)); +- } +- cpdvowels_utf16_len = n; +- } +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np < 2) { +- HUNSPELL_WARNING(stderr, "error: missing compoundsyllable information\n"); +- return 1; +- } +- if (np == 2) cpdvowels = mystrdup("aeiouAEIOU"); +- return 0; +-} +- +-/* parse in the typical fault correcting table */ +-int AffixMgr::parse_reptable(char * line, FILE * af) +-{ +- if (numrep != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate REP tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numrep = atoi(piece); +- if (numrep < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in replacement table\n"); +- free(piece); +- return 1; +- } +- reptable = (replentry *) malloc(numrep * sizeof(struct replentry)); +- if (!reptable) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing replacement table information\n"); +- return 1; +- } +- +- /* now parse the numrep lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numrep; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- reptable[j].pattern = NULL; +- reptable[j].pattern2 = NULL; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"REP",3) != 0) { +- HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n"); +- numrep = 0; +- free(piece); +- return 1; +- } +- break; +- } +- case 1: { reptable[j].pattern = mystrrep(mystrdup(piece),"_"," "); break; } +- case 2: { reptable[j].pattern2 = mystrrep(mystrdup(piece),"_"," "); break; } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if ((!(reptable[j].pattern)) || (!(reptable[j].pattern2))) { +- HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n"); +- numrep = 0; +- return 1; +- } +- } +- return 0; +-} +- +-/* parse in the typical fault correcting table */ +-int AffixMgr::parse_phonetable(char * line, FILE * af) +-{ +- if (phone) { +- HUNSPELL_WARNING(stderr, "error: duplicate PHONE tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- phone = (phonetable *) malloc(sizeof(struct phonetable)); +- phone->num = atoi(piece); +- phone->rules = NULL; +- phone->utf8 = utf8; +- if (!phone) return 1; +- if (phone->num < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in phonelacement table\n"); +- free(piece); +- return 1; +- } +- phone->rules = (char * *) malloc(2 * (phone->num + 1) * sizeof(char *)); +- if (!phone->rules) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing PHONE table information\n"); +- return 1; +- } +- +- /* now parse the phone->num lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < phone->num; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- phone->rules[j * 2] = NULL; +- phone->rules[j * 2 + 1] = NULL; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"PHONE",5) != 0) { +- HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n"); +- phone->num = 0; +- free(piece); +- return 1; +- } +- break; +- } +- case 1: { phone->rules[j * 2] = mystrrep(mystrdup(piece),"_",""); break; } +- case 2: { phone->rules[j * 2 + 1] = mystrrep(mystrdup(piece),"_",""); break; } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if ((!(phone->rules[j * 2])) || (!(phone->rules[j * 2 + 1]))) { +- HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n"); +- phone->num = 0; +- return 1; +- } +- } +- phone->rules[phone->num * 2] = mystrdup(""); +- phone->rules[phone->num * 2 + 1] = mystrdup(""); +- init_phonet_hash(*phone); +- return 0; +-} +- +-/* parse in the checkcompoundpattern table */ +-int AffixMgr::parse_checkcpdtable(char * line, FILE * af) +-{ +- if (numcheckcpd != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate compound pattern tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numcheckcpd = atoi(piece); +- if (numcheckcpd < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in compound pattern table\n"); +- free(piece); +- return 1; +- } +- checkcpdtable = (replentry *) malloc(numcheckcpd * sizeof(struct replentry)); +- if (!checkcpdtable) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing compound pattern table information\n"); +- return 1; +- } +- +- /* now parse the numcheckcpd lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numcheckcpd; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- checkcpdtable[j].pattern = NULL; +- checkcpdtable[j].pattern2 = NULL; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"CHECKCOMPOUNDPATTERN",20) != 0) { +- HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n"); +- numcheckcpd = 0; +- free(piece); +- return 1; +- } +- break; +- } +- case 1: { checkcpdtable[j].pattern = mystrdup(piece); break; } +- case 2: { checkcpdtable[j].pattern2 = mystrdup(piece); break; } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if ((!(checkcpdtable[j].pattern)) || (!(checkcpdtable[j].pattern2))) { +- HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n"); +- numcheckcpd = 0; +- return 1; +- } +- } +- return 0; +-} +- +-/* parse in the compound rule table */ +-int AffixMgr::parse_defcpdtable(char * line, FILE * af) +-{ +- if (numdefcpd != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate compound rule tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numdefcpd = atoi(piece); +- if (numdefcpd < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in compound rule table\n"); +- free(piece); +- return 1; +- } +- defcpdtable = (flagentry *) malloc(numdefcpd * sizeof(flagentry)); +- if (!defcpdtable) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing compound rule table information\n"); +- return 1; +- } +- +- /* now parse the numdefcpd lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numdefcpd; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- defcpdtable[j].def = NULL; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece, "COMPOUNDRULE", 12) != 0) { +- HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n"); +- free(piece); +- numdefcpd = 0; +- return 1; +- } +- break; +- } +- case 1: { +- defcpdtable[j].len = +- pHMgr->decode_flags(&(defcpdtable[j].def), piece); +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (!defcpdtable[j].len) { +- HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n"); +- numdefcpd = 0; +- return 1; +- } +- } +- return 0; +-} +- +- +-/* parse in the character map table */ +-int AffixMgr::parse_maptable(char * line, FILE * af) +-{ +- if (nummap != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate MAP tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- nummap = atoi(piece); +- if (nummap < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in map table\n"); +- free(piece); +- return 1; +- } +- maptable = (mapentry *) malloc(nummap * sizeof(struct mapentry)); +- if (!maptable) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing map table information\n"); +- return 1; +- } +- +- /* now parse the nummap lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < nummap; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- maptable[j].set = NULL; +- maptable[j].len = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"MAP",3) != 0) { +- HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); +- nummap = 0; +- free(piece); +- return 1; +- } +- break; +- } +- case 1: { +- maptable[j].len = 0; +- maptable[j].set = NULL; +- maptable[j].set_utf16 = NULL; +- if (!utf8) { +- maptable[j].set = mystrdup(piece); +- maptable[j].len = strlen(maptable[j].set); +- } else { +- w_char w[MAXWORDLEN]; +- int n = u8_u16(w, MAXWORDLEN, piece); +- if (n > 0) { +- flag_qsort((unsigned short *) w, 0, n); +- maptable[j].set_utf16 = (w_char *) malloc(n * sizeof(w_char)); +- if (!maptable[j].set_utf16) return 1; +- memcpy(maptable[j].set_utf16, w, n * sizeof(w_char)); +- } +- maptable[j].len = n; +- } +- break; } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if ((!(maptable[j].set || maptable[j].set_utf16)) || (!(maptable[j].len))) { +- HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); +- nummap = 0; +- return 1; +- } +- } +- return 0; +-} +- +-/* parse in the word breakpoint table */ +-int AffixMgr::parse_breaktable(char * line, FILE * af) +-{ +- if (numbreak != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate word breakpoint tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numbreak = atoi(piece); +- if (numbreak < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in BREAK table\n"); +- free(piece); +- return 1; +- } +- breaktable = (char **) malloc(numbreak * sizeof(char *)); +- if (!breaktable) return 1; +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing word breakpoint table information\n"); +- return 1; +- } +- +- /* now parse the numbreak lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numbreak; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"BREAK",5) != 0) { +- HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n"); +- free(piece); +- numbreak = 0; +- return 1; +- } +- break; +- } +- case 1: { +- breaktable[j] = mystrdup(piece); +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (!breaktable) { +- HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n"); +- numbreak = 0; +- return 1; +- } +- } +- return 0; +-} +- +-int AffixMgr::parse_affix(char * line, const char at, FILE * af, char * dupflags) +-{ +- int numents = 0; // number of affentry structures to parse +- +- unsigned short aflag = 0; // affix char identifier +- +- char ff=0; +- struct affentry * ptr= NULL; +- struct affentry * nptr= NULL; +- +- char * tp = line; +- char * nl = line; +- char * piece; +- int i = 0; +- +- // checking lines with bad syntax +-#ifdef DEBUG +- int basefieldnum = 0; +-#endif +- +- // split affix header line into pieces +- +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- // piece 1 - is type of affix +- case 0: { np++; break; } +- +- // piece 2 - is affix char +- case 1: { +- np++; +- aflag = pHMgr->decode_flag(piece); +- if (((at == 'S') && (dupflags[aflag] & dupSFX)) || +- ((at == 'P') && (dupflags[aflag] & dupPFX))) { +- HUNSPELL_WARNING(stderr, "error: duplicate affix flag %s in line %s\n", piece, nl); +- // return 1; XXX permissive mode for bad dictionaries +- } +- dupflags[aflag] += ((at == 'S') ? dupSFX : dupPFX); +- break; +- } +- // piece 3 - is cross product indicator +- case 2: { np++; if (*piece == 'Y') ff = aeXPRODUCT; break; } +- +- // piece 4 - is number of affentries +- case 3: { +- np++; +- numents = atoi(piece); +- if (numents == 0) { +- char * err = pHMgr->encode_flag(aflag); +- HUNSPELL_WARNING(stderr, "error: affix %s header has incorrect entry count in line %s\n", +- err, nl); +- free(err); +- return 1; +- } +- ptr = (struct affentry *) malloc(numents * sizeof(struct affentry)); +- if (!ptr) return 1; +- ptr->opts = ff; +- if (utf8) ptr->opts += aeUTF8; +- if (pHMgr->is_aliasf()) ptr->opts += aeALIASF; +-#ifdef HUNSPELL_EXPERIMENTAL +- if (pHMgr->is_aliasm()) ptr->opts += aeALIASM; +-#endif +- ptr->aflag = aflag; +- } +- +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- // check to make sure we parsed enough pieces +- if (np != 4) { +- char * err = pHMgr->encode_flag(aflag); +- HUNSPELL_WARNING(stderr, "error: affix %s header has insufficient data in line %s\n", err, nl); +- free(err); +- free(ptr); +- return 1; +- } +- +- // store away ptr to first affentry +- nptr = ptr; +- +- // now parse numents affentries for this affix +- for (int j=0; j < numents; j++) { +- if (!fgets(nl,MAXLNLEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- np = 0; +- +- // split line into pieces +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- // piece 1 - is type +- case 0: { +- np++; +- if (nptr != ptr) nptr->opts = ptr->opts; +- break; +- } +- +- // piece 2 - is affix char +- case 1: { +- np++; +- if (pHMgr->decode_flag(piece) != aflag) { +- char * err = pHMgr->encode_flag(aflag); +- HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl); +- HUNSPELL_WARNING(stderr, "error: possible incorrect count\n"); +- free(err); +- free(piece); +- return 1; +- } +- +- if (nptr != ptr) nptr->aflag = ptr->aflag; +- break; +- } +- +- // piece 3 - is string to strip or 0 for null +- case 2: { +- np++; +- if (complexprefixes) { +- if (utf8) reverseword_utf(piece); else reverseword(piece); +- } +- nptr->strip = mystrdup(piece); +- nptr->stripl = (unsigned char) strlen(nptr->strip); +- if (strcmp(nptr->strip,"0") == 0) { +- free(nptr->strip); +- nptr->strip=mystrdup(""); +- nptr->stripl = 0; +- } +- break; +- } +- +- // piece 4 - is affix string or 0 for null +- case 3: { +- char * dash; +-#ifdef HUNSPELL_EXPERIMENTAL +- nptr->morphcode = NULL; +-#endif +- nptr->contclass = NULL; +- nptr->contclasslen = 0; +- np++; +- dash = strchr(piece, '/'); +- if (dash) { +- *dash = '\0'; +- +- if (ignorechars) { +- if (utf8) { +- remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len); +- } else { +- remove_ignored_chars(piece,ignorechars); +- } +- } +- +- if (complexprefixes) { +- if (utf8) reverseword_utf(piece); else reverseword(piece); +- } +- nptr->appnd = mystrdup(piece); +- +- if (pHMgr->is_aliasf()) { +- int index = atoi(dash + 1); +- nptr->contclasslen = (unsigned short) pHMgr->get_aliasf(index, &(nptr->contclass)); +- } else { +- nptr->contclasslen = (unsigned short) pHMgr->decode_flags(&(nptr->contclass), dash + 1); +- flag_qsort(nptr->contclass, 0, nptr->contclasslen); +- } +- *dash = '/'; +- +- havecontclass = 1; +- for (unsigned short _i = 0; _i < nptr->contclasslen; _i++) { +- contclasses[(nptr->contclass)[_i]] = 1; +- } +- } else { +- if (ignorechars) { +- if (utf8) { +- remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len); +- } else { +- remove_ignored_chars(piece,ignorechars); +- } +- } +- +- if (complexprefixes) { +- if (utf8) reverseword_utf(piece); else reverseword(piece); +- } +- nptr->appnd = mystrdup(piece); +- } +- +- nptr->appndl = (unsigned char) strlen(nptr->appnd); +- if (strcmp(nptr->appnd,"0") == 0) { +- free(nptr->appnd); +- nptr->appnd=mystrdup(""); +- nptr->appndl = 0; +- } +- break; +- } +- +- // piece 5 - is the conditions descriptions +- case 4: { +- np++; +- if (complexprefixes) { +- int neg = 0; +- if (utf8) reverseword_utf(piece); else reverseword(piece); +- // reverse condition +- for (char * k = piece + strlen(piece) - 1; k >= piece; k--) { +- switch(*k) { +- case '[': { +- if (neg) *(k+1) = '['; else *k = ']'; +- break; +- } +- case ']': { +- *k = '['; +- if (neg) *(k+1) = '^'; +- neg = 0; +- break; +- } +- case '^': { +- if (*(k+1) == ']') neg = 1; else *(k+1) = *k; +- break; +- } +- default: { +- if (neg) *(k+1) = *k; +- } +- } +- } +- } +- if (nptr->stripl && (strcmp(piece, ".") != 0) && +- redundant_condition(at, nptr->strip, nptr->stripl, piece, nl)) +- strcpy(piece, "."); +- if (encodeit(nptr,piece)) return 1; +- break; +- } +- +-#ifdef HUNSPELL_EXPERIMENTAL +- case 5: { +- np++; +- if (pHMgr->is_aliasm()) { +- int index = atoi(piece); +- nptr->morphcode = pHMgr->get_aliasm(index); +- } else { +- if (complexprefixes) { +- if (utf8) reverseword_utf(piece); else reverseword(piece); +- } +- nptr->morphcode = mystrdup(piece); +- } +- break; +- } +-#endif +- +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- // check to make sure we parsed enough pieces +- if (np < 4) { +- char * err = pHMgr->encode_flag(aflag); +- HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl); +- free(err); +- free(ptr); +- return 1; +- } +- +-#ifdef DEBUG +-#ifdef HUNSPELL_EXPERIMENTAL +- // detect unnecessary fields, excepting comments +- if (basefieldnum) { +- int fieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6); +- if (fieldnum != basefieldnum) +- HUNSPELL_WARNING(stderr, "warning: bad field number:\n%s\n", nl); +- } else { +- basefieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6); +- } +-#endif +-#endif +- nptr++; +- } +- +- // now create SfxEntry or PfxEntry objects and use links to +- // build an ordered (sorted by affix string) list +- nptr = ptr; +- for (int k = 0; k < numents; k++) { +- if (at == 'P') { +- PfxEntry * pfxptr = new PfxEntry(this,nptr); +- build_pfxtree((AffEntry *)pfxptr); +- } else { +- SfxEntry * sfxptr = new SfxEntry(this,nptr); +- build_sfxtree((AffEntry *)sfxptr); +- } +- nptr++; +- } +- free(ptr); +- return 0; +-} +- +-int AffixMgr::redundant_condition(char ft, char * strip, int stripl, const char * cond, char * warnvar) { +- int condl = strlen(cond); +- int i; +- int j; +- int neg; +- int in; +- if (ft == 'P') { // prefix +- if (strncmp(strip, cond, condl) == 0) return 1; +- if (utf8) { +- } else { +- for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) { +- if (cond[j] != '[') { +- if (cond[j] != strip[i]) { +- HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); +- } +- } else { +- neg = (cond[j+1] == '^') ? 1 : 0; +- in = 0; +- do { +- j++; +- if (strip[i] == cond[j]) in = 1; +- } while ((j < (condl - 1)) && (cond[j] != ']')); +- if (j == (condl - 1) && (cond[j] != ']')) { +- HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar); +- return 0; +- } +- if ((!neg && !in) || (neg && in)) { +- HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); +- return 0; +- } +- } +- } +- if (j >= condl) return 1; +- } +- } else { // suffix +- if ((stripl >= condl) && strcmp(strip + stripl - condl, cond) == 0) return 1; +- if (utf8) { +- } else { +- for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) { +- if (cond[j] != ']') { +- if (cond[j] != strip[i]) { +- HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); +- } +- } else { +- in = 0; +- do { +- j--; +- if (strip[i] == cond[j]) in = 1; +- } while ((j > 0) && (cond[j] != '[')); +- if ((j == 0) && (cond[j] != '[')) { +- HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar); +- return 0; +- } +- neg = (cond[j+1] == '^') ? 1 : 0; +- if ((!neg && !in) || (neg && in)) { +- HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar); +- return 0; +- } +- } +- } +- if (j < 0) return 1; +- } +- } +- return 0; +-} +Index: mozilla/extensions/spellcheck/hunspell/src/affixmgr.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/affixmgr.hxx ++++ /dev/null +@@ -1,272 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _AFFIXMGR_HXX_ +-#define _AFFIXMGR_HXX_ +- +-#ifdef MOZILLA_CLIENT +-#ifdef __SUNPRO_CC // for SunONE Studio compiler +-using namespace std; +-#endif +-#include +-#else +-#include +-#endif +- +-#include "atypes.hxx" +-#include "baseaffix.hxx" +-#include "hashmgr.hxx" +-#include "phonet.hxx" +- +-// check flag duplication +-#define dupSFX (1 << 0) +-#define dupPFX (1 << 1) +- +-class AffixMgr +-{ +- +- AffEntry * pStart[SETSIZE]; +- AffEntry * sStart[SETSIZE]; +- AffEntry * pFlag[CONTSIZE]; +- AffEntry * sFlag[CONTSIZE]; +- HashMgr * pHMgr; +- char * keystring; +- char * trystring; +- char * encoding; +- struct cs_info * csconv; +- int utf8; +- int complexprefixes; +- FLAG compoundflag; +- FLAG compoundbegin; +- FLAG compoundmiddle; +- FLAG compoundend; +- FLAG compoundroot; +- FLAG compoundforbidflag; +- FLAG compoundpermitflag; +- int checkcompounddup; +- int checkcompoundrep; +- int checkcompoundcase; +- int checkcompoundtriple; +- FLAG forbiddenword; +- FLAG nosuggest; +- FLAG pseudoroot; +- int cpdmin; +- int numrep; +- replentry * reptable; +- int nummap; +- mapentry * maptable; +- int numbreak; +- char ** breaktable; +- int numcheckcpd; +- replentry * checkcpdtable; +- int numdefcpd; +- flagentry * defcpdtable; +- phonetable * phone; +- int maxngramsugs; +- int nosplitsugs; +- int sugswithdots; +- int cpdwordmax; +- int cpdmaxsyllable; +- char * cpdvowels; +- w_char * cpdvowels_utf16; +- int cpdvowels_utf16_len; +- char * cpdsyllablenum; +- const char * pfxappnd; // BUG: not stateless +- const char * sfxappnd; // BUG: not stateless +- FLAG sfxflag; // BUG: not stateless +- char * derived; // BUG: not stateless +- AffEntry * sfx; // BUG: not stateless +- AffEntry * pfx; // BUG: not stateless +- int checknum; +- char * wordchars; +- unsigned short * wordchars_utf16; +- int wordchars_utf16_len; +- char * ignorechars; +- unsigned short * ignorechars_utf16; +- int ignorechars_utf16_len; +- char * version; +- char * lang; +- int langnum; +- FLAG lemma_present; +- FLAG circumfix; +- FLAG onlyincompound; +- FLAG keepcase; +- int checksharps; +- +- int havecontclass; // boolean variable +- char contclasses[CONTSIZE]; // flags of possible continuing classes (twofold affix) +- flag flag_mode; +- +-public: +- +- AffixMgr(const char * affpath, HashMgr * ptr); +- ~AffixMgr(); +- struct hentry * affix_check(const char * word, int len, +- const unsigned short needflag = (unsigned short) 0, char in_compound = IN_CPD_NOT); +- struct hentry * prefix_check(const char * word, int len, +- char in_compound, const FLAG needflag = FLAG_NULL); +- inline int isSubset(const char * s1, const char * s2); +- struct hentry * prefix_check_twosfx(const char * word, int len, +- char in_compound, const FLAG needflag = FLAG_NULL); +- inline int isRevSubset(const char * s1, const char * end_of_s2, int len); +- struct hentry * suffix_check(const char * word, int len, int sfxopts, AffEntry* ppfx, +- char ** wlst, int maxSug, int * ns, const FLAG cclass = FLAG_NULL, +- const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); +- struct hentry * suffix_check_twosfx(const char * word, int len, +- int sfxopts, AffEntry* ppfx, const FLAG needflag = FLAG_NULL); +- +- char * affix_check_morph(const char * word, int len, +- const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); +- char * prefix_check_morph(const char * word, int len, +- char in_compound, const FLAG needflag = FLAG_NULL); +- char * suffix_check_morph (const char * word, int len, int sfxopts, AffEntry * ppfx, +- const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); +- +- char * prefix_check_twosfx_morph(const char * word, int len, +- char in_compound, const FLAG needflag = FLAG_NULL); +- char * suffix_check_twosfx_morph(const char * word, int len, +- int sfxopts, AffEntry * ppfx, const FLAG needflag = FLAG_NULL); +- +- int expand_rootword(struct guessword * wlst, int maxn, const char * ts, +- int wl, const unsigned short * ap, unsigned short al, char * bad, int, +- char *); +- +- short get_syllable (const char * word, int wlen); +- int cpdrep_check(const char * word, int len); +- int cpdpat_check(const char * word, int len); +- int defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** rwords, char all); +- int cpdcase_check(const char * word, int len); +- inline int candidate_check(const char * word, int len); +- struct hentry * compound_check(const char * word, int len, +- short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, +- char hu_mov_rule, int * cmpdstemnum, int * cmpdstem, char is_sug); +- +- int compound_check_morph(const char * word, int len, +- short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words, +- char hu_mov_rule, char ** result, char * partresult); +- +- struct hentry * lookup(const char * word); +- int get_numrep(); +- struct replentry * get_reptable(); +- struct phonetable * get_phonetable(); +- int get_nummap(); +- struct mapentry * get_maptable(); +- int get_numbreak(); +- char ** get_breaktable(); +- char * get_encoding(); +- int get_langnum(); +- char * get_key_string(); +- char * get_try_string(); +- const char * get_wordchars(); +- unsigned short * get_wordchars_utf16(int * len); +- char * get_ignore(); +- unsigned short * get_ignore_utf16(int * len); +- int get_compound(); +- FLAG get_compoundflag(); +- FLAG get_compoundbegin(); +- FLAG get_forbiddenword(); +- FLAG get_nosuggest(); +-// FLAG get_circumfix(); +- FLAG get_pseudoroot(); +- FLAG get_onlyincompound(); +- FLAG get_compoundroot(); +- FLAG get_lemma_present(); +- int get_checknum(); +- char * get_possible_root(); +- const char * get_prefix(); +- const char * get_suffix(); +- const char * get_derived(); +- const char * get_version(); +- const int have_contclass(); +- int get_utf8(); +- int get_complexprefixes(); +- char * get_suffixed(char ); +- int get_maxngramsugs(); +- int get_nosplitsugs(); +- int get_sugswithdots(void); +- FLAG get_keepcase(void); +- int get_checksharps(void); +- +-private: +- int parse_file(const char * affpath); +-// int parse_string(char * line, char ** out, const char * name); +- int parse_flag(char * line, unsigned short * out, const char * name); +- int parse_num(char * line, int * out, const char * name); +-// int parse_array(char * line, char ** out, unsigned short ** out_utf16, +-// int * out_utf16_len, const char * name); +- int parse_cpdsyllable(char * line); +- int parse_reptable(char * line, FILE * af); +- int parse_phonetable(char * line, FILE * af); +- int parse_maptable(char * line, FILE * af); +- int parse_breaktable(char * line, FILE * af); +- int parse_checkcpdtable(char * line, FILE * af); +- int parse_defcpdtable(char * line, FILE * af); +- int parse_affix(char * line, const char at, FILE * af, char * dupflags); +- +- int encodeit(struct affentry * ptr, char * cs); +- int build_pfxtree(AffEntry* pfxptr); +- int build_sfxtree(AffEntry* sfxptr); +- int process_pfx_order(); +- int process_sfx_order(); +- AffEntry * process_pfx_in_order(AffEntry * ptr, AffEntry * nptr); +- AffEntry * process_sfx_in_order(AffEntry * ptr, AffEntry * nptr); +- int process_pfx_tree_to_list(); +- int process_sfx_tree_to_list(); +- int redundant_condition(char, char * strip, int stripl, const char * cond, char *); +-}; +- +-#endif +- +Index: mozilla/extensions/spellcheck/hunspell/src/atypes.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/atypes.hxx ++++ /dev/null +@@ -1,154 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _ATYPES_HXX_ +-#define _ATYPES_HXX_ +- +-#ifndef HUNSPELL_WARNING +-#ifdef HUNSPELL_WARNING_ON +-#define HUNSPELL_WARNING fprintf +-#else +-// empty inline function to switch off warnings (instead of the C99 standard variadic macros) +-static inline void HUNSPELL_WARNING(FILE *, const char *, ...) {} +-#endif +-#endif +- +-// HUNSTEM def. +-#define HUNSTEM +- +-#include "csutil.hxx" +-#include "hashmgr.hxx" +- +-#define SETSIZE 256 +-#define CONTSIZE 65536 +-#define MAXWORDLEN 100 +-#define MAXWORDUTF8LEN 256 +- +-// affentry options +-#define aeXPRODUCT (1 << 0) +-#define aeUTF8 (1 << 1) +-#define aeALIASF (1 << 2) +-#define aeALIASM (1 << 3) +-#define aeINFIX (1 << 4) +- +-// compound options +-#define IN_CPD_NOT 0 +-#define IN_CPD_BEGIN 1 +-#define IN_CPD_END 2 +-#define IN_CPD_OTHER 3 +- +-#define MAXLNLEN 8192 +- +-#define MINCPDLEN 3 +-#define MAXCOMPOUND 10 +- +-#define MAXACC 1000 +- +-#define FLAG unsigned short +-#define FLAG_NULL 0x00 +-#define FREE_FLAG(a) a = 0 +- +-#define TESTAFF( a, b , c ) flag_bsearch((unsigned short *) a, (unsigned short) b, c) +- +-struct affentry +-{ +- char * strip; +- char * appnd; +- unsigned char stripl; +- unsigned char appndl; +- char numconds; +- char opts; +- unsigned short aflag; +- union { +- char base[SETSIZE]; +- struct { +- char ascii[SETSIZE/2]; +- char neg[8]; +- char all[8]; +- w_char * wchars[8]; +- int wlen[8]; +- } utf8; +- } conds; +-#ifdef HUNSPELL_EXPERIMENTAL +- char * morphcode; +-#endif +- unsigned short * contclass; +- short contclasslen; +-}; +- +-struct mapentry { +- char * set; +- w_char * set_utf16; +- int len; +-}; +- +-struct flagentry { +- FLAG * def; +- int len; +-}; +- +-struct guessword { +- char * word; +- bool allow; +- char * orig; +-}; +- +-#endif +- +- +- +- +- +Index: mozilla/extensions/spellcheck/hunspell/src/baseaffix.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/baseaffix.hxx ++++ /dev/null +@@ -1,87 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _BASEAFF_HXX_ +-#define _BASEAFF_HXX_ +- +-class AffEntry +-{ +-public: +- +-protected: +- char * appnd; +- char * strip; +- unsigned char appndl; +- unsigned char stripl; +- char numconds; +- char opts; +- unsigned short aflag; +- union { +- char base[SETSIZE]; +- struct { +- char ascii[SETSIZE/2]; +- char neg[8]; +- char all[8]; +- w_char * wchars[8]; +- int wlen[8]; +- } utf8; +- } conds; +- char * morphcode; +- unsigned short * contclass; +- short contclasslen; +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/csutil.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/csutil.cpp ++++ /dev/null +@@ -1,5400 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "csutil.hxx" +-#include "atypes.hxx" +-#include "langnum.hxx" +- +-#ifdef OPENOFFICEORG +-# include +-#else +-# ifndef MOZILLA_CLIENT +-# include "utf_info.cxx" +-# define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info))) +-# endif +-#endif +- +-#ifdef MOZILLA_CLIENT +-#include "nsCOMPtr.h" +-#include "nsServiceManagerUtils.h" +-#include "nsIUnicodeEncoder.h" +-#include "nsIUnicodeDecoder.h" +-#include "nsICaseConversion.h" +-#include "nsICharsetConverterManager.h" +-#include "nsUnicharUtilCIID.h" +-#include "nsUnicharUtils.h" +- +-static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); +-static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID); +-#endif +- +-#ifdef MOZILLA_CLIENT +-#ifdef __SUNPRO_CC // for SunONE Studio compiler +-using namespace std; +-#endif +-#else +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +-static struct unicode_info2 * utf_tbl = NULL; +-static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances +- +-/* only UTF-16 (BMP) implementation */ +-char * u16_u8(char * dest, int size, const w_char * src, int srclen) { +- char * u8 = dest; +- char * u8_max = u8 + size; +- const w_char * u2 = src; +- const w_char * u2_max = src + srclen; +- while ((u2 < u2_max) && (u8 < u8_max)) { +- if (u2->h) { // > 0xFF +- // XXX 4-byte haven't implemented yet. +- if (u2->h >= 0x08) { // >= 0x800 (3-byte UTF-8 character) +- *u8 = 0xe0 + (u2->h >> 4); +- u8++; +- if (u8 < u8_max) { +- *u8 = 0x80 + ((u2->h & 0xf) << 2) + (u2->l >> 6); +- u8++; +- if (u8 < u8_max) { +- *u8 = 0x80 + (u2->l & 0x3f); +- u8++; +- } +- } +- } else { // < 0x800 (2-byte UTF-8 character) +- *u8 = 0xc0 + (u2->h << 2) + (u2->l >> 6); +- u8++; +- if (u8 < u8_max) { +- *u8 = 0x80 + (u2->l & 0x3f); +- u8++; +- } +- } +- } else { // <= 0xFF +- if (u2->l & 0x80) { // >0x80 (2-byte UTF-8 character) +- *u8 = 0xc0 + (u2->l >> 6); +- u8++; +- if (u8 < u8_max) { +- *u8 = 0x80 + (u2->l & 0x3f); +- u8++; +- } +- } else { // < 0x80 (1-byte UTF-8 character) +- *u8 = u2->l; +- u8++; +- } +- } +- u2++; +- } +- *u8 = '\0'; +- return dest; +-} +- +- +-/* only UTF-16 (BMP) implementation */ +-int u8_u16(w_char * dest, int size, const char * src) { +- const char * u8 = src; +- w_char * u2 = dest; +- w_char * u2_max = u2 + size; +- +- while ((u2 < u2_max) && *u8) { +- switch ((*u8) & 0xf0) { +- case 0x00: +- case 0x10: +- case 0x20: +- case 0x30: +- case 0x40: +- case 0x50: +- case 0x60: +- case 0x70: { +- u2->h = 0; +- u2->l = *u8; +- break; +- } +- case 0x80: +- case 0x90: +- case 0xa0: +- case 0xb0: { +- HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Unexpected continuation bytes in %d. character position\n%s\n", u8 - src, src); +- u2->h = 0xff; +- u2->l = 0xfd; +- break; +- } +- case 0xc0: +- case 0xd0: { // 2-byte UTF-8 codes +- if ((*(u8+1) & 0xc0) == 0x80) { +- u2->h = (*u8 & 0x1f) >> 2; +- u2->l = (*u8 << 6) + (*(u8+1) & 0x3f); +- u8++; +- } else { +- HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); +- u2->h = 0xff; +- u2->l = 0xfd; +- } +- break; +- } +- case 0xe0: { // 3-byte UTF-8 codes +- if ((*(u8+1) & 0xc0) == 0x80) { +- u2->h = ((*u8 & 0x0f) << 4) + ((*(u8+1) & 0x3f) >> 2); +- u8++; +- if ((*(u8+1) & 0xc0) == 0x80) { +- u2->l = (*u8 << 6) + (*(u8+1) & 0x3f); +- u8++; +- } else { +- HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); +- u2->h = 0xff; +- u2->l = 0xfd; +- } +- } else { +- HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %d. character position:\n%s\n", u8 - src, src); +- u2->h = 0xff; +- u2->l = 0xfd; +- } +- break; +- } +- case 0xf0: { // 4 or more byte UTF-8 codes +- HUNSPELL_WARNING(stderr, "This UTF-8 encoding can't convert to UTF-16:\n%s\n", src); +- u2->h = 0xff; +- u2->l = 0xfd; +- return -1; +- } +- } +- u8++; +- u2++; +- } +- return u2 - dest; +-} +- +-void flag_qsort(unsigned short flags[], int begin, int end) { +- unsigned short reg; +- if (end > begin) { +- unsigned short pivot = flags[begin]; +- int l = begin + 1; +- int r = end; +- while(l < r) { +- if (flags[l] <= pivot) { +- l++; +- } else { +- r--; +- reg = flags[l]; +- flags[l] = flags[r]; +- flags[r] = reg; +- } +- } +- l--; +- reg = flags[begin]; +- flags[begin] = flags[l]; +- flags[l] = reg; +- +- flag_qsort(flags, begin, l); +- flag_qsort(flags, r, end); +- } +- } +- +-int flag_bsearch(unsigned short flags[], unsigned short flag, int length) { +- int mid; +- int left = 0; +- int right = length - 1; +- while (left <= right) { +- mid = (left + right) / 2; +- if (flags[mid] == flag) return 1; +- if (flag < flags[mid]) right = mid - 1; +- else left = mid + 1; +- } +- return 0; +-} +- +- // strip strings into token based on single char delimiter +- // acts like strsep() but only uses a delim char and not +- // a delim string +- // default delimiter: white space characters +- +- char * mystrsep(char ** stringp, const char delim) +- { +- char * rv = NULL; +- char * mp = *stringp; +- int n = strlen(mp); +- if (n > 0) { +- char * dp; +- if (delim) { +- dp = (char *)memchr(mp,(int)((unsigned char)delim),n); +- } else { +- // don't use isspace() here, the string can be in some random charset +- // that's way different than the locale's +- for (dp = mp; (*dp && *dp != ' ' && *dp != '\t'); dp++); +- if (!*dp) dp = NULL; +- } +- if (dp) { +- *stringp = dp+1; +- int nc = (int)((unsigned long)dp - (unsigned long)mp); +- rv = (char *) malloc(nc+1); +- if (rv) { +- memcpy(rv,mp,nc); +- *(rv+nc) = '\0'; +- return rv; +- } +- } else { +- rv = (char *) malloc(n+1); +- if (rv) { +- memcpy(rv, mp, n); +- *(rv+n) = '\0'; +- *stringp = mp + n; +- return rv; +- } +- } +- } +- return NULL; +- } +- +- +- // replaces strdup with ansi version +- char * mystrdup(const char * s) +- { +- char * d = NULL; +- if (s) { +- int sl = strlen(s); +- d = (char *) malloc(((sl+1) * sizeof(char))); +- if (d) memcpy(d,s,((sl+1)*sizeof(char))); +- } +- return d; +- } +- +- +- // remove cross-platform text line end characters +- void mychomp(char * s) +- { +- int k = strlen(s); +- if ((k > 0) && ((*(s+k-1)=='\r') || (*(s+k-1)=='\n'))) *(s+k-1) = '\0'; +- if ((k > 1) && (*(s+k-2) == '\r')) *(s+k-2) = '\0'; +- } +- +- +- // does an ansi strdup of the reverse of a string +- char * myrevstrdup(const char * s) +- { +- char * d = NULL; +- if (s) { +- int sl = strlen(s); +- d = (char *) malloc((sl+1) * sizeof(char)); +- if (d) { +- const char * p = s + sl - 1; +- char * q = d; +- while (p >= s) *q++ = *p--; +- *q = '\0'; +- } +- } +- return d; +- } +- +-#ifdef HUNSPELL_EXPERIMENTAL +- // append s to ends of every lines in text +- void strlinecat(char * dest, const char * s) +- { +- char * dup = mystrdup(dest); +- char * source = dup; +- int len = strlen(s); +- while (*source) { +- if (*source == '\n') { +- strncpy(dest, s, len); +- dest += len; +- } +- *dest = *source; +- source++; dest++; +- } +- strcpy(dest, s); +- free(dup); +- } +- +-// break text to lines +-// return number of lines +-int line_tok(const char * text, char *** lines) { +- int linenum = 0; +- char * dup = mystrdup(text); +- char * p = strchr(dup, '\n'); +- while (p) { +- linenum++; +- *p = '\0'; +- p++; +- p = strchr(p, '\n'); +- } +- *lines = (char **) calloc(linenum + 1, sizeof(char *)); +- if (!(*lines)) return -1; +- +- p = dup; +- for (int i = 0; i < linenum + 1; i++) { +- (*lines)[i] = mystrdup(p); +- p += strlen(p) + 1; +- } +- free(dup); +- return linenum; +-} +- +-// uniq line in place +-char * line_uniq(char * text) { +- char ** lines; +- int linenum = line_tok(text, &lines); +- int i; +- strcpy(text, lines[0]); +- for ( i = 1; i<=linenum; i++ ) { +- int dup = 0; +- for (int j = 0; j < i; j++) { +- if (strcmp(lines[i], lines[j]) == 0) dup = 1; +- } +- if (!dup) { +- if ((i > 1) || (*(lines[0]) != '\0')) strcat(text, "\n"); +- strcat(text, lines[i]); +- } +- } +- for ( i = 0; i<=linenum; i++ ) { +- if (lines[i]) free(lines[i]); +- } +- if (lines) free(lines); +- return text; +-} +- +-// change \n to char c +-char * line_join(char * text, char c) { +- char * p; +- for (p = text; *p; p++) if (*p == '\n') *p = c; +- return text; +-} +- +-// leave only last {[^}]*} substring for handling zero morphemes +-char * delete_zeros(char * morphout) { +- char * p = morphout; +- char * q = p; +- char * q2 = NULL; +- int suffix = 0; +- +- for (;*p && *(p+1);) { +- switch (*p) { +- case '{': +- q2 = q; +- q--; +- break; +- case '}': +- if (q2) { +- suffix = 1; +- q--; +- } +- break; +- default: +- if (suffix) { +- q = q2; +- } +- suffix = 0; +- *q = *p; +- } +- p++; +- q++; +- } +- *q = '\0'; +- return morphout; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +-char * mystrrep(char * word, const char * pat, const char * rep) { +- char * pos = strstr(word, pat); +- if (pos) { +- int replen = strlen(rep); +- int patlen = strlen(pat); +- if (replen < patlen) { +- char * end = word + strlen(word); +- char * next = pos + replen; +- char * prev = pos + strlen(pat); +- for (; prev < end; *next = *prev, prev++, next++); +- *next = '\0'; +- } else if (replen > patlen) { +- char * end = pos + patlen; +- char * next = word + strlen(word) + replen - patlen; +- char * prev = next - replen + patlen; +- for (; prev >= end; *next = *prev, prev--, next--); +- } +- strncpy(pos, rep, replen); +- } +- return word; +-} +- +- // reverse word +- int reverseword(char * word) { +- char r; +- for (char * dest = word + strlen(word) - 1; word < dest; word++, dest--) { +- r=*word; +- *word = *dest; +- *dest = r; +- } +- return 0; +- } +- +- // reverse word (error: 1) +- int reverseword_utf(char * word) { +- w_char w[MAXWORDLEN]; +- w_char * p; +- w_char r; +- int l = u8_u16(w, MAXWORDLEN, word); +- if (l == -1) return 1; +- p = w; +- for (w_char * dest = w + l - 1; p < dest; p++, dest--) { +- r=*p; +- *p = *dest; +- *dest = r; +- } +- u16_u8(word, MAXWORDUTF8LEN, w, l); +- return 0; +- } +- +- // convert null terminated string to all caps +- void mkallcap(char * p, const struct cs_info * csconv) +- { +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].cupper; +- p++; +- } +- } +- +- // convert null terminated string to all little +- void mkallsmall(char * p, const struct cs_info * csconv) +- { +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].clower; +- p++; +- } +- } +- +-void mkallsmall_utf(w_char * u, int nc, int langnum) { +- for (int i = 0; i < nc; i++) { +- unsigned short idx = (u[i].h << 8) + u[i].l; +- if (idx != unicodetolower(idx, langnum)) { +- u[i].h = (unsigned char) (unicodetolower(idx, langnum) >> 8); +- u[i].l = (unsigned char) (unicodetolower(idx, langnum) & 0x00FF); +- } +- } +-} +- +-void mkallcap_utf(w_char * u, int nc, int langnum) { +- for (int i = 0; i < nc; i++) { +- unsigned short idx = (u[i].h << 8) + u[i].l; +- if (idx != unicodetoupper(idx, langnum)) { +- u[i].h = (unsigned char) (unicodetoupper(idx, langnum) >> 8); +- u[i].l = (unsigned char) (unicodetoupper(idx, langnum) & 0x00FF); +- } +- } +-} +- +- // convert null terminated string to have intial capital +- void mkinitcap(char * p, const struct cs_info * csconv) +- { +- if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; +- } +- +-#ifndef MOZILLA_CLIENT +- // convert null terminated string to all caps using encoding +- void enmkallcap(char * d, const char * p, const char * encoding) +- +- { +- struct cs_info * csconv = get_current_cs(encoding); +- while (*p != '\0') { +- *d++ = csconv[((unsigned char) *p)].cupper; +- p++; +- } +- *d = '\0'; +- } +- +- // convert null terminated string to all little using encoding +- void enmkallsmall(char * d, const char * p, const char * encoding) +- { +- struct cs_info * csconv = get_current_cs(encoding); +- while (*p != '\0') { +- *d++ = csconv[((unsigned char) *p)].clower; +- p++; +- } +- *d = '\0'; +- } +- +- // convert null terminated string to have intial capital using encoding +- void enmkinitcap(char * d, const char * p, const char * encoding) +- { +- struct cs_info * csconv = get_current_cs(encoding); +- memcpy(d,p,(strlen(p)+1)); +- if (*p != '\0') *d= csconv[((unsigned char)*p)].cupper; +- } +- +-// these are simple character mappings for the +-// encodings supported +-// supplying isupper, tolower, and toupper +- +-struct cs_info iso1_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +- +-struct cs_info iso2_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xb1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x01, 0xb3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x01, 0xb5, 0xa5 }, +-{ 0x01, 0xb6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x01, 0xb9, 0xa9 }, +-{ 0x01, 0xba, 0xaa }, +-{ 0x01, 0xbb, 0xab }, +-{ 0x01, 0xbc, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x01, 0xbe, 0xae }, +-{ 0x01, 0xbf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xa1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xa3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xa5 }, +-{ 0x00, 0xb6, 0xa6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xa9 }, +-{ 0x00, 0xba, 0xaa }, +-{ 0x00, 0xbb, 0xab }, +-{ 0x00, 0xbc, 0xac }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xae }, +-{ 0x00, 0xbf, 0xaf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +- +-struct cs_info iso3_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xb1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x01, 0xb6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x01, 0x69, 0xa9 }, +-{ 0x01, 0xba, 0xaa }, +-{ 0x01, 0xbb, 0xab }, +-{ 0x01, 0xbc, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x01, 0xbf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xa1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xa6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0x49 }, +-{ 0x00, 0xba, 0xaa }, +-{ 0x00, 0xbb, 0xab }, +-{ 0x00, 0xbc, 0xac }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xaf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x00, 0xc3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x00, 0xd0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xe3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso4_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xb1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x01, 0xb3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x01, 0xb5, 0xa5 }, +-{ 0x01, 0xb6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x01, 0xb9, 0xa9 }, +-{ 0x01, 0xba, 0xaa }, +-{ 0x01, 0xbb, 0xab }, +-{ 0x01, 0xbc, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x01, 0xbe, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xa1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xa3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xa5 }, +-{ 0x00, 0xb6, 0xa6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xa9 }, +-{ 0x00, 0xba, 0xaa }, +-{ 0x00, 0xbb, 0xab }, +-{ 0x00, 0xbc, 0xac }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xae }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso5_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xf1, 0xa1 }, +-{ 0x01, 0xf2, 0xa2 }, +-{ 0x01, 0xf3, 0xa3 }, +-{ 0x01, 0xf4, 0xa4 }, +-{ 0x01, 0xf5, 0xa5 }, +-{ 0x01, 0xf6, 0xa6 }, +-{ 0x01, 0xf7, 0xa7 }, +-{ 0x01, 0xf8, 0xa8 }, +-{ 0x01, 0xf9, 0xa9 }, +-{ 0x01, 0xfa, 0xaa }, +-{ 0x01, 0xfb, 0xab }, +-{ 0x01, 0xfc, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x01, 0xfe, 0xae }, +-{ 0x01, 0xff, 0xaf }, +-{ 0x01, 0xd0, 0xb0 }, +-{ 0x01, 0xd1, 0xb1 }, +-{ 0x01, 0xd2, 0xb2 }, +-{ 0x01, 0xd3, 0xb3 }, +-{ 0x01, 0xd4, 0xb4 }, +-{ 0x01, 0xd5, 0xb5 }, +-{ 0x01, 0xd6, 0xb6 }, +-{ 0x01, 0xd7, 0xb7 }, +-{ 0x01, 0xd8, 0xb8 }, +-{ 0x01, 0xd9, 0xb9 }, +-{ 0x01, 0xda, 0xba }, +-{ 0x01, 0xdb, 0xbb }, +-{ 0x01, 0xdc, 0xbc }, +-{ 0x01, 0xdd, 0xbd }, +-{ 0x01, 0xde, 0xbe }, +-{ 0x01, 0xdf, 0xbf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x00, 0xd0, 0xb0 }, +-{ 0x00, 0xd1, 0xb1 }, +-{ 0x00, 0xd2, 0xb2 }, +-{ 0x00, 0xd3, 0xb3 }, +-{ 0x00, 0xd4, 0xb4 }, +-{ 0x00, 0xd5, 0xb5 }, +-{ 0x00, 0xd6, 0xb6 }, +-{ 0x00, 0xd7, 0xb7 }, +-{ 0x00, 0xd8, 0xb8 }, +-{ 0x00, 0xd9, 0xb9 }, +-{ 0x00, 0xda, 0xba }, +-{ 0x00, 0xdb, 0xbb }, +-{ 0x00, 0xdc, 0xbc }, +-{ 0x00, 0xdd, 0xbd }, +-{ 0x00, 0xde, 0xbe }, +-{ 0x00, 0xdf, 0xbf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xa1 }, +-{ 0x00, 0xf2, 0xa2 }, +-{ 0x00, 0xf3, 0xa3 }, +-{ 0x00, 0xf4, 0xa4 }, +-{ 0x00, 0xf5, 0xa5 }, +-{ 0x00, 0xf6, 0xa6 }, +-{ 0x00, 0xf7, 0xa7 }, +-{ 0x00, 0xf8, 0xa8 }, +-{ 0x00, 0xf9, 0xa9 }, +-{ 0x00, 0xfa, 0xaa }, +-{ 0x00, 0xfb, 0xab }, +-{ 0x00, 0xfc, 0xac }, +-{ 0x00, 0xfd, 0xfd }, +-{ 0x00, 0xfe, 0xae }, +-{ 0x00, 0xff, 0xaf }, +-}; +- +-struct cs_info iso6_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xc0 }, +-{ 0x00, 0xc1, 0xc1 }, +-{ 0x00, 0xc2, 0xc2 }, +-{ 0x00, 0xc3, 0xc3 }, +-{ 0x00, 0xc4, 0xc4 }, +-{ 0x00, 0xc5, 0xc5 }, +-{ 0x00, 0xc6, 0xc6 }, +-{ 0x00, 0xc7, 0xc7 }, +-{ 0x00, 0xc8, 0xc8 }, +-{ 0x00, 0xc9, 0xc9 }, +-{ 0x00, 0xca, 0xca }, +-{ 0x00, 0xcb, 0xcb }, +-{ 0x00, 0xcc, 0xcc }, +-{ 0x00, 0xcd, 0xcd }, +-{ 0x00, 0xce, 0xce }, +-{ 0x00, 0xcf, 0xcf }, +-{ 0x00, 0xd0, 0xd0 }, +-{ 0x00, 0xd1, 0xd1 }, +-{ 0x00, 0xd2, 0xd2 }, +-{ 0x00, 0xd3, 0xd3 }, +-{ 0x00, 0xd4, 0xd4 }, +-{ 0x00, 0xd5, 0xd5 }, +-{ 0x00, 0xd6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x00, 0xd8, 0xd8 }, +-{ 0x00, 0xd9, 0xd9 }, +-{ 0x00, 0xda, 0xda }, +-{ 0x00, 0xdb, 0xdb }, +-{ 0x00, 0xdc, 0xdc }, +-{ 0x00, 0xdd, 0xdd }, +-{ 0x00, 0xde, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xe0 }, +-{ 0x00, 0xe1, 0xe1 }, +-{ 0x00, 0xe2, 0xe2 }, +-{ 0x00, 0xe3, 0xe3 }, +-{ 0x00, 0xe4, 0xe4 }, +-{ 0x00, 0xe5, 0xe5 }, +-{ 0x00, 0xe6, 0xe6 }, +-{ 0x00, 0xe7, 0xe7 }, +-{ 0x00, 0xe8, 0xe8 }, +-{ 0x00, 0xe9, 0xe9 }, +-{ 0x00, 0xea, 0xea }, +-{ 0x00, 0xeb, 0xeb }, +-{ 0x00, 0xec, 0xec }, +-{ 0x00, 0xed, 0xed }, +-{ 0x00, 0xee, 0xee }, +-{ 0x00, 0xef, 0xef }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xf1 }, +-{ 0x00, 0xf2, 0xf2 }, +-{ 0x00, 0xf3, 0xf3 }, +-{ 0x00, 0xf4, 0xf4 }, +-{ 0x00, 0xf5, 0xf5 }, +-{ 0x00, 0xf6, 0xf6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xf8 }, +-{ 0x00, 0xf9, 0xf9 }, +-{ 0x00, 0xfa, 0xfa }, +-{ 0x00, 0xfb, 0xfb }, +-{ 0x00, 0xfc, 0xfc }, +-{ 0x00, 0xfd, 0xfd }, +-{ 0x00, 0xfe, 0xfe }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso7_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x01, 0xdc, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x01, 0xdd, 0xb8 }, +-{ 0x01, 0xde, 0xb9 }, +-{ 0x01, 0xdf, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x01, 0xfc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x01, 0xfd, 0xbe }, +-{ 0x01, 0xfe, 0xbf }, +-{ 0x00, 0xc0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x00, 0xd2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x01, 0xf7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x00, 0xdc, 0xb6 }, +-{ 0x00, 0xdd, 0xb8 }, +-{ 0x00, 0xde, 0xb9 }, +-{ 0x00, 0xdf, 0xba }, +-{ 0x00, 0xe0, 0xe0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd3 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xd7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xbc }, +-{ 0x00, 0xfd, 0xbe }, +-{ 0x00, 0xfe, 0xbf }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso8_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xc0 }, +-{ 0x00, 0xc1, 0xc1 }, +-{ 0x00, 0xc2, 0xc2 }, +-{ 0x00, 0xc3, 0xc3 }, +-{ 0x00, 0xc4, 0xc4 }, +-{ 0x00, 0xc5, 0xc5 }, +-{ 0x00, 0xc6, 0xc6 }, +-{ 0x00, 0xc7, 0xc7 }, +-{ 0x00, 0xc8, 0xc8 }, +-{ 0x00, 0xc9, 0xc9 }, +-{ 0x00, 0xca, 0xca }, +-{ 0x00, 0xcb, 0xcb }, +-{ 0x00, 0xcc, 0xcc }, +-{ 0x00, 0xcd, 0xcd }, +-{ 0x00, 0xce, 0xce }, +-{ 0x00, 0xcf, 0xcf }, +-{ 0x00, 0xd0, 0xd0 }, +-{ 0x00, 0xd1, 0xd1 }, +-{ 0x00, 0xd2, 0xd2 }, +-{ 0x00, 0xd3, 0xd3 }, +-{ 0x00, 0xd4, 0xd4 }, +-{ 0x00, 0xd5, 0xd5 }, +-{ 0x00, 0xd6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x00, 0xd8, 0xd8 }, +-{ 0x00, 0xd9, 0xd9 }, +-{ 0x00, 0xda, 0xda }, +-{ 0x00, 0xdb, 0xdb }, +-{ 0x00, 0xdc, 0xdc }, +-{ 0x00, 0xdd, 0xdd }, +-{ 0x00, 0xde, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xe0 }, +-{ 0x00, 0xe1, 0xe1 }, +-{ 0x00, 0xe2, 0xe2 }, +-{ 0x00, 0xe3, 0xe3 }, +-{ 0x00, 0xe4, 0xe4 }, +-{ 0x00, 0xe5, 0xe5 }, +-{ 0x00, 0xe6, 0xe6 }, +-{ 0x00, 0xe7, 0xe7 }, +-{ 0x00, 0xe8, 0xe8 }, +-{ 0x00, 0xe9, 0xe9 }, +-{ 0x00, 0xea, 0xea }, +-{ 0x00, 0xeb, 0xeb }, +-{ 0x00, 0xec, 0xec }, +-{ 0x00, 0xed, 0xed }, +-{ 0x00, 0xee, 0xee }, +-{ 0x00, 0xef, 0xef }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xf1 }, +-{ 0x00, 0xf2, 0xf2 }, +-{ 0x00, 0xf3, 0xf3 }, +-{ 0x00, 0xf4, 0xf4 }, +-{ 0x00, 0xf5, 0xf5 }, +-{ 0x00, 0xf6, 0xf6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xf8 }, +-{ 0x00, 0xf9, 0xf9 }, +-{ 0x00, 0xfa, 0xfa }, +-{ 0x00, 0xfb, 0xfb }, +-{ 0x00, 0xfc, 0xfc }, +-{ 0x00, 0xfd, 0xfd }, +-{ 0x00, 0xfe, 0xfe }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso9_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0xfd, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0xdd }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0x69, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0x49 }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso10_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xc0 }, +-{ 0x00, 0xc1, 0xc1 }, +-{ 0x00, 0xc2, 0xc2 }, +-{ 0x00, 0xc3, 0xc3 }, +-{ 0x00, 0xc4, 0xc4 }, +-{ 0x00, 0xc5, 0xc5 }, +-{ 0x00, 0xc6, 0xc6 }, +-{ 0x00, 0xc7, 0xc7 }, +-{ 0x00, 0xc8, 0xc8 }, +-{ 0x00, 0xc9, 0xc9 }, +-{ 0x00, 0xca, 0xca }, +-{ 0x00, 0xcb, 0xcb }, +-{ 0x00, 0xcc, 0xcc }, +-{ 0x00, 0xcd, 0xcd }, +-{ 0x00, 0xce, 0xce }, +-{ 0x00, 0xcf, 0xcf }, +-{ 0x00, 0xd0, 0xd0 }, +-{ 0x00, 0xd1, 0xd1 }, +-{ 0x00, 0xd2, 0xd2 }, +-{ 0x00, 0xd3, 0xd3 }, +-{ 0x00, 0xd4, 0xd4 }, +-{ 0x00, 0xd5, 0xd5 }, +-{ 0x00, 0xd6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x00, 0xd8, 0xd8 }, +-{ 0x00, 0xd9, 0xd9 }, +-{ 0x00, 0xda, 0xda }, +-{ 0x00, 0xdb, 0xdb }, +-{ 0x00, 0xdc, 0xdc }, +-{ 0x00, 0xdd, 0xdd }, +-{ 0x00, 0xde, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xe0 }, +-{ 0x00, 0xe1, 0xe1 }, +-{ 0x00, 0xe2, 0xe2 }, +-{ 0x00, 0xe3, 0xe3 }, +-{ 0x00, 0xe4, 0xe4 }, +-{ 0x00, 0xe5, 0xe5 }, +-{ 0x00, 0xe6, 0xe6 }, +-{ 0x00, 0xe7, 0xe7 }, +-{ 0x00, 0xe8, 0xe8 }, +-{ 0x00, 0xe9, 0xe9 }, +-{ 0x00, 0xea, 0xea }, +-{ 0x00, 0xeb, 0xeb }, +-{ 0x00, 0xec, 0xec }, +-{ 0x00, 0xed, 0xed }, +-{ 0x00, 0xee, 0xee }, +-{ 0x00, 0xef, 0xef }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xf1 }, +-{ 0x00, 0xf2, 0xf2 }, +-{ 0x00, 0xf3, 0xf3 }, +-{ 0x00, 0xf4, 0xf4 }, +-{ 0x00, 0xf5, 0xf5 }, +-{ 0x00, 0xf6, 0xf6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xf8 }, +-{ 0x00, 0xf9, 0xf9 }, +-{ 0x00, 0xfa, 0xfa }, +-{ 0x00, 0xfb, 0xfb }, +-{ 0x00, 0xfc, 0xfc }, +-{ 0x00, 0xfd, 0xfd }, +-{ 0x00, 0xfe, 0xfe }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info koi8r_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xb3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x01, 0xa3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xe0 }, +-{ 0x00, 0xc1, 0xe1 }, +-{ 0x00, 0xc2, 0xe2 }, +-{ 0x00, 0xc3, 0xe3 }, +-{ 0x00, 0xc4, 0xe4 }, +-{ 0x00, 0xc5, 0xe5 }, +-{ 0x00, 0xc6, 0xe6 }, +-{ 0x00, 0xc7, 0xe7 }, +-{ 0x00, 0xc8, 0xe8 }, +-{ 0x00, 0xc9, 0xe9 }, +-{ 0x00, 0xca, 0xea }, +-{ 0x00, 0xcb, 0xeb }, +-{ 0x00, 0xcc, 0xec }, +-{ 0x00, 0xcd, 0xed }, +-{ 0x00, 0xce, 0xee }, +-{ 0x00, 0xcf, 0xef }, +-{ 0x00, 0xd0, 0xf0 }, +-{ 0x00, 0xd1, 0xf1 }, +-{ 0x00, 0xd2, 0xf2 }, +-{ 0x00, 0xd3, 0xf3 }, +-{ 0x00, 0xd4, 0xf4 }, +-{ 0x00, 0xd5, 0xf5 }, +-{ 0x00, 0xd6, 0xf6 }, +-{ 0x00, 0xd7, 0xf7 }, +-{ 0x00, 0xd8, 0xf8 }, +-{ 0x00, 0xd9, 0xf9 }, +-{ 0x00, 0xda, 0xfa }, +-{ 0x00, 0xdb, 0xfb }, +-{ 0x00, 0xdc, 0xfc }, +-{ 0x00, 0xdd, 0xfd }, +-{ 0x00, 0xde, 0xfe }, +-{ 0x00, 0xdf, 0xff }, +-{ 0x01, 0xc0, 0xe0 }, +-{ 0x01, 0xc1, 0xe1 }, +-{ 0x01, 0xc2, 0xe2 }, +-{ 0x01, 0xc3, 0xe3 }, +-{ 0x01, 0xc4, 0xe4 }, +-{ 0x01, 0xc5, 0xe5 }, +-{ 0x01, 0xc6, 0xe6 }, +-{ 0x01, 0xc7, 0xe7 }, +-{ 0x01, 0xc8, 0xe8 }, +-{ 0x01, 0xc9, 0xe9 }, +-{ 0x01, 0xca, 0xea }, +-{ 0x01, 0xcb, 0xeb }, +-{ 0x01, 0xcc, 0xec }, +-{ 0x01, 0xcd, 0xed }, +-{ 0x01, 0xce, 0xee }, +-{ 0x01, 0xcf, 0xef }, +-{ 0x01, 0xd0, 0xf0 }, +-{ 0x01, 0xd1, 0xf1 }, +-{ 0x01, 0xd2, 0xf2 }, +-{ 0x01, 0xd3, 0xf3 }, +-{ 0x01, 0xd4, 0xf4 }, +-{ 0x01, 0xd5, 0xf5 }, +-{ 0x01, 0xd6, 0xf6 }, +-{ 0x01, 0xd7, 0xf7 }, +-{ 0x01, 0xd8, 0xf8 }, +-{ 0x01, 0xd9, 0xf9 }, +-{ 0x01, 0xda, 0xfa }, +-{ 0x01, 0xdb, 0xfb }, +-{ 0x01, 0xdc, 0xfc }, +-{ 0x01, 0xdd, 0xfd }, +-{ 0x01, 0xde, 0xfe }, +-{ 0x01, 0xdf, 0xff }, +-}; +- +-struct cs_info koi8u_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xb3 }, +-{ 0x00, 0xa4, 0xb4 }, /* ie */ +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xb6 }, /* i */ +-{ 0x00, 0xa7, 0xb7 }, /* ii */ +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xbd }, /* g'' */ +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x01, 0xa3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, /* IE */ +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, /* I */ +-{ 0x00, 0xb7, 0xb7 }, /* II */ +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xe0 }, +-{ 0x00, 0xc1, 0xe1 }, +-{ 0x00, 0xc2, 0xe2 }, +-{ 0x00, 0xc3, 0xe3 }, +-{ 0x00, 0xc4, 0xe4 }, +-{ 0x00, 0xc5, 0xe5 }, +-{ 0x00, 0xc6, 0xe6 }, +-{ 0x00, 0xc7, 0xe7 }, +-{ 0x00, 0xc8, 0xe8 }, +-{ 0x00, 0xc9, 0xe9 }, +-{ 0x00, 0xca, 0xea }, +-{ 0x00, 0xcb, 0xeb }, +-{ 0x00, 0xcc, 0xec }, +-{ 0x00, 0xcd, 0xed }, +-{ 0x00, 0xce, 0xee }, +-{ 0x00, 0xcf, 0xef }, +-{ 0x00, 0xd0, 0xf0 }, +-{ 0x00, 0xd1, 0xf1 }, +-{ 0x00, 0xd2, 0xf2 }, +-{ 0x00, 0xd3, 0xf3 }, +-{ 0x00, 0xd4, 0xf4 }, +-{ 0x00, 0xd5, 0xf5 }, +-{ 0x00, 0xd6, 0xf6 }, +-{ 0x00, 0xd7, 0xf7 }, +-{ 0x00, 0xd8, 0xf8 }, +-{ 0x00, 0xd9, 0xf9 }, +-{ 0x00, 0xda, 0xfa }, +-{ 0x00, 0xdb, 0xfb }, +-{ 0x00, 0xdc, 0xfc }, +-{ 0x00, 0xdd, 0xfd }, +-{ 0x00, 0xde, 0xfe }, +-{ 0x00, 0xdf, 0xff }, +-{ 0x01, 0xc0, 0xe0 }, +-{ 0x01, 0xc1, 0xe1 }, +-{ 0x01, 0xc2, 0xe2 }, +-{ 0x01, 0xc3, 0xe3 }, +-{ 0x01, 0xc4, 0xe4 }, +-{ 0x01, 0xc5, 0xe5 }, +-{ 0x01, 0xc6, 0xe6 }, +-{ 0x01, 0xc7, 0xe7 }, +-{ 0x01, 0xc8, 0xe8 }, +-{ 0x01, 0xc9, 0xe9 }, +-{ 0x01, 0xca, 0xea }, +-{ 0x01, 0xcb, 0xeb }, +-{ 0x01, 0xcc, 0xec }, +-{ 0x01, 0xcd, 0xed }, +-{ 0x01, 0xce, 0xee }, +-{ 0x01, 0xcf, 0xef }, +-{ 0x01, 0xd0, 0xf0 }, +-{ 0x01, 0xd1, 0xf1 }, +-{ 0x01, 0xd2, 0xf2 }, +-{ 0x01, 0xd3, 0xf3 }, +-{ 0x01, 0xd4, 0xf4 }, +-{ 0x01, 0xd5, 0xf5 }, +-{ 0x01, 0xd6, 0xf6 }, +-{ 0x01, 0xd7, 0xf7 }, +-{ 0x01, 0xd8, 0xf8 }, +-{ 0x01, 0xd9, 0xf9 }, +-{ 0x01, 0xda, 0xfa }, +-{ 0x01, 0xdb, 0xfb }, +-{ 0x01, 0xdc, 0xfc }, +-{ 0x01, 0xdd, 0xfd }, +-{ 0x01, 0xde, 0xfe }, +-{ 0x01, 0xdf, 0xff }, +-}; +- +-struct cs_info cp1251_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x01, 0x90, 0x80 }, +-{ 0x01, 0x83, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x81 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x01, 0x9a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x01, 0x9c, 0x8c }, +-{ 0x01, 0x9d, 0x8d }, +-{ 0x01, 0x9e, 0x8e }, +-{ 0x01, 0x9f, 0x8f }, +-{ 0x00, 0x90, 0x80 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x8a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x8c }, +-{ 0x00, 0x9d, 0x8d }, +-{ 0x00, 0x9e, 0x8e }, +-{ 0x00, 0x9f, 0x8f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xa2, 0xa1 }, +-{ 0x00, 0xa2, 0xa1 }, +-{ 0x01, 0xbc, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x01, 0xb4, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x01, 0xb8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x01, 0xba, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x01, 0xbf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x01, 0xb3, 0xb2 }, +-{ 0x00, 0xb3, 0xb2 }, +-{ 0x00, 0xb4, 0xa5 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xa8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xaa }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xa3 }, +-{ 0x01, 0xbe, 0xbd }, +-{ 0x00, 0xbe, 0xbd }, +-{ 0x00, 0xbf, 0xaf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x01, 0xf7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x01, 0xff, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xd7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xdf }, +-}; +- +-struct cs_info iso13_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0A, 0x0A }, +-{ 0x00, 0x0B, 0x0B }, +-{ 0x00, 0x0C, 0x0C }, +-{ 0x00, 0x0D, 0x0D }, +-{ 0x00, 0x0E, 0x0E }, +-{ 0x00, 0x0F, 0x0F }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1A, 0x1A }, +-{ 0x00, 0x1B, 0x1B }, +-{ 0x00, 0x1C, 0x1C }, +-{ 0x00, 0x1D, 0x1D }, +-{ 0x00, 0x1E, 0x1E }, +-{ 0x00, 0x1F, 0x1F }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2A, 0x2A }, +-{ 0x00, 0x2B, 0x2B }, +-{ 0x00, 0x2C, 0x2C }, +-{ 0x00, 0x2D, 0x2D }, +-{ 0x00, 0x2E, 0x2E }, +-{ 0x00, 0x2F, 0x2F }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3A, 0x3A }, +-{ 0x00, 0x3B, 0x3B }, +-{ 0x00, 0x3C, 0x3C }, +-{ 0x00, 0x3D, 0x3D }, +-{ 0x00, 0x3E, 0x3E }, +-{ 0x00, 0x3F, 0x3F }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6A, 0x4A }, +-{ 0x01, 0x6B, 0x4B }, +-{ 0x01, 0x6C, 0x4C }, +-{ 0x01, 0x6D, 0x4D }, +-{ 0x01, 0x6E, 0x4E }, +-{ 0x01, 0x6F, 0x4F }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7A, 0x5A }, +-{ 0x00, 0x5B, 0x5B }, +-{ 0x00, 0x5C, 0x5C }, +-{ 0x00, 0x5D, 0x5D }, +-{ 0x00, 0x5E, 0x5E }, +-{ 0x00, 0x5F, 0x5F }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6A, 0x4A }, +-{ 0x00, 0x6B, 0x4B }, +-{ 0x00, 0x6C, 0x4C }, +-{ 0x00, 0x6D, 0x4D }, +-{ 0x00, 0x6E, 0x4E }, +-{ 0x00, 0x6F, 0x4F }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7A, 0x5A }, +-{ 0x00, 0x7B, 0x7B }, +-{ 0x00, 0x7C, 0x7C }, +-{ 0x00, 0x7D, 0x7D }, +-{ 0x00, 0x7E, 0x7E }, +-{ 0x00, 0x7F, 0x7F }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8A, 0x8A }, +-{ 0x00, 0x8B, 0x8B }, +-{ 0x00, 0x8C, 0x8C }, +-{ 0x00, 0x8D, 0x8D }, +-{ 0x00, 0x8E, 0x8E }, +-{ 0x00, 0x8F, 0x8F }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9A, 0x9A }, +-{ 0x00, 0x9B, 0x9B }, +-{ 0x00, 0x9C, 0x9C }, +-{ 0x00, 0x9D, 0x9D }, +-{ 0x00, 0x9E, 0x9E }, +-{ 0x00, 0x9F, 0x9F }, +-{ 0x00, 0xA0, 0xA0 }, +-{ 0x00, 0xA1, 0xA1 }, +-{ 0x00, 0xA2, 0xA2 }, +-{ 0x00, 0xA3, 0xA3 }, +-{ 0x00, 0xA4, 0xA4 }, +-{ 0x00, 0xA5, 0xA5 }, +-{ 0x00, 0xA6, 0xA6 }, +-{ 0x00, 0xA7, 0xA7 }, +-{ 0x01, 0xB8, 0xA8 }, +-{ 0x00, 0xA9, 0xA9 }, +-{ 0x01, 0xBA, 0xAA }, +-{ 0x00, 0xAB, 0xAB }, +-{ 0x00, 0xAC, 0xAC }, +-{ 0x00, 0xAD, 0xAD }, +-{ 0x00, 0xAE, 0xAE }, +-{ 0x01, 0xBF, 0xAF }, +-{ 0x00, 0xB0, 0xB0 }, +-{ 0x00, 0xB1, 0xB1 }, +-{ 0x00, 0xB2, 0xB2 }, +-{ 0x00, 0xB3, 0xB3 }, +-{ 0x00, 0xB4, 0xB4 }, +-{ 0x00, 0xB5, 0xB5 }, +-{ 0x00, 0xB6, 0xB6 }, +-{ 0x00, 0xB7, 0xB7 }, +-{ 0x00, 0xB8, 0xA8 }, +-{ 0x00, 0xB9, 0xB9 }, +-{ 0x00, 0xBA, 0xAA }, +-{ 0x00, 0xBB, 0xBB }, +-{ 0x00, 0xBC, 0xBC }, +-{ 0x00, 0xBD, 0xBD }, +-{ 0x00, 0xBE, 0xBE }, +-{ 0x00, 0xBF, 0xAF }, +-{ 0x01, 0xE0, 0xC0 }, +-{ 0x01, 0xE1, 0xC1 }, +-{ 0x01, 0xE2, 0xC2 }, +-{ 0x01, 0xE3, 0xC3 }, +-{ 0x01, 0xE4, 0xC4 }, +-{ 0x01, 0xE5, 0xC5 }, +-{ 0x01, 0xE6, 0xC6 }, +-{ 0x01, 0xE7, 0xC7 }, +-{ 0x01, 0xE8, 0xC8 }, +-{ 0x01, 0xE9, 0xC9 }, +-{ 0x01, 0xEA, 0xCA }, +-{ 0x01, 0xEB, 0xCB }, +-{ 0x01, 0xEC, 0xCC }, +-{ 0x01, 0xED, 0xCD }, +-{ 0x01, 0xEE, 0xCE }, +-{ 0x01, 0xEF, 0xCF }, +-{ 0x01, 0xF0, 0xD0 }, +-{ 0x01, 0xF1, 0xD1 }, +-{ 0x01, 0xF2, 0xD2 }, +-{ 0x01, 0xF3, 0xD3 }, +-{ 0x01, 0xF4, 0xD4 }, +-{ 0x01, 0xF5, 0xD5 }, +-{ 0x01, 0xF6, 0xD6 }, +-{ 0x00, 0xD7, 0xD7 }, +-{ 0x01, 0xF8, 0xD8 }, +-{ 0x01, 0xF9, 0xD9 }, +-{ 0x01, 0xFA, 0xDA }, +-{ 0x01, 0xFB, 0xDB }, +-{ 0x01, 0xFC, 0xDC }, +-{ 0x01, 0xFD, 0xDD }, +-{ 0x01, 0xFE, 0xDE }, +-{ 0x00, 0xDF, 0xDF }, +-{ 0x00, 0xE0, 0xC0 }, +-{ 0x00, 0xE1, 0xC1 }, +-{ 0x00, 0xE2, 0xC2 }, +-{ 0x00, 0xE3, 0xC3 }, +-{ 0x00, 0xE4, 0xC4 }, +-{ 0x00, 0xE5, 0xC5 }, +-{ 0x00, 0xE6, 0xC6 }, +-{ 0x00, 0xE7, 0xC7 }, +-{ 0x00, 0xE8, 0xC8 }, +-{ 0x00, 0xE9, 0xC9 }, +-{ 0x00, 0xEA, 0xCA }, +-{ 0x00, 0xEB, 0xCB }, +-{ 0x00, 0xEC, 0xCC }, +-{ 0x00, 0xED, 0xCD }, +-{ 0x00, 0xEE, 0xCE }, +-{ 0x00, 0xEF, 0xCF }, +-{ 0x00, 0xF0, 0xD0 }, +-{ 0x00, 0xF1, 0xD1 }, +-{ 0x00, 0xF2, 0xD2 }, +-{ 0x00, 0xF3, 0xD3 }, +-{ 0x00, 0xF4, 0xD4 }, +-{ 0x00, 0xF5, 0xD5 }, +-{ 0x00, 0xF6, 0xD6 }, +-{ 0x00, 0xF7, 0xF7 }, +-{ 0x00, 0xF8, 0xD8 }, +-{ 0x00, 0xF9, 0xD9 }, +-{ 0x00, 0xFA, 0xDA }, +-{ 0x00, 0xFB, 0xDB }, +-{ 0x00, 0xFC, 0xDC }, +-{ 0x00, 0xFD, 0xDD }, +-{ 0x00, 0xFE, 0xDE }, +-{ 0x00, 0xFF, 0xFF }, +-}; +- +- +-struct cs_info iso14_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x01, 0xa2, 0xa1 }, +-{ 0x00, 0xa2, 0xa1 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x01, 0xa5, 0xa4 }, +-{ 0x00, 0xa5, 0xa4 }, +-{ 0x01, 0xa6, 0xab }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x01, 0xb8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x01, 0xba, 0xaa }, +-{ 0x00, 0xab, 0xa6 }, +-{ 0x01, 0xbc, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x01, 0xff, 0xaf }, +-{ 0x01, 0xb1, 0xb0 }, +-{ 0x00, 0xb1, 0xb0 }, +-{ 0x01, 0xb3, 0xb2 }, +-{ 0x00, 0xb3, 0xb2 }, +-{ 0x01, 0xb5, 0xb4 }, +-{ 0x00, 0xb5, 0xb4 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x01, 0xb9, 0xb7 }, +-{ 0x00, 0xb8, 0xa8 }, +-{ 0x00, 0xb9, 0xb6 }, +-{ 0x00, 0xba, 0xaa }, +-{ 0x01, 0xbf, 0xbb }, +-{ 0x00, 0xbc, 0xac }, +-{ 0x01, 0xbe, 0xbd }, +-{ 0x00, 0xbe, 0xbd }, +-{ 0x00, 0xbf, 0xbb }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x01, 0xf7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xd7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct cs_info iso15_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x01, 0xa8, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa6 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x01, 0xb8, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb4 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x01, 0xbd, 0xbc }, +-{ 0x00, 0xbd, 0xbc }, +-{ 0x01, 0xff, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x01, 0xe0, 0xc0 }, +-{ 0x01, 0xe1, 0xc1 }, +-{ 0x01, 0xe2, 0xc2 }, +-{ 0x01, 0xe3, 0xc3 }, +-{ 0x01, 0xe4, 0xc4 }, +-{ 0x01, 0xe5, 0xc5 }, +-{ 0x01, 0xe6, 0xc6 }, +-{ 0x01, 0xe7, 0xc7 }, +-{ 0x01, 0xe8, 0xc8 }, +-{ 0x01, 0xe9, 0xc9 }, +-{ 0x01, 0xea, 0xca }, +-{ 0x01, 0xeb, 0xcb }, +-{ 0x01, 0xec, 0xcc }, +-{ 0x01, 0xed, 0xcd }, +-{ 0x01, 0xee, 0xce }, +-{ 0x01, 0xef, 0xcf }, +-{ 0x01, 0xf0, 0xd0 }, +-{ 0x01, 0xf1, 0xd1 }, +-{ 0x01, 0xf2, 0xd2 }, +-{ 0x01, 0xf3, 0xd3 }, +-{ 0x01, 0xf4, 0xd4 }, +-{ 0x01, 0xf5, 0xd5 }, +-{ 0x01, 0xf6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x01, 0xf8, 0xd8 }, +-{ 0x01, 0xf9, 0xd9 }, +-{ 0x01, 0xfa, 0xda }, +-{ 0x01, 0xfb, 0xdb }, +-{ 0x01, 0xfc, 0xdc }, +-{ 0x01, 0xfd, 0xdd }, +-{ 0x01, 0xfe, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xc0 }, +-{ 0x00, 0xe1, 0xc1 }, +-{ 0x00, 0xe2, 0xc2 }, +-{ 0x00, 0xe3, 0xc3 }, +-{ 0x00, 0xe4, 0xc4 }, +-{ 0x00, 0xe5, 0xc5 }, +-{ 0x00, 0xe6, 0xc6 }, +-{ 0x00, 0xe7, 0xc7 }, +-{ 0x00, 0xe8, 0xc8 }, +-{ 0x00, 0xe9, 0xc9 }, +-{ 0x00, 0xea, 0xca }, +-{ 0x00, 0xeb, 0xcb }, +-{ 0x00, 0xec, 0xcc }, +-{ 0x00, 0xed, 0xcd }, +-{ 0x00, 0xee, 0xce }, +-{ 0x00, 0xef, 0xcf }, +-{ 0x00, 0xf0, 0xd0 }, +-{ 0x00, 0xf1, 0xd1 }, +-{ 0x00, 0xf2, 0xd2 }, +-{ 0x00, 0xf3, 0xd3 }, +-{ 0x00, 0xf4, 0xd4 }, +-{ 0x00, 0xf5, 0xd5 }, +-{ 0x00, 0xf6, 0xd6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xd8 }, +-{ 0x00, 0xf9, 0xd9 }, +-{ 0x00, 0xfa, 0xda }, +-{ 0x00, 0xfb, 0xdb }, +-{ 0x00, 0xfc, 0xdc }, +-{ 0x00, 0xfd, 0xdd }, +-{ 0x00, 0xfe, 0xde }, +-{ 0x00, 0xff, 0xbe }, +-}; +- +-struct cs_info iscii_devanagari_tbl[] = { +-{ 0x00, 0x00, 0x00 }, +-{ 0x00, 0x01, 0x01 }, +-{ 0x00, 0x02, 0x02 }, +-{ 0x00, 0x03, 0x03 }, +-{ 0x00, 0x04, 0x04 }, +-{ 0x00, 0x05, 0x05 }, +-{ 0x00, 0x06, 0x06 }, +-{ 0x00, 0x07, 0x07 }, +-{ 0x00, 0x08, 0x08 }, +-{ 0x00, 0x09, 0x09 }, +-{ 0x00, 0x0a, 0x0a }, +-{ 0x00, 0x0b, 0x0b }, +-{ 0x00, 0x0c, 0x0c }, +-{ 0x00, 0x0d, 0x0d }, +-{ 0x00, 0x0e, 0x0e }, +-{ 0x00, 0x0f, 0x0f }, +-{ 0x00, 0x10, 0x10 }, +-{ 0x00, 0x11, 0x11 }, +-{ 0x00, 0x12, 0x12 }, +-{ 0x00, 0x13, 0x13 }, +-{ 0x00, 0x14, 0x14 }, +-{ 0x00, 0x15, 0x15 }, +-{ 0x00, 0x16, 0x16 }, +-{ 0x00, 0x17, 0x17 }, +-{ 0x00, 0x18, 0x18 }, +-{ 0x00, 0x19, 0x19 }, +-{ 0x00, 0x1a, 0x1a }, +-{ 0x00, 0x1b, 0x1b }, +-{ 0x00, 0x1c, 0x1c }, +-{ 0x00, 0x1d, 0x1d }, +-{ 0x00, 0x1e, 0x1e }, +-{ 0x00, 0x1f, 0x1f }, +-{ 0x00, 0x20, 0x20 }, +-{ 0x00, 0x21, 0x21 }, +-{ 0x00, 0x22, 0x22 }, +-{ 0x00, 0x23, 0x23 }, +-{ 0x00, 0x24, 0x24 }, +-{ 0x00, 0x25, 0x25 }, +-{ 0x00, 0x26, 0x26 }, +-{ 0x00, 0x27, 0x27 }, +-{ 0x00, 0x28, 0x28 }, +-{ 0x00, 0x29, 0x29 }, +-{ 0x00, 0x2a, 0x2a }, +-{ 0x00, 0x2b, 0x2b }, +-{ 0x00, 0x2c, 0x2c }, +-{ 0x00, 0x2d, 0x2d }, +-{ 0x00, 0x2e, 0x2e }, +-{ 0x00, 0x2f, 0x2f }, +-{ 0x00, 0x30, 0x30 }, +-{ 0x00, 0x31, 0x31 }, +-{ 0x00, 0x32, 0x32 }, +-{ 0x00, 0x33, 0x33 }, +-{ 0x00, 0x34, 0x34 }, +-{ 0x00, 0x35, 0x35 }, +-{ 0x00, 0x36, 0x36 }, +-{ 0x00, 0x37, 0x37 }, +-{ 0x00, 0x38, 0x38 }, +-{ 0x00, 0x39, 0x39 }, +-{ 0x00, 0x3a, 0x3a }, +-{ 0x00, 0x3b, 0x3b }, +-{ 0x00, 0x3c, 0x3c }, +-{ 0x00, 0x3d, 0x3d }, +-{ 0x00, 0x3e, 0x3e }, +-{ 0x00, 0x3f, 0x3f }, +-{ 0x00, 0x40, 0x40 }, +-{ 0x01, 0x61, 0x41 }, +-{ 0x01, 0x62, 0x42 }, +-{ 0x01, 0x63, 0x43 }, +-{ 0x01, 0x64, 0x44 }, +-{ 0x01, 0x65, 0x45 }, +-{ 0x01, 0x66, 0x46 }, +-{ 0x01, 0x67, 0x47 }, +-{ 0x01, 0x68, 0x48 }, +-{ 0x01, 0x69, 0x49 }, +-{ 0x01, 0x6a, 0x4a }, +-{ 0x01, 0x6b, 0x4b }, +-{ 0x01, 0x6c, 0x4c }, +-{ 0x01, 0x6d, 0x4d }, +-{ 0x01, 0x6e, 0x4e }, +-{ 0x01, 0x6f, 0x4f }, +-{ 0x01, 0x70, 0x50 }, +-{ 0x01, 0x71, 0x51 }, +-{ 0x01, 0x72, 0x52 }, +-{ 0x01, 0x73, 0x53 }, +-{ 0x01, 0x74, 0x54 }, +-{ 0x01, 0x75, 0x55 }, +-{ 0x01, 0x76, 0x56 }, +-{ 0x01, 0x77, 0x57 }, +-{ 0x01, 0x78, 0x58 }, +-{ 0x01, 0x79, 0x59 }, +-{ 0x01, 0x7a, 0x5a }, +-{ 0x00, 0x5b, 0x5b }, +-{ 0x00, 0x5c, 0x5c }, +-{ 0x00, 0x5d, 0x5d }, +-{ 0x00, 0x5e, 0x5e }, +-{ 0x00, 0x5f, 0x5f }, +-{ 0x00, 0x60, 0x60 }, +-{ 0x00, 0x61, 0x41 }, +-{ 0x00, 0x62, 0x42 }, +-{ 0x00, 0x63, 0x43 }, +-{ 0x00, 0x64, 0x44 }, +-{ 0x00, 0x65, 0x45 }, +-{ 0x00, 0x66, 0x46 }, +-{ 0x00, 0x67, 0x47 }, +-{ 0x00, 0x68, 0x48 }, +-{ 0x00, 0x69, 0x49 }, +-{ 0x00, 0x6a, 0x4a }, +-{ 0x00, 0x6b, 0x4b }, +-{ 0x00, 0x6c, 0x4c }, +-{ 0x00, 0x6d, 0x4d }, +-{ 0x00, 0x6e, 0x4e }, +-{ 0x00, 0x6f, 0x4f }, +-{ 0x00, 0x70, 0x50 }, +-{ 0x00, 0x71, 0x51 }, +-{ 0x00, 0x72, 0x52 }, +-{ 0x00, 0x73, 0x53 }, +-{ 0x00, 0x74, 0x54 }, +-{ 0x00, 0x75, 0x55 }, +-{ 0x00, 0x76, 0x56 }, +-{ 0x00, 0x77, 0x57 }, +-{ 0x00, 0x78, 0x58 }, +-{ 0x00, 0x79, 0x59 }, +-{ 0x00, 0x7a, 0x5a }, +-{ 0x00, 0x7b, 0x7b }, +-{ 0x00, 0x7c, 0x7c }, +-{ 0x00, 0x7d, 0x7d }, +-{ 0x00, 0x7e, 0x7e }, +-{ 0x00, 0x7f, 0x7f }, +-{ 0x00, 0x80, 0x80 }, +-{ 0x00, 0x81, 0x81 }, +-{ 0x00, 0x82, 0x82 }, +-{ 0x00, 0x83, 0x83 }, +-{ 0x00, 0x84, 0x84 }, +-{ 0x00, 0x85, 0x85 }, +-{ 0x00, 0x86, 0x86 }, +-{ 0x00, 0x87, 0x87 }, +-{ 0x00, 0x88, 0x88 }, +-{ 0x00, 0x89, 0x89 }, +-{ 0x00, 0x8a, 0x8a }, +-{ 0x00, 0x8b, 0x8b }, +-{ 0x00, 0x8c, 0x8c }, +-{ 0x00, 0x8d, 0x8d }, +-{ 0x00, 0x8e, 0x8e }, +-{ 0x00, 0x8f, 0x8f }, +-{ 0x00, 0x90, 0x90 }, +-{ 0x00, 0x91, 0x91 }, +-{ 0x00, 0x92, 0x92 }, +-{ 0x00, 0x93, 0x93 }, +-{ 0x00, 0x94, 0x94 }, +-{ 0x00, 0x95, 0x95 }, +-{ 0x00, 0x96, 0x96 }, +-{ 0x00, 0x97, 0x97 }, +-{ 0x00, 0x98, 0x98 }, +-{ 0x00, 0x99, 0x99 }, +-{ 0x00, 0x9a, 0x9a }, +-{ 0x00, 0x9b, 0x9b }, +-{ 0x00, 0x9c, 0x9c }, +-{ 0x00, 0x9d, 0x9d }, +-{ 0x00, 0x9e, 0x9e }, +-{ 0x00, 0x9f, 0x9f }, +-{ 0x00, 0xa0, 0xa0 }, +-{ 0x00, 0xa1, 0xa1 }, +-{ 0x00, 0xa2, 0xa2 }, +-{ 0x00, 0xa3, 0xa3 }, +-{ 0x00, 0xa4, 0xa4 }, +-{ 0x00, 0xa5, 0xa5 }, +-{ 0x00, 0xa6, 0xa6 }, +-{ 0x00, 0xa7, 0xa7 }, +-{ 0x00, 0xa8, 0xa8 }, +-{ 0x00, 0xa9, 0xa9 }, +-{ 0x00, 0xaa, 0xaa }, +-{ 0x00, 0xab, 0xab }, +-{ 0x00, 0xac, 0xac }, +-{ 0x00, 0xad, 0xad }, +-{ 0x00, 0xae, 0xae }, +-{ 0x00, 0xaf, 0xaf }, +-{ 0x00, 0xb0, 0xb0 }, +-{ 0x00, 0xb1, 0xb1 }, +-{ 0x00, 0xb2, 0xb2 }, +-{ 0x00, 0xb3, 0xb3 }, +-{ 0x00, 0xb4, 0xb4 }, +-{ 0x00, 0xb5, 0xb5 }, +-{ 0x00, 0xb6, 0xb6 }, +-{ 0x00, 0xb7, 0xb7 }, +-{ 0x00, 0xb8, 0xb8 }, +-{ 0x00, 0xb9, 0xb9 }, +-{ 0x00, 0xba, 0xba }, +-{ 0x00, 0xbb, 0xbb }, +-{ 0x00, 0xbc, 0xbc }, +-{ 0x00, 0xbd, 0xbd }, +-{ 0x00, 0xbe, 0xbe }, +-{ 0x00, 0xbf, 0xbf }, +-{ 0x00, 0xc0, 0xc0 }, +-{ 0x00, 0xc1, 0xc1 }, +-{ 0x00, 0xc2, 0xc2 }, +-{ 0x00, 0xc3, 0xc3 }, +-{ 0x00, 0xc4, 0xc4 }, +-{ 0x00, 0xc5, 0xc5 }, +-{ 0x00, 0xc6, 0xc6 }, +-{ 0x00, 0xc7, 0xc7 }, +-{ 0x00, 0xc8, 0xc8 }, +-{ 0x00, 0xc9, 0xc9 }, +-{ 0x00, 0xca, 0xca }, +-{ 0x00, 0xcb, 0xcb }, +-{ 0x00, 0xcc, 0xcc }, +-{ 0x00, 0xcd, 0xcd }, +-{ 0x00, 0xce, 0xce }, +-{ 0x00, 0xcf, 0xcf }, +-{ 0x00, 0xd0, 0xd0 }, +-{ 0x00, 0xd1, 0xd1 }, +-{ 0x00, 0xd2, 0xd2 }, +-{ 0x00, 0xd3, 0xd3 }, +-{ 0x00, 0xd4, 0xd4 }, +-{ 0x00, 0xd5, 0xd5 }, +-{ 0x00, 0xd6, 0xd6 }, +-{ 0x00, 0xd7, 0xd7 }, +-{ 0x00, 0xd8, 0xd8 }, +-{ 0x00, 0xd9, 0xd9 }, +-{ 0x00, 0xda, 0xda }, +-{ 0x00, 0xdb, 0xdb }, +-{ 0x00, 0xdc, 0xdc }, +-{ 0x00, 0xdd, 0xdd }, +-{ 0x00, 0xde, 0xde }, +-{ 0x00, 0xdf, 0xdf }, +-{ 0x00, 0xe0, 0xe0 }, +-{ 0x00, 0xe1, 0xe1 }, +-{ 0x00, 0xe2, 0xe2 }, +-{ 0x00, 0xe3, 0xe3 }, +-{ 0x00, 0xe4, 0xe4 }, +-{ 0x00, 0xe5, 0xe5 }, +-{ 0x00, 0xe6, 0xe6 }, +-{ 0x00, 0xe7, 0xe7 }, +-{ 0x00, 0xe8, 0xe8 }, +-{ 0x00, 0xe9, 0xe9 }, +-{ 0x00, 0xea, 0xea }, +-{ 0x00, 0xeb, 0xeb }, +-{ 0x00, 0xec, 0xec }, +-{ 0x00, 0xed, 0xed }, +-{ 0x00, 0xee, 0xee }, +-{ 0x00, 0xef, 0xef }, +-{ 0x00, 0xf0, 0xf0 }, +-{ 0x00, 0xf1, 0xf1 }, +-{ 0x00, 0xf2, 0xf2 }, +-{ 0x00, 0xf3, 0xf3 }, +-{ 0x00, 0xf4, 0xf4 }, +-{ 0x00, 0xf5, 0xf5 }, +-{ 0x00, 0xf6, 0xf6 }, +-{ 0x00, 0xf7, 0xf7 }, +-{ 0x00, 0xf8, 0xf8 }, +-{ 0x00, 0xf9, 0xf9 }, +-{ 0x00, 0xfa, 0xfa }, +-{ 0x00, 0xfb, 0xfb }, +-{ 0x00, 0xfc, 0xfc }, +-{ 0x00, 0xfd, 0xfd }, +-{ 0x00, 0xfe, 0xfe }, +-{ 0x00, 0xff, 0xff }, +-}; +- +-struct enc_entry encds[] = { +-{"ISO8859-1",iso1_tbl}, +-{"ISO8859-2",iso2_tbl}, +-{"ISO8859-3",iso3_tbl}, +-{"ISO8859-4",iso4_tbl}, +-{"ISO8859-5",iso5_tbl}, +-{"ISO8859-6",iso6_tbl}, +-{"ISO8859-7",iso7_tbl}, +-{"ISO8859-8",iso8_tbl}, +-{"ISO8859-9",iso9_tbl}, +-{"ISO8859-10",iso10_tbl}, +-{"KOI8-R",koi8r_tbl}, +-{"KOI8-U",koi8u_tbl}, +-{"microsoft-cp1251",cp1251_tbl}, +-{"ISO8859-13", iso13_tbl}, +-{"ISO8859-14", iso14_tbl}, +-{"ISO8859-15", iso15_tbl}, +-{"ISCII-DEVANAGARI", iscii_devanagari_tbl}, +-}; +- +-struct cs_info * get_current_cs(const char * es) { +- struct cs_info * ccs = encds[0].cs_table; +- int n = sizeof(encds) / sizeof(encds[0]); +- for (int i = 0; i < n; i++) { +- if (strcmp(es,encds[i].enc_name) == 0) { +- ccs = encds[i].cs_table; +- } +- } +- return ccs; +-} +-#else +-// XXX This function was rewritten for mozilla. Instead of storing the +-// conversion tables static in this file, create them when needed +-// with help the mozilla backend. +-struct cs_info * get_current_cs(const char * es) { +- struct cs_info *ccs; +- +- nsCOMPtr encoder; +- nsCOMPtr decoder; +- nsCOMPtr caseConv; +- +- nsresult rv; +- nsCOMPtr ccm = do_GetService(kCharsetConverterManagerCID, &rv); +- if (NS_FAILED(rv)) +- return nsnull; +- +- rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder)); +- if (encoder && NS_SUCCEEDED(rv)) +- encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?'); +- if (NS_FAILED(rv)) +- return nsnull; +- rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder)); +- +- caseConv = do_GetService(kUnicharUtilCID, &rv); +- if (NS_FAILED(rv)) +- return nsnull; +- +- ccs = (struct cs_info *) malloc(256 * sizeof(cs_info)); +- +- PRInt32 charLength = 256; +- PRInt32 uniLength = 512; +- char *source = (char *)malloc(charLength * sizeof(char)); +- PRUnichar *uni = (PRUnichar *)malloc(uniLength * sizeof(PRUnichar)); +- char *lower = (char *)malloc(charLength * sizeof(char)); +- char *upper = (char *)malloc(charLength * sizeof(char)); +- +- // Create a long string of all chars. +- unsigned int i; +- for (i = 0x00; i <= 0xff ; ++i) { +- source[i] = i; +- } +- +- // Convert this long string to unicode +- rv = decoder->Convert(source, &charLength, uni, &uniLength); +- +- // Do case conversion stuff, and convert back. +- caseConv->ToUpper(uni, uni, uniLength); +- encoder->Convert(uni, &uniLength, upper, &charLength); +- +- uniLength = 512; +- charLength = 256; +- rv = decoder->Convert(source, &charLength, uni, &uniLength); +- caseConv->ToLower(uni, uni, uniLength); +- encoder->Convert(uni, &uniLength, lower, &charLength); +- +- // Store +- for (i = 0x00; i <= 0xff ; ++i) { +- ccs[i].cupper = upper[i]; +- ccs[i].clower = lower[i]; +- +- if (ccs[i].clower != (unsigned char)i) +- ccs[i].ccase = true; +- else +- ccs[i].ccase = false; +- +- } +- +- free(source); +- free(uni); +- free(lower); +- free(upper); +- +- return ccs; +-} +-#endif +- +-// primitive isalpha() replacement for tokenization +-char * get_casechars(const char * enc) { +- struct cs_info * csconv = get_current_cs(enc); +- char expw[MAXLNLEN]; +- char * p = expw; +- for (int i = 0; i <= 255; i++) { +- if ((csconv[i].cupper != csconv[i].clower)) { +- *p = (char) i; +- p++; +- } +- } +- *p = '\0'; +-#ifdef MOZILLA_CLIENT +- delete csconv; +-#endif +- return mystrdup(expw); +-} +- +- +- +-struct lang_map lang2enc[] = { +-{"ar", "UTF-8", LANG_ar}, +-{"az", "UTF-8", LANG_az}, +-{"bg", "microsoft-cp1251", LANG_bg}, +-{"ca", "ISO8859-1", LANG_ca}, +-{"cs", "ISO8859-2", LANG_cs}, +-{"da", "ISO8859-1", LANG_da}, +-{"de", "ISO8859-1", LANG_de}, +-{"el", "ISO8859-7", LANG_el}, +-{"en", "ISO8859-1", LANG_en}, +-{"es", "ISO8859-1", LANG_es}, +-{"eu", "ISO8859-1", LANG_eu}, +-{"gl", "ISO8859-1", LANG_gl}, +-{"fr", "ISO8859-15", LANG_fr}, +-{"hr", "ISO8859-2", LANG_hr}, +-{"hu", "ISO8859-2", LANG_hu}, +-{"it", "ISO8859-1", LANG_it}, +-{"la", "ISO8859-1", LANG_la}, +-{"lv", "ISO8859-13", LANG_lv}, +-{"nl", "ISO8859-1", LANG_nl}, +-{"pl", "ISO8859-2", LANG_pl}, +-{"pt", "ISO8859-1", LANG_pt}, +-{"sv", "ISO8859-1", LANG_sv}, +-{"tr", "UTF-8", LANG_tr}, +-{"ru", "KOI8-R", LANG_ru}, +-{"uk", "KOI8-U", LANG_uk} +-}; +- +- +-const char * get_default_enc(const char * lang) { +- int n = sizeof(lang2enc) / sizeof(lang2enc[0]); +- for (int i = 0; i < n; i++) { +- if (strcmp(lang,lang2enc[i].lang) == 0) { +- return lang2enc[i].def_enc; +- } +- } +- return NULL; +-} +- +-int get_lang_num(const char * lang) { +- int n = sizeof(lang2enc) / sizeof(lang2enc[0]); +- for (int i = 0; i < n; i++) { +- if (strncmp(lang,lang2enc[i].lang,2) == 0) { +- return lang2enc[i].num; +- } +- } +- return LANG_xx; +-} +- +-#ifndef OPENOFFICEORG +-#ifndef MOZILLA_CLIENT +-int initialize_utf_tbl() { +- utf_tbl_count++; +- if (utf_tbl) return 0; +- utf_tbl = (unicode_info2 *) malloc(CONTSIZE * sizeof(unicode_info2)); +- if (utf_tbl) { +- int j; +- for (j = 0; j < CONTSIZE; j++) { +- utf_tbl[j].cletter = 0; +- utf_tbl[j].clower = (unsigned short) j; +- utf_tbl[j].cupper = (unsigned short) j; +- } +- for (j = 0; j < UTF_LST_LEN; j++) { +- utf_tbl[utf_lst[j].c].cletter = 1; +- utf_tbl[utf_lst[j].c].clower = utf_lst[j].clower; +- utf_tbl[utf_lst[j].c].cupper = utf_lst[j].cupper; +- } +- } else return 1; +- return 0; +-} +-#endif +-#endif +- +-void free_utf_tbl() { +- if (utf_tbl_count > 0) utf_tbl_count--; +- if (utf_tbl && (utf_tbl_count == 0)) { +- free(utf_tbl); +- utf_tbl = NULL; +- } +-} +- +-#ifdef MOZILLA_CLIENT +-static nsCOMPtr& getcaseConv() +-{ +- nsresult rv; +- static nsCOMPtr caseConv = do_GetService(kUnicharUtilCID, &rv); +- return caseConv; +-} +-#endif +- +-unsigned short unicodetoupper(unsigned short c, int langnum) +-{ +- // In Azeri and Turkish, I and i dictinct letters: +- // There are a dotless lower case i pair of upper `I', +- // and an upper I with dot pair of lower `i'. +- if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr))) +- return 0x0130; +-#ifdef OPENOFFICEORG +- return u_toupper(c); +-#else +-#ifdef MOZILLA_CLIENT +- PRUnichar ch2; +- getcaseConv()->ToUpper((PRUnichar) c, &ch2); +- return ch2; +-#else +- return (utf_tbl) ? utf_tbl[c].cupper : c; +-#endif +-#endif +-} +- +-unsigned short unicodetolower(unsigned short c, int langnum) +-{ +- // In Azeri and Turkish, I and i dictinct letters: +- // There are a dotless lower case i pair of upper `I', +- // and an upper I with dot pair of lower `i'. +- if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr))) +- return 0x0131; +-#ifdef OPENOFFICEORG +- return u_tolower(c); +-#else +-#ifdef MOZILLA_CLIENT +- PRUnichar ch2; +- getcaseConv()->ToLower((PRUnichar) c, &ch2); +- return ch2; +-#else +- return (utf_tbl) ? utf_tbl[c].clower : c; +-#endif +-#endif +-} +- +-int unicodeisalpha(unsigned short c) +-{ +-#ifdef OPENOFFICEORG +- return u_isalpha(c); +-#else +- return (utf_tbl) ? utf_tbl[c].cletter : 0; +-#endif +-} +- +-/* get type of capitalization */ +-int get_captype(char * word, int nl, cs_info * csconv) { +- // now determine the capitalization type of the first nl letters +- int ncap = 0; +- int nneutral = 0; +- int firstcap = 0; +- +- for (char * q = word; *q != '\0'; q++) { +- if (csconv[*((unsigned char *)q)].ccase) ncap++; +- if (csconv[*((unsigned char *)q)].cupper == csconv[*((unsigned char *)q)].clower) nneutral++; +- } +- if (ncap) { +- firstcap = csconv[*((unsigned char *) word)].ccase; +- } +- +- // now finally set the captype +- if (ncap == 0) { +- return NOCAP; +- } else if ((ncap == 1) && firstcap) { +- return INITCAP; +- } else if ((ncap == nl) || ((ncap + nneutral) == nl)) { +- return ALLCAP; +- } else if ((ncap > 1) && firstcap) { +- return HUHINITCAP; +- } +- return HUHCAP; +-} +- +-int get_captype_utf8(w_char * word, int nl, int langnum) { +- // now determine the capitalization type of the first nl letters +- int ncap = 0; +- int nneutral = 0; +- int firstcap = 0; +- unsigned short idx; +- // don't check too long words +- if (nl >= MAXWORDLEN) return 0; +- // big Unicode character (non BMP area) +- if (nl == -1) return NOCAP; +- for (int i = 0; i < nl; i++) { +- idx = (word[i].h << 8) + word[i].l; +- if (idx != unicodetolower(idx, langnum)) ncap++; +- if (unicodetoupper(idx, langnum) == unicodetolower(idx, langnum)) nneutral++; +- } +- if (ncap) { +- idx = (word[0].h << 8) + word[0].l; +- firstcap = (idx != unicodetolower(idx, langnum)); +- } +- +- // now finally set the captype +- if (ncap == 0) { +- return NOCAP; +- } else if ((ncap == 1) && firstcap) { +- return INITCAP; +- } else if ((ncap == nl) || ((ncap + nneutral) == nl)) { +- return ALLCAP; +- } else if ((ncap > 1) && firstcap) { +- return HUHINITCAP; +- } +- return HUHCAP; +-} +- +- +-// strip all ignored characters in the string +-void remove_ignored_chars_utf(char * word, unsigned short ignored_chars[], int ignored_len) +-{ +- w_char w[MAXWORDLEN]; +- w_char w2[MAXWORDLEN]; +- int i; +- int j; +- int len = u8_u16(w, MAXWORDLEN, word); +- for (i = 0, j = 0; i < len; i++) { +- if (!flag_bsearch(ignored_chars, ((unsigned short *) w)[i], ignored_len)) { +- w2[j] = w[i]; +- j++; +- } +- } +- if (j < i) u16_u8(word, MAXWORDUTF8LEN, w2, j); +-} +- +-// strip all ignored characters in the string +-void remove_ignored_chars(char * word, char * ignored_chars) +-{ +- for (char * p = word; *p != '\0'; p++) { +- if (!strchr(ignored_chars, *p)) { +- *word = *p; +- word++; +- } +- } +- *word = '\0'; +-} +- +-int parse_string(char * line, char ** out, const char * warnvar) +-{ +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- if (*out) { +- HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", warnvar); +- return 1; +- } +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- *out = mystrdup(piece); +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- HUNSPELL_WARNING(stderr, "error: missing %s information\n", warnvar); +- return 1; +- } +- return 0; +-} +- +-int parse_array(char * line, char ** out, +- unsigned short ** out_utf16, int * out_utf16_len, const char * name, int utf8) { +- if (parse_string(line, out, name)) return 1; +- if (utf8) { +- w_char w[MAXWORDLEN]; +- int n = u8_u16(w, MAXWORDLEN, *out); +- if (n > 0) { +- flag_qsort((unsigned short *) w, 0, n); +- *out_utf16 = (unsigned short *) malloc(n * sizeof(unsigned short)); +- if (!*out_utf16) return 1; +- memcpy(*out_utf16, w, n * sizeof(unsigned short)); +- } +- *out_utf16_len = n; +- } +- return 0; +-} +Index: mozilla/extensions/spellcheck/hunspell/src/csutil.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/csutil.hxx ++++ /dev/null +@@ -1,233 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef __CSUTILHXX__ +-#define __CSUTILHXX__ +- +-// First some base level utility routines +- +-#define NOCAP 0 +-#define INITCAP 1 +-#define ALLCAP 2 +-#define HUHCAP 3 +-#define HUHINITCAP 4 +- +-#define FIELD_STEM "st:" +-#define FIELD_POS "po:" +-#define FIELD_SUFF "su:" +-#define FIELD_PREF "pr:" +-#define FIELD_FREQ "fr:" +-#define FIELD_PHON "ph:" +-#define FIELD_HYPH "hy:" +-#define FIELD_COMP "co:" +- +-// default flags +-#define ONLYUPCASEFLAG 65535 +- +-typedef struct { +- unsigned char l; +- unsigned char h; +-} w_char; +- +-#define w_char_eq(a,b) (((a).l == (b).l) && ((a).h == (b).h)) +- +-// convert UTF-16 characters to UTF-8 +-char * u16_u8(char * dest, int size, const w_char * src, int srclen); +- +-// convert UTF-8 characters to UTF-16 +-int u8_u16(w_char * dest, int size, const char * src); +- +-// sort 2-byte vector +-void flag_qsort(unsigned short flags[], int begin, int end); +- +-// binary search in 2-byte vector +-int flag_bsearch(unsigned short flags[], unsigned short flag, int right); +- +-// remove end of line char(s) +-void mychomp(char * s); +- +-// duplicate string +-char * mystrdup(const char * s); +- +-// duplicate reverse of string +-char * myrevstrdup(const char * s); +- +-// parse into tokens with char delimiter +-char * mystrsep(char ** sptr, const char delim); +-// parse into tokens with char delimiter +-char * mystrsep2(char ** sptr, const char delim); +- +-// parse into tokens with char delimiter +-char * mystrrep(char *, const char *, const char *); +- +-// append s to ends of every lines in text +-void strlinecat(char * lines, const char * s); +- +-// tokenize into lines with new line +- int line_tok(const char * text, char *** lines); +- +-// tokenize into lines with new line and uniq in place +- char * line_uniq(char * text); +- +-// change \n to c in place +- char * line_join(char * text, char c); +- +-// leave only last {[^}]*} pattern in string +- char * delete_zeros(char * morphout); +- +-// reverse word +- int reverseword(char *); +- +-// reverse word +- int reverseword_utf(char *); +- +-// character encoding information +-struct cs_info { +- unsigned char ccase; +- unsigned char clower; +- unsigned char cupper; +-}; +- +-// two character arrays +-struct replentry { +- char * pattern; +- char * pattern2; +-}; +- +-// Unicode character encoding information +-struct unicode_info { +- unsigned short c; +- unsigned short cupper; +- unsigned short clower; +-}; +- +-struct unicode_info2 { +- char cletter; +- unsigned short cupper; +- unsigned short clower; +-}; +- +-int initialize_utf_tbl(); +-void free_utf_tbl(); +-unsigned short unicodetoupper(unsigned short c, int langnum); +-unsigned short unicodetolower(unsigned short c, int langnum); +-int unicodeisalpha(unsigned short c); +- +-struct enc_entry { +- const char * enc_name; +- struct cs_info * cs_table; +-}; +- +-// language to encoding default map +- +-struct lang_map { +- const char * lang; +- const char * def_enc; +- int num; +-}; +- +-struct cs_info * get_current_cs(const char * es); +- +-const char * get_default_enc(const char * lang); +- +-// get language identifiers of language codes +-int get_lang_num(const char * lang); +- +-// get characters of the given 8bit encoding with lower- and uppercase forms +-char * get_casechars(const char * enc); +- +-// convert null terminated string to all caps using encoding +-void enmkallcap(char * d, const char * p, const char * encoding); +- +-// convert null terminated string to all little using encoding +-void enmkallsmall(char * d, const char * p, const char * encoding); +- +-// convert null terminated string to have intial capital using encoding +-void enmkinitcap(char * d, const char * p, const char * encoding); +- +-// convert null terminated string to all caps +-void mkallcap(char * p, const struct cs_info * csconv); +- +-// convert null terminated string to all little +-void mkallsmall(char * p, const struct cs_info * csconv); +- +-// convert null terminated string to have intial capital +-void mkinitcap(char * p, const struct cs_info * csconv); +- +-// convert first nc characters of UTF-8 string to little +-void mkallsmall_utf(w_char * u, int nc, int langnum); +- +-// convert first nc characters of UTF-8 string to capital +-void mkallcap_utf(w_char * u, int nc, int langnum); +- +-// get type of capitalization +-int get_captype(char * q, int nl, cs_info *); +- +-// get type of capitalization (UTF-8) +-int get_captype_utf8(w_char * q, int nl, int langnum); +- +-// strip all ignored characters in the string +-void remove_ignored_chars_utf(char * word, unsigned short ignored_chars[], int ignored_len); +- +-// strip all ignored characters in the string +-void remove_ignored_chars(char * word, char * ignored_chars); +- +-int parse_string(char * line, char ** out, const char * name); +- +-int parse_array(char * line, char ** out, +- unsigned short ** out_utf16, int * out_utf16_len, const char * name, int utf8); +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/hashmgr.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/hashmgr.cpp ++++ /dev/null +@@ -1,941 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "hashmgr.hxx" +-#include "csutil.hxx" +-#include "atypes.hxx" +- +-#ifdef MOZILLA_CLIENT +-#ifdef __SUNPRO_CC // for SunONE Studio compiler +-using namespace std; +-#endif +-#else +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +-// build a hash table from a munched word list +- +-HashMgr::HashMgr(const char * tpath, const char * apath) +-{ +- tablesize = 0; +- tableptr = NULL; +- flag_mode = FLAG_CHAR; +- complexprefixes = 0; +- utf8 = 0; +- langnum = 0; +- lang = NULL; +- enc = NULL; +- csconv = 0; +- ignorechars = NULL; +- ignorechars_utf16 = NULL; +- ignorechars_utf16_len = 0; +- numaliasf = 0; +- aliasf = NULL; +- numaliasm = 0; +- aliasm = NULL; +- forbiddenword = FLAG_NULL; // forbidden word signing flag +- load_config(apath); +- int ec = load_tables(tpath); +- if (ec) { +- /* error condition - what should we do here */ +- HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n",ec); +- if (tableptr) { +- free(tableptr); +- tableptr = NULL; +- } +- tablesize = 0; +- } +-} +- +- +-HashMgr::~HashMgr() +-{ +- if (tableptr) { +- // now pass through hash table freeing up everything +- // go through column by column of the table +- for (int i=0; i < tablesize; i++) { +- struct hentry * pt = tableptr[i]; +- struct hentry * nt = NULL; +-/* if (pt) { +- if (pt->astr && (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen))) free(pt->astr); +-#ifdef HUNSPELL_EXPERIMENTAL +- if (pt->description && !aliasm) free(pt->description); +-#endif +- pt = pt->next; +- } +-*/ +- while(pt) { +- nt = pt->next; +- if (pt->astr && (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen))) free(pt->astr); +-#ifdef HUNSPELL_EXPERIMENTAL +- if (pt->description && !aliasm) free(pt->description); +-#endif +- free(pt); +- pt = nt; +- } +- } +- free(tableptr); +- } +- tablesize = 0; +- +- if (aliasf) { +- for (int j = 0; j < (numaliasf); j++) free(aliasf[j]); +- free(aliasf); +- aliasf = NULL; +- if (aliasflen) { +- free(aliasflen); +- aliasflen = NULL; +- } +- } +- if (aliasm) { +- for (int j = 0; j < (numaliasm); j++) free(aliasm[j]); +- free(aliasm); +- aliasm = NULL; +- } +- +-#ifndef OPENOFFICEORG +-#ifndef MOZILLA_CLIENT +- if (utf8) free_utf_tbl(); +-#endif +-#endif +- +- if (enc) free(enc); +- if (lang) free(lang); +- +- if (ignorechars) free(ignorechars); +- if (ignorechars_utf16) free(ignorechars_utf16); +-} +- +-// lookup a root word in the hashtable +- +-struct hentry * HashMgr::lookup(const char *word) const +-{ +- struct hentry * dp; +- if (tableptr) { +- dp = tableptr[hash(word)]; +- if (!dp) return NULL; +- for ( ; dp != NULL; dp = dp->next) { +- if (strcmp(word,&(dp->word)) == 0) return dp; +- } +- } +- return NULL; +-} +- +-// add a word to the hash table (private) +-int HashMgr::add_word(const char * word, int wbl, int wcl, unsigned short * aff, +- int al, const char * desc, bool onlyupcase) +-{ +- bool upcasehomonym = false; +- int descl = (desc) ? strlen(desc) : 0; +- // variable-length hash record with word and optional fields +- // instead of mmap implementation temporarily +- struct hentry* hp = +- (struct hentry *) malloc (sizeof(struct hentry) + wbl + descl + 1); +- if (!hp) return 1; +- char * hpw = &(hp->word); +- strcpy(hpw, word); +- if (desc && strncmp(desc, FIELD_PHON, strlen(FIELD_PHON)) == 0) { +- strcpy(hpw + wbl + 1, desc + strlen(FIELD_PHON)); +- hp->var = 1; +- } else { +- hp->var = 0; +- } +- if (ignorechars != NULL) { +- if (utf8) { +- remove_ignored_chars_utf(hpw, ignorechars_utf16, ignorechars_utf16_len); +- } else { +- remove_ignored_chars(hpw, ignorechars); +- } +- } +- if (complexprefixes) { +- if (utf8) reverseword_utf(hpw); else reverseword(hpw); +- } +- +- int i = hash(hpw); +- +- hp->blen = (unsigned char) wbl; +- hp->clen = (unsigned char) wcl; +- hp->alen = (short) al; +- hp->astr = aff; +- hp->next = NULL; +- hp->next_homonym = NULL; +-#ifdef HUNSPELL_EXPERIMENTAL +- if (aliasm) { +- hp->description = (desc) ? get_aliasm(atoi(desc)) : mystrdup(desc); +- } else { +- hp->description = mystrdup(desc); +- if (desc && !hp->description) +- { +- free(hp->astr); +- free(hp); +- return 1; +- } +- if (hp->description && complexprefixes) { +- if (utf8) reverseword_utf(hp->description); else reverseword(hp->description); +- } +- } +-#endif +- +- struct hentry * dp = tableptr[i]; +- if (!dp) { +- tableptr[i] = hp; +- return 0; +- } +- while (dp->next != NULL) { +- if ((!dp->next_homonym) && (strcmp(&(hp->word), &(dp->word)) == 0)) { +- // remove hidden onlyupcase homonym +- if (!onlyupcase) { +- if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { +- free(dp->astr); +- dp->astr = hp->astr; +- dp->alen = hp->alen; +- free(hp); +- return 0; +- } else { +- dp->next_homonym = hp; +- } +- } else { +- upcasehomonym = true; +- } +- } +- dp=dp->next; +- } +- if (strcmp(&(hp->word), &(dp->word)) == 0) { +- // remove hidden onlyupcase homonym +- if (!onlyupcase) { +- if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { +- free(dp->astr); +- dp->astr = hp->astr; +- dp->alen = hp->alen; +- free(hp); +- return 0; +- } else { +- dp->next_homonym = hp; +- } +- } else { +- upcasehomonym = true; +- } +- } +- if (!upcasehomonym) { +- dp->next = hp; +- } else { +- // remove hidden onlyupcase homonym +- if (hp->astr) free(hp->astr); +- free(hp); +- } +- return 0; +-} +- +-int HashMgr::add_hidden_capitalized_word(char * word, int wbl, int wcl, +- unsigned short * flags, int al, char * dp, int captype) +-{ +- // add inner capitalized forms to handle the following allcap forms: +- // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG +- // Allcaps with suffixes: CIA's -> CIA'S +- if (((captype == HUHCAP) || (captype == HUHINITCAP) || +- ((captype == ALLCAP) && (flags != NULL))) && +- !((flags != NULL) && TESTAFF(flags, forbiddenword, al))) { +- unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (al+1)); +- if (!flags2) return 1; +- if (al) memcpy(flags2, flags, al * sizeof(unsigned short)); +- flags2[al] = ONLYUPCASEFLAG; +- if (utf8) { +- char st[MAXDELEN]; +- w_char w[MAXDELEN]; +- int wlen = u8_u16(w, MAXDELEN, word); +- mkallsmall_utf(w, wlen, langnum); +- mkallcap_utf(w, 1, langnum); +- u16_u8(st, MAXDELEN, w, wlen); +- return add_word(st,wbl,wcl,flags2,al+1,dp, true); +- } else { +- mkallsmall(word, csconv); +- mkinitcap(word, csconv); +- return add_word(word,wbl,wcl,flags2,al+1,dp, true); +- } +- } +- return 0; +-} +- +-// detect captype and modify word length for UTF-8 encoding +-int HashMgr::get_clen_and_captype(const char * word, int wbl, int * captype) { +- int len; +- if (utf8) { +- w_char dest_utf[MAXDELEN]; +- len = u8_u16(dest_utf, MAXDELEN, word); +- *captype = get_captype_utf8(dest_utf, len, langnum); +- } else { +- len = wbl; +- *captype = get_captype((char *) word, len, csconv); +- } +- return len; +-} +- +-// add a custom dic. word to the hash table (public) +-int HashMgr::put_word(const char * word, char * aff) +-{ +- unsigned short * flags; +- int al = 0; +- if (aff) { +- al = decode_flags(&flags, aff); +- flag_qsort(flags, 0, al); +- } else { +- flags = NULL; +- } +- +- int captype; +- int wbl = strlen(word); +- int wcl = get_clen_and_captype(word, wbl, &captype); +- add_word(word, wbl, wcl, flags, al, NULL, false); +- return add_hidden_capitalized_word((char *) word, wbl, wcl, flags, al, NULL, captype); +-} +- +-int HashMgr::put_word_pattern(const char * word, const char * pattern) +-{ +- // detect captype and modify word length for UTF-8 encoding +- struct hentry * dp = lookup(pattern); +- if (dp && dp->astr) { +- int captype; +- int wbl = strlen(word); +- int wcl = get_clen_and_captype(word, wbl, &captype); +- if (aliasf) { +- add_word(word, wbl, wcl, dp->astr, dp->alen, NULL, false); +- } else { +- unsigned short * flags = (unsigned short *) malloc (dp->alen * sizeof(short)); +- if (flags) { +- memcpy((void *) flags, (void *) dp->astr, dp->alen * sizeof(short)); +- add_word(word, wbl, wcl, flags, dp->alen, NULL, false); +- } else return 1; +- } +- return add_hidden_capitalized_word((char *) word, wbl, wcl, dp->astr, dp->alen, NULL, captype); +- } +- return 1; +-} +- +-// walk the hash table entry by entry - null at end +-// initialize: col=-1; hp = NULL; hp = walk_hashtable(&col, hp); +-struct hentry * HashMgr::walk_hashtable(int &col, struct hentry * hp) const +-{ +- if (hp && hp->next != NULL) return hp->next; +- for (col++; col < tablesize; col++) { +- if (tableptr[col]) return tableptr[col]; +- } +- // null at end and reset to start +- col = -1; +- return NULL; +-} +- +-// load a munched word list and build a hash table on the fly +-int HashMgr::load_tables(const char * tpath) +-{ +- int al; +- char * ap; +- char * dp; +- unsigned short * flags; +- +- // raw dictionary - munched file +- FILE * rawdict = fopen(tpath, "r"); +- if (rawdict == NULL) return 1; +- +- // first read the first line of file to get hash table size */ +- char ts[MAXDELEN]; +- if (! fgets(ts, MAXDELEN-1,rawdict)) { +- HUNSPELL_WARNING(stderr, "error: empty dic file\n"); +- fclose(rawdict); +- return 2; +- } +- mychomp(ts); +- +- /* remove byte order mark */ +- if (strncmp(ts,"\xEF\xBB\xBF",3) == 0) { +- memmove(ts, ts+3, strlen(ts+3)+1); +- HUNSPELL_WARNING(stderr, "warning: dic file begins with byte order mark: possible incompatibility with old Hunspell versions\n"); +- } +- +- if ((*ts < '1') || (*ts > '9')) HUNSPELL_WARNING(stderr, "error - missing word count in dictionary file\n"); +- tablesize = atoi(ts); +- if (!tablesize) { +- fclose(rawdict); +- return 4; +- } +- tablesize = tablesize + 5 + USERWORD; +- if ((tablesize %2) == 0) tablesize++; +- +- // allocate the hash table +- tableptr = (struct hentry **) malloc(tablesize * sizeof(struct hentry *)); +- if (! tableptr) { +- fclose(rawdict); +- return 3; +- } +- for (int i=0; i 1x 2y Zz) +- len = strlen(flags); +- if (len%2 == 1) HUNSPELL_WARNING(stderr, "error: length of FLAG_LONG flagvector is odd: %s\n", flags); +- len /= 2; +- *result = (unsigned short *) malloc(len * sizeof(short)); +- if (!*result) return -1; +- for (int i = 0; i < len; i++) { +- (*result)[i] = (((unsigned short) flags[i * 2]) << 8) + (unsigned short) flags[i * 2 + 1]; +- } +- break; +- } +- case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521 23 233) +- len = 1; +- char * src = flags; +- unsigned short * dest; +- char * p; +- for (p = flags; *p; p++) { +- if (*p == ',') len++; +- } +- *result = (unsigned short *) malloc(len * sizeof(short)); +- if (!*result) return -1; +- dest = *result; +- for (p = flags; *p; p++) { +- if (*p == ',') { +- *dest = (unsigned short) atoi(src); +- if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); +- src = p + 1; +- dest++; +- } +- } +- *dest = (unsigned short) atoi(src); +- if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); +- break; +- } +- case FLAG_UNI: { // UTF-8 characters +- w_char w[MAXDELEN/2]; +- len = u8_u16(w, MAXDELEN/2, flags); +- *result = (unsigned short *) malloc(len * sizeof(short)); +- if (!*result) return -1; +- memcpy(*result, w, len * sizeof(short)); +- break; +- } +- default: { // Ispell's one-character flags (erfg -> e r f g) +- unsigned short * dest; +- len = strlen(flags); +- *result = (unsigned short *) malloc(len * sizeof(short)); +- if (!*result) return -1; +- dest = *result; +- for (unsigned char * p = (unsigned char *) flags; *p; p++) { +- *dest = (unsigned short) *p; +- dest++; +- } +- } +- } +- return len; +-} +- +-unsigned short HashMgr::decode_flag(const char * f) { +- unsigned short s = 0; +- switch (flag_mode) { +- case FLAG_LONG: +- s = ((unsigned short) f[0] << 8) + (unsigned short) f[1]; +- break; +- case FLAG_NUM: +- s = (unsigned short) atoi(f); +- break; +- case FLAG_UNI: +- u8_u16((w_char *) &s, 1, f); +- break; +- default: +- s = (unsigned short) *((unsigned char *)f); +- } +- if (!s) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); +- return s; +-} +- +-char * HashMgr::encode_flag(unsigned short f) { +- unsigned char ch[10]; +- if (f==0) return mystrdup("(NULL)"); +- if (flag_mode == FLAG_LONG) { +- ch[0] = (unsigned char) (f >> 8); +- ch[1] = (unsigned char) (f - ((f >> 8) << 8)); +- ch[2] = '\0'; +- } else if (flag_mode == FLAG_NUM) { +- sprintf((char *) ch, "%d", f); +- } else if (flag_mode == FLAG_UNI) { +- u16_u8((char *) &ch, 10, (w_char *) &f, 1); +- } else { +- ch[0] = (unsigned char) (f); +- ch[1] = '\0'; +- } +- return mystrdup((char *) ch); +-} +- +-// read in aff file and set flag mode +-int HashMgr::load_config(const char * affpath) +-{ +- int firstline = 1; +- +- // io buffers +- char line[MAXDELEN+1]; +- +- // open the affix file +- FILE * afflst; +- afflst = fopen(affpath,"r"); +- if (!afflst) { +- HUNSPELL_WARNING(stderr, "Error - could not open affix description file %s\n",affpath); +- return 1; +- } +- +- // read in each line ignoring any that do not +- // start with a known line type indicator +- +- while (fgets(line,MAXDELEN,afflst)) { +- mychomp(line); +- +- /* remove byte order mark */ +- if (firstline) { +- firstline = 0; +- if (strncmp(line,"\xEF\xBB\xBF",3) == 0) memmove(line, line+3, strlen(line+3)+1); +- } +- +- /* parse in the try string */ +- if ((strncmp(line,"FLAG",4) == 0) && isspace(line[4])) { +- if (flag_mode != FLAG_CHAR) { +- HUNSPELL_WARNING(stderr, "error: duplicate FLAG parameter\n"); +- } +- if (strstr(line, "long")) flag_mode = FLAG_LONG; +- if (strstr(line, "num")) flag_mode = FLAG_NUM; +- if (strstr(line, "UTF-8")) flag_mode = FLAG_UNI; +- if (flag_mode == FLAG_CHAR) { +- HUNSPELL_WARNING(stderr, "error: FLAG need `num', `long' or `UTF-8' parameter: %s\n", line); +- } +- } +- if (strncmp(line,"FORBIDDENWORD",13) == 0) { +- char * st = NULL; +- if (parse_string(line, &st, "FORBIDDENWORD")) { +- fclose(afflst); +- return 1; +- } +- forbiddenword = decode_flag(st); +- free(st); +- } +- if (strncmp(line, "SET", 3) == 0) { +- if (parse_string(line, &enc, "SET")) { +- fclose(afflst); +- return 1; +- } +- if (strcmp(enc, "UTF-8") == 0) { +- utf8 = 1; +-#ifndef OPENOFFICEORG +-#ifndef MOZILLA_CLIENT +- initialize_utf_tbl(); +-#endif +-#endif +- } else csconv = get_current_cs(enc); +- } +- if (strncmp(line, "LANG", 4) == 0) { +- if (parse_string(line, &lang, "LANG")) { +- fclose(afflst); +- return 1; +- } +- langnum = get_lang_num(lang); +- } +- +- /* parse in the ignored characters (for example, Arabic optional diacritics characters */ +- if (strncmp(line,"IGNORE",6) == 0) { +- if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) { +- fclose(afflst); +- return 1; +- } +- } +- +- if ((strncmp(line,"AF",2) == 0) && isspace(line[2])) { +- if (parse_aliasf(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +- +-#ifdef HUNSPELL_EXPERIMENTAL +- if ((strncmp(line,"AM",2) == 0) && isspace(line[2])) { +- if (parse_aliasm(line, afflst)) { +- fclose(afflst); +- return 1; +- } +- } +-#endif +- if (strncmp(line,"COMPLEXPREFIXES",15) == 0) complexprefixes = 1; +- if (((strncmp(line,"SFX",3) == 0) || (strncmp(line,"PFX",3) == 0)) && isspace(line[3])) break; +- } +- if (csconv == NULL) csconv = get_current_cs("ISO8859-1"); +- fclose(afflst); +- return 0; +-} +- +-/* parse in the ALIAS table */ +-int HashMgr::parse_aliasf(char * line, FILE * af) +-{ +- if (numaliasf != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate AF (alias for flag vector) tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numaliasf = atoi(piece); +- if (numaliasf < 1) { +- numaliasf = 0; +- aliasf = NULL; +- aliasflen = NULL; +- HUNSPELL_WARNING(stderr, "incorrect number of entries in AF table\n"); +- free(piece); +- return 1; +- } +- aliasf = (unsigned short **) malloc(numaliasf * sizeof(unsigned short *)); +- aliasflen = (unsigned short *) malloc(numaliasf * sizeof(short)); +- if (!aliasf || !aliasflen) { +- numaliasf = 0; +- if (aliasf) free(aliasf); +- if (aliasflen) free(aliasflen); +- aliasf = NULL; +- aliasflen = NULL; +- return 1; +- } +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- numaliasf = 0; +- free(aliasf); +- free(aliasflen); +- aliasf = NULL; +- aliasflen = NULL; +- HUNSPELL_WARNING(stderr, "error: missing AF table information\n"); +- return 1; +- } +- +- /* now parse the numaliasf lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numaliasf; j++) { +- if (!fgets(nl,MAXDELEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- aliasf[j] = NULL; +- aliasflen[j] = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"AF",2) != 0) { +- numaliasf = 0; +- free(aliasf); +- free(aliasflen); +- aliasf = NULL; +- aliasflen = NULL; +- HUNSPELL_WARNING(stderr, "error: AF table is corrupt\n"); +- free(piece); +- return 1; +- } +- break; +- } +- case 1: { +- aliasflen[j] = (unsigned short) decode_flags(&(aliasf[j]), piece); +- flag_qsort(aliasf[j], 0, aliasflen[j]); +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (!aliasf[j]) { +- free(aliasf); +- free(aliasflen); +- aliasf = NULL; +- aliasflen = NULL; +- numaliasf = 0; +- HUNSPELL_WARNING(stderr, "error: AF table is corrupt\n"); +- return 1; +- } +- } +- return 0; +-} +- +-int HashMgr::is_aliasf() { +- return (aliasf != NULL); +-} +- +-int HashMgr::get_aliasf(int index, unsigned short ** fvec) { +- if ((index > 0) && (index <= numaliasf)) { +- *fvec = aliasf[index - 1]; +- return aliasflen[index - 1]; +- } +- HUNSPELL_WARNING(stderr, "error: bad flag alias index: %d\n", index); +- *fvec = NULL; +- return 0; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-/* parse morph alias definitions */ +-int HashMgr::parse_aliasm(char * line, FILE * af) +-{ +- if (numaliasm != 0) { +- HUNSPELL_WARNING(stderr, "error: duplicate AM (aliases for morphological descriptions) tables used\n"); +- return 1; +- } +- char * tp = line; +- char * piece; +- int i = 0; +- int np = 0; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { np++; break; } +- case 1: { +- numaliasm = atoi(piece); +- if (numaliasm < 1) { +- HUNSPELL_WARNING(stderr, "incorrect number of entries in AM table\n"); +- free(piece); +- return 1; +- } +- aliasm = (char **) malloc(numaliasm * sizeof(char *)); +- if (!aliasm) { +- numaliasm = 0; +- return 1; +- } +- np++; +- break; +- } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (np != 2) { +- numaliasm = 0; +- free(aliasm); +- aliasm = NULL; +- HUNSPELL_WARNING(stderr, "error: missing AM alias information\n"); +- return 1; +- } +- +- /* now parse the numaliasm lines to read in the remainder of the table */ +- char * nl = line; +- for (int j=0; j < numaliasm; j++) { +- if (!fgets(nl,MAXDELEN,af)) return 1; +- mychomp(nl); +- tp = nl; +- i = 0; +- aliasm[j] = NULL; +- piece = mystrsep(&tp, 0); +- while (piece) { +- if (*piece != '\0') { +- switch(i) { +- case 0: { +- if (strncmp(piece,"AM",2) != 0) { +- HUNSPELL_WARNING(stderr, "error: AM table is corrupt\n"); +- free(piece); +- numaliasm = 0; +- free(aliasm); +- aliasm = NULL; +- return 1; +- } +- break; +- } +- case 1: { +- if (complexprefixes) { +- if (utf8) reverseword_utf(piece); +- else reverseword(piece); +- } +- aliasm[j] = mystrdup(piece); +- break; } +- default: break; +- } +- i++; +- } +- free(piece); +- piece = mystrsep(&tp, 0); +- } +- if (!aliasm[j]) { +- numaliasm = 0; +- free(aliasm); +- aliasm = NULL; +- HUNSPELL_WARNING(stderr, "error: map table is corrupt\n"); +- return 1; +- } +- } +- return 0; +-} +- +-int HashMgr::is_aliasm() { +- return (aliasm != NULL); +-} +- +-char * HashMgr::get_aliasm(int index) { +- if ((index > 0) && (index <= numaliasm)) return aliasm[index - 1]; +- HUNSPELL_WARNING(stderr, "error: bad morph. alias index: %d\n", index); +- return NULL; +-} +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/hashmgr.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/hashmgr.hxx ++++ /dev/null +@@ -1,129 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _HASHMGR_HXX_ +-#define _HASHMGR_HXX_ +- +-#ifndef MOZILLA_CLIENT +-#include +-#else +-#include +-#endif +- +-#include "htypes.hxx" +- +-enum flag { FLAG_CHAR, FLAG_LONG, FLAG_NUM, FLAG_UNI }; +- +-class HashMgr +-{ +- int tablesize; +- struct hentry ** tableptr; +- int userword; +- flag flag_mode; +- int complexprefixes; +- int utf8; +- unsigned short forbiddenword; +- int langnum; +- char * enc; +- char * lang; +- struct cs_info * csconv; +- char * ignorechars; +- unsigned short * ignorechars_utf16; +- int ignorechars_utf16_len; +- int numaliasf; // flag vector `compression' with aliases +- unsigned short ** aliasf; +- unsigned short * aliasflen; +- int numaliasm; // morphological desciption `compression' with aliases +- char ** aliasm; +- +- +-public: +- HashMgr(const char * tpath, const char * apath); +- ~HashMgr(); +- +- struct hentry * lookup(const char *) const; +- int hash(const char *) const; +- struct hentry * walk_hashtable(int & col, struct hentry * hp) const; +- +- int put_word(const char * word, char * ap); +- int put_word_pattern(const char * word, const char * pattern); +- int decode_flags(unsigned short ** result, char * flags); +- unsigned short decode_flag(const char * flag); +- char * encode_flag(unsigned short flag); +- int is_aliasf(); +- int get_aliasf(int index, unsigned short ** fvec); +-#ifdef HUNSPELL_EXPERIMENTAL +- int is_aliasm(); +- char * get_aliasm(int index); +-#endif +- +- +-private: +- int get_clen_and_captype(const char * word, int wbl, int * captype); +- int load_tables(const char * tpath); +- int add_word(const char * word, int wbl, int wcl, unsigned short * ap, +- int al, const char * desc, bool onlyupcase); +- int load_config(const char * affpath); +- int parse_aliasf(char * line, FILE * af); +- int add_hidden_capitalized_word(char * word, int wbl, int wcl, +- unsigned short * flags, int al, char * dp, int captype); +-#ifdef HUNSPELL_EXPERIMENTAL +- int parse_aliasm(char * line, FILE * af); +-#endif +- +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/htypes.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/htypes.hxx ++++ /dev/null +@@ -1,85 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _HTYPES_HXX_ +-#define _HTYPES_HXX_ +- +-#define MAXDELEN 8192 +- +-#define ROTATE_LEN 5 +- +-#define ROTATE(v,q) \ +- (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q))-1)); +- +-// approx. number of user defined words +-#define USERWORD 1000 +- +-struct hentry +-{ +- unsigned char blen; // word length in bytes +- unsigned char clen; // word length in characters (different for UTF-8 enc.) +- short alen; // length of affix flag vector +- unsigned short * astr; // affix flag vector +- struct hentry * next; // next word with same hash code +- struct hentry * next_homonym; // next homonym word (with same hash code) +-#ifdef HUNSPELL_EXPERIMENTAL +- char * description; // morphological data (optional) +-#endif +- char var; // variable fields (only for special pronounciation yet) +- char word; // variable-length word (8-bit or UTF-8 encoding) +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/hunspell.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/hunspell.cpp ++++ /dev/null +@@ -1,1807 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#endif +- +-#include "hunspell.hxx" +-#include "hunspell.h" +- +-#ifndef MOZILLA_CLIENT +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +-Hunspell::Hunspell(const char * affpath, const char * dpath) +-{ +- encoding = NULL; +- csconv = NULL; +- utf8 = 0; +- complexprefixes = 0; +- +- /* first set up the hash manager */ +- pHMgr = new HashMgr(dpath, affpath); +- +- /* next set up the affix manager */ +- /* it needs access to the hash manager lookup methods */ +- pAMgr = new AffixMgr(affpath,pHMgr); +- +- /* get the preferred try string and the dictionary */ +- /* encoding from the Affix Manager for that dictionary */ +- char * try_string = pAMgr->get_try_string(); +- encoding = pAMgr->get_encoding(); +- csconv = get_current_cs(encoding); +- langnum = pAMgr->get_langnum(); +- utf8 = pAMgr->get_utf8(); +- complexprefixes = pAMgr->get_complexprefixes(); +- wordbreak = pAMgr->get_breaktable(); +- +- /* and finally set up the suggestion manager */ +- pSMgr = new SuggestMgr(try_string, MAXSUGGESTION, pAMgr); +- if (try_string) free(try_string); +- +-} +- +-Hunspell::~Hunspell() +-{ +- if (pSMgr) delete pSMgr; +- if (pAMgr) delete pAMgr; +- if (pHMgr) delete pHMgr; +- pSMgr = NULL; +- pAMgr = NULL; +- pHMgr = NULL; +-#ifdef MOZILLA_CLIENT +- free(csconv); +-#endif +- csconv= NULL; +- if (encoding) free(encoding); +- encoding = NULL; +-} +- +- +-// make a copy of src at destination while removing all leading +-// blanks and removing any trailing periods after recording +-// their presence with the abbreviation flag +-// also since already going through character by character, +-// set the capitalization type +-// return the length of the "cleaned" (and UTF-8 encoded) word +- +-int Hunspell::cleanword2(char * dest, const char * src, +- w_char * dest_utf, int * nc, int * pcaptype, int * pabbrev) +-{ +- unsigned char * p = (unsigned char *) dest; +- const unsigned char * q = (const unsigned char * ) src; +- +- // first skip over any leading blanks +- while ((*q != '\0') && (*q == ' ')) q++; +- +- // now strip off any trailing periods (recording their presence) +- *pabbrev = 0; +- int nl = strlen((const char *)q); +- while ((nl > 0) && (*(q+nl-1)=='.')) { +- nl--; +- (*pabbrev)++; +- } +- +- // if no characters are left it can't be capitalized +- if (nl <= 0) { +- *pcaptype = NOCAP; +- *p = '\0'; +- return 0; +- } +- +- strncpy(dest, (char *) q, nl); +- *(dest + nl) = '\0'; +- nl = strlen(dest); +- if (utf8) { +- *nc = u8_u16(dest_utf, MAXWORDLEN, dest); +- // don't check too long words +- if (*nc >= MAXWORDLEN) return 0; +- if (*nc == -1) { // big Unicode character (non BMP area) +- *pcaptype = NOCAP; +- return nl; +- } +- *pcaptype = get_captype_utf8(dest_utf, *nc, langnum); +- } else { +- *pcaptype = get_captype(dest, nl, csconv); +- *nc = nl; +- } +- return nl; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-int Hunspell::cleanword(char * dest, const char * src, +- int * pcaptype, int * pabbrev) +-{ +- unsigned char * p = (unsigned char *) dest; +- const unsigned char * q = (const unsigned char * ) src; +- int firstcap = 0; +- +- // first skip over any leading blanks +- while ((*q != '\0') && (*q == ' ')) q++; +- +- // now strip off any trailing periods (recording their presence) +- *pabbrev = 0; +- int nl = strlen((const char *)q); +- while ((nl > 0) && (*(q+nl-1)=='.')) { +- nl--; +- (*pabbrev)++; +- } +- +- // if no characters are left it can't be capitalized +- if (nl <= 0) { +- *pcaptype = NOCAP; +- *p = '\0'; +- return 0; +- } +- +- // now determine the capitalization type of the first nl letters +- int ncap = 0; +- int nneutral = 0; +- int nc = 0; +- +- if (!utf8) { +- while (nl > 0) { +- nc++; +- if (csconv[(*q)].ccase) ncap++; +- if (csconv[(*q)].cupper == csconv[(*q)].clower) nneutral++; +- *p++ = *q++; +- nl--; +- } +- // remember to terminate the destination string +- *p = '\0'; +- firstcap = csconv[(unsigned char)(*dest)].ccase; +- } else { +- unsigned short idx; +- w_char t[MAXWORDLEN]; +- nc = u8_u16(t, MAXWORDLEN, src); +- for (int i = 0; i < nc; i++) { +- idx = (t[i].h << 8) + t[i].l; +- unsigned short low = unicodetolower(idx, langnum); +- if (idx != low) ncap++; +- if (unicodetoupper(idx, langnum) == low) nneutral++; +- } +- u16_u8(dest, MAXWORDUTF8LEN, t, nc); +- if (ncap) { +- idx = (t[0].h << 8) + t[0].l; +- firstcap = (idx != unicodetolower(idx, langnum)); +- } +- } +- +- // now finally set the captype +- if (ncap == 0) { +- *pcaptype = NOCAP; +- } else if ((ncap == 1) && firstcap) { +- *pcaptype = INITCAP; +- } else if ((ncap == nc) || ((ncap + nneutral) == nc)){ +- *pcaptype = ALLCAP; +- } else if ((ncap > 1) && firstcap) { +- *pcaptype = HUHINITCAP; +- } else { +- *pcaptype = HUHCAP; +- } +- return strlen(dest); +-} +-#endif +- +-void Hunspell::mkallcap(char * p) +-{ +- if (utf8) { +- w_char u[MAXWORDLEN]; +- int nc = u8_u16(u, MAXWORDLEN, p); +- unsigned short idx; +- for (int i = 0; i < nc; i++) { +- idx = (u[i].h << 8) + u[i].l; +- if (idx != unicodetoupper(idx, langnum)) { +- u[i].h = (unsigned char) (unicodetoupper(idx, langnum) >> 8); +- u[i].l = (unsigned char) (unicodetoupper(idx, langnum) & 0x00FF); +- } +- } +- u16_u8(p, MAXWORDUTF8LEN, u, nc); +- } else { +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].cupper; +- p++; +- } +- } +-} +- +-int Hunspell::mkallcap2(char * p, w_char * u, int nc) +-{ +- if (utf8) { +- unsigned short idx; +- for (int i = 0; i < nc; i++) { +- idx = (u[i].h << 8) + u[i].l; +- unsigned short up = unicodetoupper(idx, langnum); +- if (idx != up) { +- u[i].h = (unsigned char) (up >> 8); +- u[i].l = (unsigned char) (up & 0x00FF); +- } +- } +- u16_u8(p, MAXWORDUTF8LEN, u, nc); +- return strlen(p); +- } else { +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].cupper; +- p++; +- } +- } +- return nc; +-} +- +- +-void Hunspell::mkallsmall(char * p) +-{ +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].clower; +- p++; +- } +-} +- +-int Hunspell::mkallsmall2(char * p, w_char * u, int nc) +-{ +- if (utf8) { +- unsigned short idx; +- for (int i = 0; i < nc; i++) { +- idx = (u[i].h << 8) + u[i].l; +- unsigned short low = unicodetolower(idx, langnum); +- if (idx != low) { +- u[i].h = (unsigned char) (low >> 8); +- u[i].l = (unsigned char) (low & 0x00FF); +- } +- } +- u16_u8(p, MAXWORDUTF8LEN, u, nc); +- return strlen(p); +- } else { +- while (*p != '\0') { +- *p = csconv[((unsigned char) *p)].clower; +- p++; +- } +- } +- return nc; +-} +- +-// convert UTF-8 sharp S codes to latin 1 +-char * Hunspell::sharps_u8_l1(char * dest, char * source) { +- char * p = dest; +- *p = *source; +- for (p++, source++; *(source - 1); p++, source++) { +- *p = *source; +- if (*source == '\x9F') *--p = '\xDF'; +- } +- return dest; +-} +- +-// recursive search for right ss - sharp s permutations +-hentry * Hunspell::spellsharps(char * base, char * pos, int n, +- int repnum, char * tmp, int * info, char **root) { +- pos = strstr(pos, "ss"); +- if (pos && (n < MAXSHARPS)) { +- *pos = '\xC3'; +- *(pos + 1) = '\x9F'; +- hentry * h = spellsharps(base, pos + 2, n + 1, repnum + 1, tmp, info, root); +- if (h) return h; +- *pos = 's'; +- *(pos + 1) = 's'; +- h = spellsharps(base, pos + 2, n + 1, repnum, tmp, info, root); +- if (h) return h; +- } else if (repnum > 0) { +- if (utf8) return checkword(base, info, root); +- return checkword(sharps_u8_l1(tmp, base), info, root); +- } +- return NULL; +-} +- +-int Hunspell::is_keepcase(const hentry * rv) { +- return pAMgr && rv->astr && pAMgr->get_keepcase() && +- TESTAFF(rv->astr, pAMgr->get_keepcase(), rv->alen); +-} +- +-/* insert a word to beginning of the suggestion array and return ns */ +-int Hunspell::insert_sug(char ***slst, char * word, int ns) { +- if (ns == MAXSUGGESTION) { +- ns--; +- free((*slst)[ns]); +- } +- for (int k = ns; k > 0; k--) (*slst)[k] = (*slst)[k - 1]; +- (*slst)[0] = mystrdup(word); +- return ns + 1; +-} +- +-int Hunspell::spell(const char * word, int * info, char ** root) +-{ +- struct hentry * rv=NULL; +- // need larger vector. For example, Turkish capital letter I converted a +- // 2-byte UTF-8 character (dotless i) by mkallsmall. +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- w_char unicw[MAXWORDLEN]; +- int nc = strlen(word); +- int wl2 = 0; +- if (utf8) { +- if (nc >= MAXWORDUTF8LEN) return 0; +- } else { +- if (nc >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- int wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv); +- int info2 = 0; +- if (wl == 0) return 1; +- if (root) *root = NULL; +- +- // allow numbers with dots and commas (but forbid double separators: "..", ",," etc.) +- enum { NBEGIN, NNUM, NSEP }; +- int nstate = NBEGIN; +- int i; +- +- for (i = 0; (i < wl); i++) { +- if ((cw[i] <= '9') && (cw[i] >= '0')) { +- nstate = NNUM; +- } else if ((cw[i] == ',') || (cw[i] == '.') || (cw[i] == '-')) { +- if ((nstate == NSEP) || (i == 0)) break; +- nstate = NSEP; +- } else break; +- } +- if ((i == wl) && (nstate == NNUM)) return 1; +- if (!info) info = &info2; else *info = 0; +- +- // LANG_hu section: number(s) + (percent or degree) with suffixes +- if (langnum == LANG_hu) { +- if ((nstate == NNUM) && ((cw[i] == '%') || ((!utf8 && (cw[i] == '\xB0')) || +- (utf8 && (strncmp(cw + i, "\xC2\xB0", 2)==0)))) +- && checkword(cw + i, info, root)) return 1; +- } +- // END of LANG_hu section +- +- switch(captype) { +- case HUHCAP: +- case HUHINITCAP: +- case NOCAP: { +- rv = checkword(cw, info, root); +- if ((abbv) && !(rv)) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- rv = checkword(wspace, info, root); +- } +- break; +- } +- case ALLCAP: { +- rv = checkword(cw, info, root); +- if (rv) break; +- if (abbv) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- rv = checkword(wspace, info, root); +- if (rv) break; +- } +- // Spec. prefix handling for Catalan, French, Italian: +- // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia). +- if (pAMgr && strchr(cw, '\'')) { +- wl = mkallsmall2(cw, unicw, nc); +- char * apostrophe = strchr(cw, '\''); +- if (utf8) { +- w_char tmpword[MAXWORDLEN]; +- *apostrophe = '\0'; +- wl2 = u8_u16(tmpword, MAXWORDLEN, cw); +- *apostrophe = '\''; +- if (wl2 < nc) { +- mkinitcap2(apostrophe + 1, unicw + wl2 + 1, nc - wl2 - 1); +- rv = checkword(cw, info, root); +- if (rv) break; +- } +- } else { +- mkinitcap2(apostrophe + 1, unicw, nc); +- rv = checkword(cw, info, root); +- if (rv) break; +- } +- mkinitcap2(cw, unicw, nc); +- rv = checkword(cw, info, root); +- if (rv) break; +- } +- if (pAMgr && pAMgr->get_checksharps() && strstr(cw, "SS")) { +- char tmpword[MAXWORDUTF8LEN]; +- wl = mkallsmall2(cw, unicw, nc); +- memcpy(wspace,cw,(wl+1)); +- rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); +- if (!rv) { +- wl2 = mkinitcap2(cw, unicw, nc); +- rv = spellsharps(cw, cw, 0, 0, tmpword, info, root); +- } +- if ((abbv) && !(rv)) { +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); +- if (!rv) { +- memcpy(wspace, cw, wl2); +- *(wspace+wl2) = '.'; +- *(wspace+wl2+1) = '\0'; +- rv = spellsharps(wspace, wspace, 0, 0, tmpword, info, root); +- } +- } +- if (rv) break; +- } +- } +- case INITCAP: { +- wl = mkallsmall2(cw, unicw, nc); +- memcpy(wspace,cw,(wl+1)); +- wl2 = mkinitcap2(cw, unicw, nc); +- if (captype == INITCAP) *info += SPELL_INITCAP; +- rv = checkword(cw, info, root); +- if (captype == INITCAP) *info -= SPELL_INITCAP; +- // forbid bad capitalization +- // (for example, ijs -> Ijs instead of IJs in Dutch) +- // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag) +- if (*info & SPELL_FORBIDDEN) { +- rv = NULL; +- break; +- } +- if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; +- if (rv) break; +- +- rv = checkword(wspace, info, root); +- if (abbv && !rv) { +- +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- rv = checkword(wspace, info, root); +- if (!rv) { +- memcpy(wspace, cw, wl2); +- *(wspace+wl2) = '.'; +- *(wspace+wl2+1) = '\0'; +- if (captype == INITCAP) *info += SPELL_INITCAP; +- rv = checkword(wspace, info, root); +- if (captype == INITCAP) *info -= SPELL_INITCAP; +- if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; +- break; +- } +- } +- if (rv && is_keepcase(rv) && +- ((captype == ALLCAP) || +- // if CHECKSHARPS: KEEPCASE words with \xDF are allowed +- // in INITCAP form, too. +- !(pAMgr->get_checksharps() && +- ((utf8 && strstr(wspace, "\xC3\x9F")) || +- (!utf8 && strchr(wspace, '\xDF')))))) rv = NULL; +- break; +- } +- } +- +- if (rv) return 1; +- +- // recursive breaking at break points (not good for morphological analysis) +- if (wordbreak) { +- char * s; +- char r; +- int corr = 0; +- // German words beginning with "-" are not accepted +- if (langnum == LANG_de) corr = 1; +- int numbreak = pAMgr ? pAMgr->get_numbreak() : 0; +- for (int j = 0; j < numbreak; j++) { +- s=(char *) strstr(cw + corr, wordbreak[j]); +- if (s) { +- r = *s; +- *s = '\0'; +- // examine 2 sides of the break point +- if (spell(cw) && spell(s + strlen(wordbreak[j]))) { +- *s = r; +- return 1; +- } +- *s = r; +- } +- } +- } +- +- // LANG_hu: compoundings with dashes and n-dashes XXX deprecated! +- if (langnum == LANG_hu) { +- int n; +- // compound word with dash (HU) I18n +- char * dash; +- int result = 0; +- // n-dash +- dash = (char *) strstr(cw,"\xE2\x80\x93"); +- if (dash && !wordbreak) { +- *dash = '\0'; +- // examine 2 sides of the dash +- if (spell(cw) && spell(dash + 3)) { +- *dash = '\xE2'; +- return 1; +- } +- *dash = '\xE2'; +- } +- dash = (char *) strchr(cw,'-'); +- if (dash) { +- *dash='\0'; +- // examine 2 sides of the dash +- if (dash[1] == '\0') { // base word ending with dash +- if (spell(cw)) return 1; +- } else { +- // first word ending with dash: word- +- char r2 = *(dash + 1); +- dash[0]='-'; +- dash[1]='\0'; +- result = spell(cw); +- dash[1] = r2; +- dash[0]='\0'; +- if (result && spell(dash+1) && ((strlen(dash+1) > 1) || (dash[1] == 'e') || +- ((dash[1] > '0') && (dash[1] < '9')))) return 1; +- } +- // affixed number in correct word +- if (result && (dash > cw) && (((*(dash-1)<='9') && (*(dash-1)>='0')) || (*(dash-1)>='.'))) { +- *dash='-'; +- n = 1; +- if (*(dash - n) == '.') n++; +- // search first not a number character to left from dash +- while (((dash - n)>=cw) && ((*(dash - n)=='0') || (n < 3)) && (n < 6)) { +- n++; +- } +- if ((dash - n) < cw) n--; +- // numbers: deprecated +- for(; n >= 1; n--) { +- if ((*(dash - n) >= '0') && (*(dash - n) <= '9') && +- checkword(dash - n, info, root)) return 1; +- } +- } +- } +- } +- return 0; +-} +- +-struct hentry * Hunspell::checkword(const char * w, int * info, char ** root) +-{ +- struct hentry * he = NULL; +- int len; +- char w2[MAXWORDUTF8LEN]; +- const char * word; +- +- char * ignoredchars = pAMgr->get_ignore(); +- if (ignoredchars != NULL) { +- strcpy(w2, w); +- if (utf8) { +- int ignoredchars_utf16_len; +- unsigned short * ignoredchars_utf16 = pAMgr->get_ignore_utf16(&ignoredchars_utf16_len); +- remove_ignored_chars_utf(w2, ignoredchars_utf16, ignoredchars_utf16_len); +- } else { +- remove_ignored_chars(w2,ignoredchars); +- } +- word = w2; +- } else word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- if (word != w2) { +- strcpy(w2, word); +- word = w2; +- } +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- } +- +- // look word in hash table +- if (pHMgr) he = pHMgr->lookup(word); +- +- // check forbidden and onlyincompound words +- if ((he) && (he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { +- if (info) *info += SPELL_FORBIDDEN; +- // LANG_hu section: set dash information for suggestions +- if (langnum == LANG_hu) { +- if (pAMgr->get_compoundflag() && +- TESTAFF(he->astr, pAMgr->get_compoundflag(), he->alen)) { +- if (info) *info += SPELL_COMPOUND; +- } +- } +- return NULL; +- } +- +- // he = next not pseudoroot, onlyincompound homonym or onlyupcase word +- while (he && (he->astr) && +- ((pAMgr->get_pseudoroot() && TESTAFF(he->astr, pAMgr->get_pseudoroot(), he->alen)) || +- (pAMgr->get_onlyincompound() && TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || +- (info && (*info & SPELL_INITCAP) && TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)) +- )) he = he->next_homonym; +- +- // check with affixes +- if (!he && pAMgr) { +- // try stripping off affixes */ +- len = strlen(word); +- he = pAMgr->affix_check(word, len, 0); +- +- // check compound restriction and onlyupcase +- if (he && he->astr && ( +- (pAMgr->get_onlyincompound() && +- TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || +- (info && (*info & SPELL_INITCAP) && +- TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) { +- he = NULL; +- } +- +- if (he) { +- if ((he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { +- if (info) *info += SPELL_FORBIDDEN; +- return NULL; +- } +- if (root) { +- *root = mystrdup(&(he->word)); +- if (complexprefixes) { +- if (utf8) reverseword_utf(*root); else reverseword(*root); +- } +- } +- // try check compound word +- } else if (pAMgr->get_compound()) { +- he = pAMgr->compound_check(word, len, +- 0,0,100,0,NULL,0,NULL,NULL,0); +- // LANG_hu section: `moving rule' with last dash +- if ((!he) && (langnum == LANG_hu) && (word[len-1]=='-')) { +- char * dup = mystrdup(word); +- dup[len-1] = '\0'; +- he = pAMgr->compound_check(dup, len-1, +- -5,0,100,0,NULL,1,NULL,NULL,0); +- free(dup); +- } +- // end of LANG speficic region +- if (he) { +- if (root) { +- *root = mystrdup(&(he->word)); +- if (complexprefixes) { +- if (utf8) reverseword_utf(*root); else reverseword(*root); +- } +- } +- if (info) *info += SPELL_COMPOUND; +- } +- } +- +- } +- +- return he; +-} +- +-int Hunspell::suggest(char*** slst, const char * word) +-{ +- int onlycmpdsug = 0; +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- w_char unicw[MAXWORDLEN]; +- int nc = strlen(word); +- if (utf8) { +- if (nc >= MAXWORDUTF8LEN) return 0; +- } else { +- if (nc >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- int wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv); +- if (wl == 0) return 0; +- int ns = 0; +- *slst = NULL; +- int capwords = 0; +- +- switch(captype) { +- case NOCAP: { +- ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); +- break; +- } +- +- case INITCAP: { +- capwords = 1; +- ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); +- if (ns == -1) break; +- memcpy(wspace,cw,(wl+1)); +- mkallsmall2(wspace, unicw, nc); +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- break; +- } +- case HUHINITCAP: +- capwords = 1; +- case HUHCAP: { +- ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug); +- if (ns != -1) { +- int prevns; +- // something.The -> something. The +- char * dot = strchr(cw, '.'); +- if (dot && (dot > cw)) { +- int captype_; +- if (utf8) { +- w_char w_[MAXWORDLEN]; +- int wl_ = u8_u16(w_, MAXWORDLEN, dot + 1); +- captype_ = get_captype_utf8(w_, wl_, langnum); +- } else captype_ = get_captype(dot+1, strlen(dot+1), csconv); +- if (captype_ == INITCAP) { +- char * st = mystrdup(cw); +- st = (char *) realloc(st, wl + 2); +- if (st) { +- st[(dot - cw) + 1] = ' '; +- strcpy(st + (dot - cw) + 2, dot + 1); +- ns = insert_sug(slst, st, ns); +- free(st); +- } +- } +- } +- if (captype == HUHINITCAP) { +- // TheOpenOffice.org -> The OpenOffice.org +- memcpy(wspace,cw,(wl+1)); +- mkinitsmall2(wspace, unicw, nc); +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- } +- memcpy(wspace,cw,(wl+1)); +- mkallsmall2(wspace, unicw, nc); +- if (spell(wspace)) ns = insert_sug(slst, wspace, ns); +- prevns = ns; +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- if (captype == HUHINITCAP) { +- mkinitcap2(wspace, unicw, nc); +- if (spell(wspace)) ns = insert_sug(slst, wspace, ns); +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- } +- // aNew -> "a New" (instead of "a new") +- for (int j = prevns; j < ns; j++) { +- char * space = strchr((*slst)[j],' '); +- if (space) { +- int slen = strlen(space + 1); +- // different case after space (need capitalisation) +- if ((slen < wl) && strcmp(cw + wl - slen, space + 1)) { +- w_char w[MAXWORDLEN]; +- int wc = 0; +- char * r = (*slst)[j]; +- if (utf8) wc = u8_u16(w, MAXWORDLEN, space + 1); +- mkinitcap2(space + 1, w, wc); +- // set as first suggestion +- for (int k = j; k > 0; k--) (*slst)[k] = (*slst)[k - 1]; +- (*slst)[0] = r; +- } +- } +- } +- } +- break; +- } +- +- case ALLCAP: { +- memcpy(wspace, cw, (wl+1)); +- mkallsmall2(wspace, unicw, nc); +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- if (ns == -1) break; +- if (pAMgr && pAMgr->get_keepcase() && spell(wspace)) +- ns = insert_sug(slst, wspace, ns); +- mkinitcap2(wspace, unicw, nc); +- ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug); +- for (int j=0; j < ns; j++) { +- mkallcap((*slst)[j]); +- if (pAMgr && pAMgr->get_checksharps()) { +- char * pos; +- if (utf8) { +- pos = strstr((*slst)[j], "\xC3\x9F"); +- while (pos) { +- *pos = 'S'; +- *(pos+1) = 'S'; +- pos = strstr(pos+2, "\xC3\x9F"); +- } +- } else { +- pos = strchr((*slst)[j], '\xDF'); +- while (pos) { +- (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 2); +- mystrrep((*slst)[j], "\xDF", "SS"); +- pos = strchr((*slst)[j], '\xDF'); +- } +- } +- } +- } +- break; +- } +- } +- +- // LANG_hu section: replace '-' with ' ' in Hungarian +- if (langnum == LANG_hu) { +- for (int j=0; j < ns; j++) { +- char * pos = strchr((*slst)[j],'-'); +- if (pos) { +- int info; +- char w[MAXWORDUTF8LEN]; +- *pos = '\0'; +- strcpy(w, (*slst)[j]); +- strcat(w, pos + 1); +- spell(w, &info, NULL); +- if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) { +- *pos = ' '; +- } else *pos = '-'; +- } +- } +- } +- // END OF LANG_hu section +- +- // try ngram approach since found nothing +- if ((ns == 0 || onlycmpdsug) && pAMgr && (pAMgr->get_maxngramsugs() != 0)) { +- switch(captype) { +- case NOCAP: { +- ns = pSMgr->ngsuggest(*slst, cw, ns, pHMgr); +- break; +- } +- case HUHCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall2(wspace, unicw, nc); +- ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); +- break; +- } +- case INITCAP: { +- capwords = 1; +- memcpy(wspace,cw,(wl+1)); +- mkallsmall2(wspace, unicw, nc); +- ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); +- break; +- } +- case ALLCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall2(wspace, unicw, nc); +- int oldns = ns; +- ns = pSMgr->ngsuggest(*slst, wspace, ns, pHMgr); +- for (int j = oldns; j < ns; j++) +- mkallcap((*slst)[j]); +- break; +- } +- } +- } +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- for (int j = 0; j < ns; j++) { +- if (utf8) reverseword_utf((*slst)[j]); else reverseword((*slst)[j]); +- } +- } +- +- // capitalize +- if (capwords) for (int j=0; j < ns; j++) { +- mkinitcap((*slst)[j]); +- } +- +- // expand suggestions with dot(s) +- if (abbv && pAMgr && pAMgr->get_sugswithdots()) { +- for (int j = 0; j < ns; j++) { +- (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 1 + abbv); +- strcat((*slst)[j], word + strlen(word) - abbv); +- } +- } +- +- // remove bad capitalized and forbidden forms +- if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) { +- switch (captype) { +- case INITCAP: +- case ALLCAP: { +- int l = 0; +- for (int j=0; j < ns; j++) { +- if (!strchr((*slst)[j],' ') && !spell((*slst)[j])) { +- char s[MAXSWUTF8L]; +- w_char w[MAXSWL]; +- int len; +- if (utf8) { +- len = u8_u16(w, MAXSWL, (*slst)[j]); +- } else { +- strcpy(s, (*slst)[j]); +- len = strlen(s); +- } +- mkallsmall2(s, w, len); +- free((*slst)[j]); +- if (spell(s)) { +- (*slst)[l] = mystrdup(s); +- l++; +- } else { +- mkinitcap2(s, w, len); +- if (spell(s)) { +- (*slst)[l] = mystrdup(s); +- l++; +- } +- } +- } else { +- (*slst)[l] = (*slst)[j]; +- l++; +- } +- } +- ns = l; +- } +- } +- } +- +- // remove duplications +- int l = 0; +- for (int j = 0; j < ns; j++) { +- (*slst)[l] = (*slst)[j]; +- for (int k = 0; k < l; k++) { +- if (strcmp((*slst)[k], (*slst)[j]) == 0) { +- free((*slst)[j]); +- l--; +- } +- } +- l++; +- } +- return l; +-} +- +-char * Hunspell::get_dic_encoding() +-{ +- return encoding; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// XXX need UTF-8 support +-int Hunspell::suggest_auto(char*** slst, const char * word) +-{ +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- int wl = strlen(word); +- if (utf8) { +- if (wl >= MAXWORDUTF8LEN) return 0; +- } else { +- if (wl >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- wl = cleanword(cw, word, &captype, &abbv); +- if (wl == 0) return 0; +- int ns = 0; +- *slst = NULL; // HU, nsug in pSMgr->suggest +- +- switch(captype) { +- case NOCAP: { +- ns = pSMgr->suggest_auto(slst, cw, ns); +- if (ns>0) break; +- break; +- } +- +- case INITCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_auto(slst, wspace, ns); +- for (int j=0; j < ns; j++) +- mkinitcap((*slst)[j]); +- ns = pSMgr->suggest_auto(slst, cw, ns); +- break; +- +- } +- +- case HUHCAP: { +- ns = pSMgr->suggest_auto(slst, cw, ns); +- if (ns == 0) { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_auto(slst, wspace, ns); +- } +- break; +- } +- +- case ALLCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_auto(slst, wspace, ns); +- +- mkinitcap(wspace); +- ns = pSMgr->suggest_auto(slst, wspace, ns); +- +- for (int j=0; j < ns; j++) +- mkallcap((*slst)[j]); +- break; +- } +- } +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- for (int j = 0; j < ns; j++) { +- if (utf8) reverseword_utf((*slst)[j]); else reverseword((*slst)[j]); +- } +- } +- +- // expand suggestions with dot(s) +- if (abbv && pAMgr && pAMgr->get_sugswithdots()) { +- for (int j = 0; j < ns; j++) { +- (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 1 + abbv); +- strcat((*slst)[j], word + strlen(word) - abbv); +- } +- } +- +- // LANG_hu section: replace '-' with ' ' in Hungarian +- if (langnum == LANG_hu) { +- for (int j=0; j < ns; j++) { +- char * pos = strchr((*slst)[j],'-'); +- if (pos) { +- int info; +- char w[MAXWORDUTF8LEN]; +- *pos = '\0'; +- strcpy(w, (*slst)[j]); +- strcat(w, pos + 1); +- spell(w, &info, NULL); +- if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) { +- *pos = ' '; +- } else *pos = '-'; +- } +- } +- } +- // END OF LANG_hu section +- return ns; +-} +- +-// XXX need UTF-8 support +-int Hunspell::stem(char*** slst, const char * word) +-{ +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- int wl = strlen(word); +- if (utf8) { +- if (wl >= MAXWORDUTF8LEN) return 0; +- } else { +- if (wl >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- wl = cleanword(cw, word, &captype, &abbv); +- if (wl == 0) return 0; +- +- int ns = 0; +- +- *slst = NULL; // HU, nsug in pSMgr->suggest +- +- switch(captype) { +- case HUHCAP: +- case NOCAP: { +- ns = pSMgr->suggest_stems(slst, cw, ns); +- +- if ((abbv) && (ns == 0)) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- } +- +- break; +- } +- +- case INITCAP: { +- +- ns = pSMgr->suggest_stems(slst, cw, ns); +- +- if (ns == 0) { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- +- } +- +- if ((abbv) && (ns == 0)) { +- memcpy(wspace,cw,wl); +- mkallsmall(wspace); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- } +- +- break; +- +- } +- +- case ALLCAP: { +- ns = pSMgr->suggest_stems(slst, cw, ns); +- if (ns != 0) break; +- +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- +- if (ns == 0) { +- mkinitcap(wspace); +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- } +- +- if ((abbv) && (ns == 0)) { +- memcpy(wspace,cw,wl); +- mkallsmall(wspace); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- ns = pSMgr->suggest_stems(slst, wspace, ns); +- } +- +- +- break; +- } +- } +- +- return ns; +-} +- +-int Hunspell::suggest_pos_stems(char*** slst, const char * word) +-{ +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- int wl = strlen(word); +- if (utf8) { +- if (wl >= MAXWORDUTF8LEN) return 0; +- } else { +- if (wl >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- wl = cleanword(cw, word, &captype, &abbv); +- if (wl == 0) return 0; +- +- int ns = 0; // ns=0 = normalized input +- +- *slst = NULL; // HU, nsug in pSMgr->suggest +- +- switch(captype) { +- case HUHCAP: +- case NOCAP: { +- ns = pSMgr->suggest_pos_stems(slst, cw, ns); +- +- if ((abbv) && (ns == 0)) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- ns = pSMgr->suggest_pos_stems(slst, wspace, ns); +- } +- +- break; +- } +- +- case INITCAP: { +- +- ns = pSMgr->suggest_pos_stems(slst, cw, ns); +- +- if (ns == 0 || ((*slst)[0][0] == '#')) { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_pos_stems(slst, wspace, ns); +- } +- +- break; +- +- } +- +- case ALLCAP: { +- ns = pSMgr->suggest_pos_stems(slst, cw, ns); +- if (ns != 0) break; +- +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- ns = pSMgr->suggest_pos_stems(slst, wspace, ns); +- +- if (ns == 0) { +- mkinitcap(wspace); +- ns = pSMgr->suggest_pos_stems(slst, wspace, ns); +- } +- break; +- } +- } +- +- return ns; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +-const char * Hunspell::get_wordchars() +-{ +- return pAMgr->get_wordchars(); +-} +- +-unsigned short * Hunspell::get_wordchars_utf16(int * len) +-{ +- return pAMgr->get_wordchars_utf16(len); +-} +- +-void Hunspell::mkinitcap(char * p) +-{ +- if (!utf8) { +- if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; +- } else { +- int len; +- w_char u[MAXWORDLEN]; +- len = u8_u16(u, MAXWORDLEN, p); +- unsigned short i = unicodetoupper((u[0].h << 8) + u[0].l, langnum); +- u[0].h = (unsigned char) (i >> 8); +- u[0].l = (unsigned char) (i & 0x00FF); +- u16_u8(p, MAXWORDUTF8LEN, u, len); +- } +-} +- +-int Hunspell::mkinitcap2(char * p, w_char * u, int nc) +-{ +- if (!utf8) { +- if (*p != '\0') *p = csconv[((unsigned char)*p)].cupper; +- } else if (nc > 0) { +- unsigned short i = unicodetoupper((u[0].h << 8) + u[0].l, langnum); +- u[0].h = (unsigned char) (i >> 8); +- u[0].l = (unsigned char) (i & 0x00FF); +- u16_u8(p, MAXWORDUTF8LEN, u, nc); +- return strlen(p); +- } +- return nc; +-} +- +-int Hunspell::mkinitsmall2(char * p, w_char * u, int nc) +-{ +- if (!utf8) { +- if (*p != '\0') *p = csconv[((unsigned char)*p)].clower; +- } else if (nc > 0) { +- unsigned short i = unicodetolower((u[0].h << 8) + u[0].l, langnum); +- u[0].h = (unsigned char) (i >> 8); +- u[0].l = (unsigned char) (i & 0x00FF); +- u16_u8(p, MAXWORDUTF8LEN, u, nc); +- return strlen(p); +- } +- return nc; +-} +- +-int Hunspell::put_word(const char * word) +-{ +- if (pHMgr) return pHMgr->put_word(word, NULL); +- return 0; +-} +- +-int Hunspell::put_word_pattern(const char * word, const char * pattern) +-{ +- if (pHMgr) return pHMgr->put_word_pattern(word, pattern); +- return 0; +-} +- +-const char * Hunspell::get_version() +-{ +- return pAMgr->get_version(); +-} +- +-struct cs_info * Hunspell::get_csconv() +-{ +- return csconv; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// XXX need UTF-8 support +-char * Hunspell::morph(const char * word) +-{ +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- int wl = strlen(word); +- if (utf8) { +- if (wl >= MAXWORDUTF8LEN) return 0; +- } else { +- if (wl >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- wl = cleanword(cw, word, &captype, &abbv); +- if (wl == 0) { +- if (abbv) { +- for (wl = 0; wl < abbv; wl++) cw[wl] = '.'; +- cw[wl] = '\0'; +- abbv = 0; +- } else return 0; +- } +- +- char result[MAXLNLEN]; +- char * st = NULL; +- +- *result = '\0'; +- +- int n = 0; +- int n2 = 0; +- int n3 = 0; +- +- // test numbers +- // LANG_hu section: set dash information for suggestions +- if (langnum == LANG_hu) { +- while ((n < wl) && +- (((cw[n] <= '9') && (cw[n] >= '0')) || (((cw[n] == '.') || (cw[n] == ',')) && (n > 0)))) { +- n++; +- if ((cw[n] == '.') || (cw[n] == ',')) { +- if (((n2 == 0) && (n > 3)) || +- ((n2 > 0) && ((cw[n-1] == '.') || (cw[n-1] == ',')))) break; +- n2++; +- n3 = n; +- } +- } +- +- if ((n == wl) && (n3 > 0) && (n - n3 > 3)) return NULL; +- if ((n == wl) || ((n>0) && ((cw[n]=='%') || (cw[n]=='\xB0')) && checkword(cw+n, NULL, NULL))) { +- strcat(result, cw); +- result[n - 1] = '\0'; +- if (n == wl) { +- st = pSMgr->suggest_morph(cw + n - 1); +- if (st) { +- strcat(result, st); +- free(st); +- } +- } else { +- char sign = cw[n]; +- cw[n] = '\0'; +- st = pSMgr->suggest_morph(cw + n - 1); +- if (st) { +- strcat(result, st); +- free(st); +- } +- strcat(result, "+"); // XXX SPEC. MORPHCODE +- cw[n] = sign; +- st = pSMgr->suggest_morph(cw + n); +- if (st) { +- strcat(result, st); +- free(st); +- } +- } +- return mystrdup(result); +- } +- } +- // END OF LANG_hu section +- +- switch(captype) { +- case NOCAP: { +- st = pSMgr->suggest_morph(cw); +- if (st) { +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- case INITCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- st = pSMgr->suggest_morph(cw); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- mkallsmall(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- case HUHCAP: { +- st = pSMgr->suggest_morph(cw); +- if (st) { +- strcat(result, st); +- free(st); +- } +-#if 0 +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +-#endif +- break; +- } +- case ALLCAP: { +- memcpy(wspace,cw,(wl+1)); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- mkallsmall(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,(wl+1)); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- if (*result) strcat(result, "\n"); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- mkallsmall(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- } +- +- if (result && (*result)) { +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- if (utf8) reverseword_utf(result); else reverseword(result); +- } +- return mystrdup(result); +- } +- +- // compound word with dash (HU) I18n +- char * dash = NULL; +- int nresult = 0; +- // LANG_hu section: set dash information for suggestions +- if (langnum == LANG_hu) dash = (char *) strchr(cw,'-'); +- if ((langnum == LANG_hu) && dash) { +- *dash='\0'; +- // examine 2 sides of the dash +- if (dash[1] == '\0') { // base word ending with dash +- if (spell(cw)) return pSMgr->suggest_morph(cw); +- } else if ((dash[1] == 'e') && (dash[2] == '\0')) { // XXX (HU) -e hat. +- if (spell(cw) && (spell("-e"))) { +- st = pSMgr->suggest_morph(cw); +- if (st) { +- strcat(result, st); +- free(st); +- } +- strcat(result,"+"); // XXX spec. separator in MORPHCODE +- st = pSMgr->suggest_morph("-e"); +- if (st) { +- strcat(result, st); +- free(st); +- } +- return mystrdup(result); +- } +- } else { +- // first word ending with dash: word- XXX ??? +- char r2 = *(dash + 1); +- dash[0]='-'; +- dash[1]='\0'; +- nresult = spell(cw); +- dash[1] = r2; +- dash[0]='\0'; +- if (nresult && spell(dash+1) && ((strlen(dash+1) > 1) || +- ((dash[1] > '0') && (dash[1] < '9')))) { +- st = morph(cw); +- if (st) { +- strcat(result, st); +- free(st); +- strcat(result,"+"); // XXX spec. separator in MORPHCODE +- } +- st = morph(dash+1); +- if (st) { +- strcat(result, st); +- free(st); +- } +- return mystrdup(result); +- } +- } +- // affixed number in correct word +- if (nresult && (dash > cw) && (((*(dash-1)<='9') && +- (*(dash-1)>='0')) || (*(dash-1)=='.'))) { +- *dash='-'; +- n = 1; +- if (*(dash - n) == '.') n++; +- // search first not a number character to left from dash +- while (((dash - n)>=cw) && ((*(dash - n)=='0') || (n < 3)) && (n < 6)) { +- n++; +- } +- if ((dash - n) < cw) n--; +- // numbers: valami1000000-hoz +- // examine 100000-hoz, 10000-hoz 1000-hoz, 10-hoz, +- // 56-hoz, 6-hoz +- for(; n >= 1; n--) { +- if ((*(dash - n) >= '0') && (*(dash - n) <= '9') && checkword(dash - n, NULL, NULL)) { +- strcat(result, cw); +- result[dash - cw - n] = '\0'; +- st = pSMgr->suggest_morph(dash - n); +- if (st) { +- strcat(result, st); +- free(st); +- } +- return mystrdup(result); +- } +- } +- } +- } +- return NULL; +-} +- +-// XXX need UTF-8 support +-char * Hunspell::morph_with_correction(const char * word) +-{ +- char cw[MAXWORDUTF8LEN]; +- char wspace[MAXWORDUTF8LEN]; +- if (! pSMgr) return 0; +- int wl = strlen(word); +- if (utf8) { +- if (wl >= MAXWORDUTF8LEN) return 0; +- } else { +- if (wl >= MAXWORDLEN) return 0; +- } +- int captype = 0; +- int abbv = 0; +- wl = cleanword(cw, word, &captype, &abbv); +- if (wl == 0) return 0; +- +- char result[MAXLNLEN]; +- char * st = NULL; +- +- *result = '\0'; +- +- +- switch(captype) { +- case NOCAP: { +- st = pSMgr->suggest_morph_for_spelling_error(cw); +- if (st) { +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- case INITCAP: { +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- st = pSMgr->suggest_morph_for_spelling_error(cw); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,wl); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- mkallsmall(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- case HUHCAP: { +- st = pSMgr->suggest_morph_for_spelling_error(cw); +- if (st) { +- strcat(result, st); +- free(st); +- } +- memcpy(wspace,cw,(wl+1)); +- mkallsmall(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- break; +- } +- case ALLCAP: { +- memcpy(wspace,cw,(wl+1)); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- mkallsmall(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- if (abbv) { +- memcpy(wspace,cw,(wl+1)); +- *(wspace+wl) = '.'; +- *(wspace+wl+1) = '\0'; +- if (*result) strcat(result, "\n"); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- strcat(result, st); +- free(st); +- } +- mkallsmall(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- mkinitcap(wspace); +- st = pSMgr->suggest_morph_for_spelling_error(wspace); +- if (st) { +- if (*result) strcat(result, "\n"); +- strcat(result, st); +- free(st); +- } +- } +- break; +- } +- } +- +- if (result) return mystrdup(result); +- return NULL; +-} +- +-/* analyze word +- * return line count +- * XXX need a better data structure for morphological analysis */ +-int Hunspell::analyze(char ***out, const char *word) { +- int n = 0; +- if (!word) return 0; +- char * m = morph(word); +- if(!m) return 0; +- if (!out) +- { +- n = line_tok(m, out); +- free(m); +- return n; +- } +- +- // without memory allocation +- /* BUG missing buffer size checking */ +- int i, p; +- for(p = 0, i = 0; m[i]; i++) { +- if(m[i] == '\n' || !m[i+1]) { +- n++; +- strncpy((*out)[n++], m + p, i - p + 1); +- if (m[i] == '\n') (*out)[n++][i - p] = '\0'; +- if(!m[i+1]) break; +- p = i + 1; +- } +- } +- free(m); +- return n; +-} +- +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +-Hunhandle *Hunspell_create(const char * affpath, const char * dpath) +-{ +- return (Hunhandle*)(new Hunspell(affpath, dpath)); +-} +- +-void Hunspell_destroy(Hunhandle *pHunspell) +-{ +- delete (Hunspell*)(pHunspell); +-} +- +-int Hunspell_spell(Hunhandle *pHunspell, const char *word) +-{ +- return ((Hunspell*)pHunspell)->spell(word); +-} +- +-char *Hunspell_get_dic_encoding(Hunhandle *pHunspell) +-{ +- return ((Hunspell*)pHunspell)->get_dic_encoding(); +-} +- +-int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word) +-{ +- return ((Hunspell*)pHunspell)->suggest(slst, word); +-} +Index: mozilla/extensions/spellcheck/hunspell/src/hunspell.h +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/hunspell.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _MYSPELLMGR_H_ +-#define _MYSPELLMGR_H_ +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-typedef struct Hunhandle Hunhandle; +- +-Hunhandle *Hunspell_create(const char * affpath, const char * dpath); +-void Hunspell_destroy(Hunhandle *pHunspell); +- +-/* spell(word) - spellcheck word +- * output: 0 = bad word, not 0 = good word +- */ +-int Hunspell_spell(Hunhandle *pHunspell, const char *); +- +-char *Hunspell_get_dic_encoding(Hunhandle *pHunspell); +- +-/* suggest(suggestions, word) - search suggestions +- * input: pointer to an array of strings pointer and the (bad) word +- * array of strings pointer (here *slst) may not be initialized +- * output: number of suggestions in string array, and suggestions in +- * a newly allocated array of strings (*slts will be NULL when number +- * of suggestion equals 0.) +- */ +-int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word); +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/hunspell.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/hunspell.hxx ++++ /dev/null +@@ -1,195 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#include "hashmgr.hxx" +-#include "affixmgr.hxx" +-#include "suggestmgr.hxx" +-#include "csutil.hxx" +-#include "langnum.hxx" +- +-#define SPELL_COMPOUND (1 << 0) +-#define SPELL_FORBIDDEN (1 << 1) +-#define SPELL_ALLCAP (1 << 2) +-#define SPELL_NOCAP (1 << 3) +-#define SPELL_INITCAP (1 << 4) +- +-#define MAXSUGGESTION 15 +-#define MAXSHARPS 5 +- +-#ifndef _MYSPELLMGR_HXX_ +-#define _MYSPELLMGR_HXX_ +- +-#ifdef HUNSPELL_STATIC +- #define DLLEXPORT +-#else +- #ifdef HUNSPELL_EXPORTS +- #define DLLEXPORT __declspec( dllexport ) +- #else +- #define DLLEXPORT __declspec( dllimport ) +- #endif +-#endif +- +-#ifdef W32 +-class DLLEXPORT Hunspell +-#else +-class Hunspell +-#endif +-{ +- AffixMgr* pAMgr; +- HashMgr* pHMgr; +- SuggestMgr* pSMgr; +- char * encoding; +- struct cs_info * csconv; +- int langnum; +- int utf8; +- int complexprefixes; +- char** wordbreak; +- +-public: +- +- /* Hunspell(aff, dic) - constructor of Hunspell class +- * input: path of affix file and dictionary file +- */ +- +- Hunspell(const char * affpath, const char * dpath); +- +- ~Hunspell(); +- +- /* spell(word) - spellcheck word +- * output: 0 = bad word, not 0 = good word +- * +- * plus output: +- * info: information bit array, fields: +- * SPELL_COMPOUND = a compound word +- * SPELL_FORBIDDEN = an explicit forbidden word +- * root: root (stem), when input is a word with affix(es) +- */ +- +- int spell(const char * word, int * info = NULL, char ** root = NULL); +- +- /* suggest(suggestions, word) - search suggestions +- * input: pointer to an array of strings pointer and the (bad) word +- * array of strings pointer (here *slst) may not be initialized +- * output: number of suggestions in string array, and suggestions in +- * a newly allocated array of strings (*slts will be NULL when number +- * of suggestion equals 0.) +- */ +- +- int suggest(char*** slst, const char * word); +- char * get_dic_encoding(); +- +- /* handling custom dictionary */ +- +- int put_word(const char * word); +- +- /* pattern is a sample dictionary word +- * put word into custom dictionary with affix flags of pattern word +- */ +- +- int put_word_pattern(const char * word, const char * pattern); +- +- /* other */ +- +- /* get extra word characters definied in affix file for tokenization */ +- const char * get_wordchars(); +- unsigned short * get_wordchars_utf16(int * len); +- +- struct cs_info * get_csconv(); +- const char * get_version(); +- +- /* experimental functions */ +- +-#ifdef HUNSPELL_EXPERIMENTAL +- /* suffix is an affix flag string, similarly in dictionary files */ +- +- int put_word_suffix(const char * word, const char * suffix); +- +- /* morphological analysis */ +- +- char * morph(const char * word); +- int analyze(char*** out, const char *word); +- +- char * morph_with_correction(const char * word); +- +- /* stemmer function */ +- +- int stem(char*** slst, const char * word); +- +- /* spec. suggestions */ +- int suggest_auto(char*** slst, const char * word); +- int suggest_pos_stems(char*** slst, const char * word); +- char * get_possible_root(); +-#endif +- +-private: +- int cleanword(char *, const char *, int * pcaptype, int * pabbrev); +- int cleanword2(char *, const char *, w_char *, int * w_len, int * pcaptype, int * pabbrev); +- void mkinitcap(char *); +- int mkinitcap2(char * p, w_char * u, int nc); +- int mkinitsmall2(char * p, w_char * u, int nc); +- void mkallcap(char *); +- int mkallcap2(char * p, w_char * u, int nc); +- void mkallsmall(char *); +- int mkallsmall2(char * p, w_char * u, int nc); +- struct hentry * checkword(const char *, int * info, char **root); +- char * sharps_u8_l1(char * dest, char * source); +- hentry * spellsharps(char * base, char *, int, int, char * tmp, int * info, char **root); +- int is_keepcase(const hentry * rv); +- int insert_sug(char ***slst, char * word, int ns); +- +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/langnum.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/langnum.hxx ++++ /dev/null +@@ -1,94 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _LANGNUM_HXX_ +-#define _LANGNUM_HXX_ +- +-/* +- language numbers for language specific codes +- see http://l10n.openoffice.org/languages.html +-*/ +- +-enum { +-LANG_ar=96, +-LANG_az=100, // custom number +-LANG_bg=41, +-LANG_ca=37, +-LANG_cs=42, +-LANG_da=45, +-LANG_de=49, +-LANG_el=30, +-LANG_en=01, +-LANG_es=34, +-LANG_eu=10, +-LANG_fr=02, +-LANG_gl=38, +-LANG_hr=78, +-LANG_hu=36, +-LANG_it=39, +-LANG_la=99, // custom number +-LANG_lv=101, // custom number +-LANG_nl=31, +-LANG_pl=48, +-LANG_pt=03, +-LANG_ru=07, +-LANG_sv=50, +-LANG_tr=90, +-LANG_uk=80, +-LANG_xx=999 +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/phonet.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/phonet.cpp ++++ /dev/null +@@ -1,310 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developer of the Original Code is Björn Jacke. Portions created +- * by the Initial Developers are Copyright (C) 2000-2007 the Initial +- * Developers. All Rights Reserved. +- * +- * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de) +- * László Németh (nemethl@gyorsposta.hu) +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- * Changelog: +- * 2000-01-05 Björn Jacke +- * Initial Release insprired by the article about phonetic +- * transformations out of c't 25/1999 +- * +- * 2007-07-26 Björn Jacke +- * Released under MPL/GPL/LGPL tri-license for Hunspell +- * +- * 2007-08-23 László Németh +- * Porting from Aspell to Hunspell using C-like structs +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "csutil.hxx" +-#include "phonet.hxx" +- +-void init_phonet_hash(phonetable & parms) +- { +- int i, k; +- +- for (i = 0; i < parms.hash_size; i++) { +- parms.hash[i] = -1; +- } +- +- for (i = 0; parms.rules[i][0] != '\0'; i += 2) { +- /** set hash value **/ +- k = (unsigned char) parms.rules[i][0]; +- +- if (parms.hash[k] < 0) { +- parms.hash[k] = i; +- } +- } +- } +- +- // like strcpy but safe if the strings overlap +- // but only if dest < src +- static inline void strmove(char * dest, char * src) { +- while (*src) +- *dest++ = *src++; +- *dest = '\0'; +- } +- +-/* phonetic transcription algorithm */ +-/* see: http://aspell.net/man-html/Phonetic-Code.html */ +-/* convert string to uppercase before this call */ +-int phonet (const char * inword, char * target, +- int len, +- phonetable & parms) +- { +- /** Do phonetic transformation. **/ +- /** "len" = length of "inword" incl. '\0'. **/ +- +- /** result: >= 0: length of "target" **/ +- /** otherwise: error **/ +- +- int i,j,k=0,n,p,z; +- int k0,n0,p0=-333,z0; +- char c, c0; +- const char * s; +- typedef unsigned char uchar; +- char word[MAXPHONETUTF8LEN + 1]; +- if (len == -1) len = strlen(inword); +- if (len > MAXPHONETUTF8LEN) return 0; +- strcpy(word, inword); +- +- /** check word **/ +- i = j = z = 0; +- while ((c = word[i]) != '\0') { +- n = parms.hash[(uchar) c]; +- z0 = 0; +- +- if (n >= 0) { +- /** check all rules for the same letter **/ +- while (parms.rules[n][0] == c) { +- +- /** check whole string **/ +- k = 1; /** number of found letters **/ +- p = 5; /** default priority **/ +- s = parms.rules[n]; +- s++; /** important for (see below) "*(s-1)" **/ +- +- while (*s != '\0' && word[i+k] == *s +- && !isdigit (*s) && strchr ("(-<^$", *s) == NULL) { +- k++; +- s++; +- } +- if (*s == '(') { +- /** check letters in "(..)" **/ +- if (isalpha(word[i+k]) // ...could be implied? +- && strchr(s+1, word[i+k]) != NULL) { +- k++; +- while (*s != ')') +- s++; +- s++; +- } +- } +- p0 = (int) *s; +- k0 = k; +- while (*s == '-' && k > 1) { +- k--; +- s++; +- } +- if (*s == '<') +- s++; +- if (isdigit (*s)) { +- /** determine priority **/ +- p = *s - '0'; +- s++; +- } +- if (*s == '^' && *(s+1) == '^') +- s++; +- +- if (*s == '\0' +- || (*s == '^' +- && (i == 0 || ! isalpha(word[i-1])) +- && (*(s+1) != '$' +- || (! isalpha(word[i+k0]) ))) +- || (*s == '$' && i > 0 +- && isalpha(word[i-1]) +- && (! isalpha(word[i+k0]) ))) +- { +- /** search for followup rules, if: **/ +- /** parms.followup and k > 1 and NO '-' in searchstring **/ +- c0 = word[i+k-1]; +- n0 = parms.hash[(uchar) c0]; +- +-// if (parms.followup && k > 1 && n0 >= 0 +- if (k > 1 && n0 >= 0 +- && p0 != (int) '-' && word[i+k] != '\0') { +- /** test follow-up rule for "word[i+k]" **/ +- while (parms.rules[n0][0] == c0) { +- +- /** check whole string **/ +- k0 = k; +- p0 = 5; +- s = parms.rules[n0]; +- s++; +- while (*s != '\0' && word[i+k0] == *s +- && ! isdigit(*s) && strchr("(-<^$",*s) == NULL) { +- k0++; +- s++; +- } +- if (*s == '(') { +- /** check letters **/ +- if (isalpha(word[i+k0]) +- && strchr (s+1, word[i+k0]) != NULL) { +- k0++; +- while (*s != ')' && *s != '\0') +- s++; +- if (*s == ')') +- s++; +- } +- } +- while (*s == '-') { +- /** "k0" gets NOT reduced **/ +- /** because "if (k0 == k)" **/ +- s++; +- } +- if (*s == '<') +- s++; +- if (isdigit (*s)) { +- p0 = *s - '0'; +- s++; +- } +- +- if (*s == '\0' +- /** *s == '^' cuts **/ +- || (*s == '$' && ! isalpha(word[i+k0]))) +- { +- if (k0 == k) { +- /** this is just a piece of the string **/ +- n0 += 2; +- continue; +- } +- +- if (p0 < p) { +- /** priority too low **/ +- n0 += 2; +- continue; +- } +- /** rule fits; stop search **/ +- break; +- } +- n0 += 2; +- } /** End of "while (parms.rules[n0][0] == c0)" **/ +- +- if (p0 >= p && parms.rules[n0][0] == c0) { +- n += 2; +- continue; +- } +- } /** end of follow-up stuff **/ +- +- /** replace string **/ +- s = parms.rules[n+1]; +- p0 = (parms.rules[n][0] != '\0' +- && strchr (parms.rules[n]+1,'<') != NULL) ? 1:0; +- if (p0 == 1 && z == 0) { +- /** rule with '<' is used **/ +- if (j > 0 && *s != '\0' +- && (target[j-1] == c || target[j-1] == *s)) { +- j--; +- } +- z0 = 1; +- z = 1; +- k0 = 0; +- while (*s != '\0' && word[i+k0] != '\0') { +- word[i+k0] = *s; +- k0++; +- s++; +- } +- if (k > k0) +- strmove (&word[0]+i+k0, &word[0]+i+k); +- +- /** new "actual letter" **/ +- c = word[i]; +- } +- else { /** no '<' rule used **/ +- i += k - 1; +- z = 0; +- while (*s != '\0' +- && *(s+1) != '\0' && j < len) { +- if (j == 0 || target[j-1] != *s) { +- target[j] = *s; +- j++; +- } +- s++; +- } +- /** new "actual letter" **/ +- c = *s; +- if (parms.rules[n][0] != '\0' +- && strstr (parms.rules[n]+1, "^^") != NULL) { +- if (c != '\0') { +- target[j] = c; +- j++; +- } +- strmove (&word[0], &word[0]+i+1); +- i = 0; +- z0 = 1; +- } +- } +- break; +- } /** end of follow-up stuff **/ +- n += 2; +- } /** end of while (parms.rules[n][0] == c) **/ +- } /** end of if (n >= 0) **/ +- if (z0 == 0) { +-// if (k && (assert(p0!=-333),!p0) && j < len && c != '\0' +-// && (!parms.collapse_result || j == 0 || target[j-1] != c)){ +- if (k && !p0 && j < len && c != '\0' +- && (1 || j == 0 || target[j-1] != c)){ +- /** condense only double letters **/ +- target[j] = c; +- ///printf("\n setting \n"); +- j++; +- } +- +- i++; +- z = 0; +- k=0; +- } +- } /** end of while ((c = word[i]) != '\0') **/ +- +- target[j] = '\0'; +- return (j); +- +- } /** end of function "phonet" **/ +Index: mozilla/extensions/spellcheck/hunspell/src/phonet.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/phonet.hxx ++++ /dev/null +@@ -1,66 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developer of the Original Code is Björn Jacke. Portions created +- * by the Initial Developers are Copyright (C) 2000-2007 the Initial +- * Developers. All Rights Reserved. +- * +- * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de) +- * László Németh (nemethl@gyorsposta.hu) +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- * Changelog: +- * 2000-01-05 Björn Jacke +- * Initial Release insprired by the article about phonetic +- * transformations out of c't 25/1999 +- * +- * 2007-07-20 Björn Jacke +- * Released under MPL/GPL/LGPL tri-license for Hunspell +- * +- * 2007-08-22 László Németh +- * Porting from Aspell to Hunspell by little modifications +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef __PHONETHXX__ +-#define __PHONETHXX__ +- +-#define MAXPHONETLEN 256 +-#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4) +- +-struct phonetable { +- char utf8; +- cs_info * lang; +- int num; +- char * * rules; +- static const int hash_size = 256; +- int hash[hash_size]; +-}; +- +-void init_phonet_hash(phonetable & parms); +- +-int phonet (const char * inword, char * target, +- int len, phonetable & phone); +- +-#endif +Index: mozilla/extensions/spellcheck/hunspell/src/suggestmgr.cpp +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/suggestmgr.cpp ++++ /dev/null +@@ -1,2036 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef MOZILLA_CLIENT +-#include +-#include +-#include +-#include +-#else +-#include +-#include +-#include +-#include +-#endif +- +-#include "suggestmgr.hxx" +- +-#ifndef MOZILLA_CLIENT +-#ifndef W32 +-using namespace std; +-#endif +-#endif +- +-const w_char W_VLINE = { '\0', '|' }; +- +-SuggestMgr::SuggestMgr(const char * tryme, int maxn, +- AffixMgr * aptr) +-{ +- +- // register affix manager and check in string of chars to +- // try when building candidate suggestions +- pAMgr = aptr; +- +- ckeyl = 0; +- ckey = NULL; +- ckey_utf = NULL; +- +- ctryl = 0; +- ctry = NULL; +- ctry_utf = NULL; +- +- utf8 = 0; +- langnum = 0; +- complexprefixes = 0; +- +- maxSug = maxn; +- nosplitsugs = 0; +- maxngramsugs = MAXNGRAMSUGS; +- +- if (pAMgr) { +- char * enc = pAMgr->get_encoding(); +- csconv = get_current_cs(enc); +- free(enc); +- langnum = pAMgr->get_langnum(); +- ckey = pAMgr->get_key_string(); +- nosplitsugs = pAMgr->get_nosplitsugs(); +- if (pAMgr->get_maxngramsugs() >= 0) maxngramsugs = pAMgr->get_maxngramsugs(); +- utf8 = pAMgr->get_utf8(); +- complexprefixes = pAMgr->get_complexprefixes(); +- } +- +- if (ckey) { +- if (utf8) { +- w_char t[MAXSWL]; +- ckeyl = u8_u16(t, MAXSWL, ckey); +- ckey_utf = (w_char *) malloc(ckeyl * sizeof(w_char)); +- if (ckey_utf) memcpy(ckey_utf, t, ckeyl * sizeof(w_char)); +- } else { +- ckeyl = strlen(ckey); +- } +- } +- +- if (tryme) { +- if (utf8) { +- w_char t[MAXSWL]; +- ctryl = u8_u16(t, MAXSWL, tryme); +- ctry_utf = (w_char *) malloc(ctryl * sizeof(w_char)); +- if (ctry_utf) memcpy(ctry_utf, t, ctryl * sizeof(w_char)); +- } else { +- ctry = mystrdup(tryme); +- ctryl = strlen(ctry); +- } +- } +-} +- +- +-SuggestMgr::~SuggestMgr() +-{ +- pAMgr = NULL; +- if (ckey) free(ckey); +- ckey = NULL; +- if (ckey_utf) free(ckey_utf); +- ckey_utf = NULL; +- ckeyl = 0; +- if (ctry) free(ctry); +- ctry = NULL; +- if (ctry_utf) free(ctry_utf); +- ctry_utf = NULL; +- ctryl = 0; +- maxSug = 0; +-} +- +-int SuggestMgr::testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest, +- int * timer, clock_t * timelimit) { +- int cwrd = 1; +- if (ns == maxSug) return maxSug; +- for (int k=0; k < ns; k++) { +- if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; +- } +- if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) { +- wlst[ns] = mystrdup(candidate); +- if (wlst[ns] == NULL) { +- for (int j=0; j HTML) +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? capchars_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- capchars(wlst, word, nsug, cpdsuggest); +- } +- +- // perhaps we made a typical fault of spelling +- if ((nsug < maxSug) && (nsug > -1)) +- nsug = replchars(wlst, word, nsug, cpdsuggest); +- +- // perhaps we made chose the wrong char from a related set +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = mapchars(wlst, word, nsug, cpdsuggest); +- } +- +- // did we swap the order of chars by mistake +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? swapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- swapchar(wlst, word, nsug, cpdsuggest); +- } +- +- // did we swap the order of non adjacent chars by mistake +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? longswapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- longswapchar(wlst, word, nsug, cpdsuggest); +- } +- +- // did we just hit the wrong key in place of a good char (case and keyboard) +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? badcharkey_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- badcharkey(wlst, word, nsug, cpdsuggest); +- } +- +- // did we add a char that should not be there +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? extrachar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- extrachar(wlst, word, nsug, cpdsuggest); +- } +- +- // only suggest compound words when no other suggestion +- if ((cpdsuggest == 0) && (nsug > 0)) nocompoundtwowords=1; +- +- // did we forgot a char +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? forgotchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- forgotchar(wlst, word, nsug, cpdsuggest); +- } +- +- // did we move a char +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? movechar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- movechar(wlst, word, nsug, cpdsuggest); +- } +- +- // did we just hit the wrong key in place of a good char +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? badchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- badchar(wlst, word, nsug, cpdsuggest); +- } +- +- // did we double two characters +- if ((nsug < maxSug) && (nsug > -1)) { +- nsug = (utf8) ? doubletwochars_utf(wlst, word_utf, wl, nsug, cpdsuggest) : +- doubletwochars(wlst, word, nsug, cpdsuggest); +- } +- +- // perhaps we forgot to hit space and two words ran together +- if ((!nosplitsugs) && (nsug < maxSug) && (nsug > -1)) { +- nsug = twowords(wlst, word, nsug, cpdsuggest); +- } +- +- } // repeating ``for'' statement compounding support +- +- if (nsug < 0) { +- // we ran out of memory - we should free up as much as possible +- for (int i = 0; i < maxSug; i++) +- if (wlst[i] != NULL) free(wlst[i]); +- free(wlst); +- wlst = NULL; +- } +- +- if (!nocompoundtwowords && (nsug > 0) && onlycompoundsug) *onlycompoundsug = 1; +- +- *slst = wlst; +- return nsug; +-} +- +-// generate suggestions for a word with typical mistake +-// pass in address of array of char * pointers +-#ifdef HUNSPELL_EXPERIMENTAL +-int SuggestMgr::suggest_auto(char*** slst, const char * w, int nsug) +-{ +- int nocompoundtwowords = 0; +- char ** wlst; +- +- char w2[MAXWORDUTF8LEN]; +- const char * word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- strcpy(w2, w); +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- word = w2; +- } +- +- if (*slst) { +- wlst = *slst; +- } else { +- wlst = (char **) malloc(maxSug * sizeof(char *)); +- if (wlst == NULL) return -1; +- } +- +- for (int cpdsuggest=0; (cpdsuggest<2) && (nocompoundtwowords==0); cpdsuggest++) { +- +- // perhaps we made a typical fault of spelling +- if ((nsug < maxSug) && (nsug > -1)) +- nsug = replchars(wlst, word, nsug, cpdsuggest); +- +- // perhaps we made chose the wrong char from a related set +- if ((nsug < maxSug) && (nsug > -1)) +- nsug = mapchars(wlst, word, nsug, cpdsuggest); +- +- if ((cpdsuggest==0) && (nsug>0)) nocompoundtwowords=1; else * +- +- // perhaps we forgot to hit space and two words ran together +- +- if ((nsug < maxSug) && (nsug > -1) && check_forbidden(word, strlen(word))) { +- nsug = twowords(wlst, word, nsug, cpdsuggest); +- } +- +- } // repeating ``for'' statement compounding support +- +- if (nsug < 0) { +- for (int i=0;i HTML) +-int SuggestMgr::capchars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- w_char candidate_utf[MAXSWL]; +- memcpy(candidate_utf, word, wl * sizeof(w_char)); +- mkallcap_utf(candidate_utf, wl, langnum); +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +-} +- +-// suggestions for an uppercase word (html -> HTML) +-int SuggestMgr::capchars(char** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- strcpy(candidate, word); +- mkallcap(candidate, csconv); +- return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +-} +- +-// suggestions for when chose the wrong char out of a related set +-int SuggestMgr::mapchars(char** wlst, const char * word, int ns, int cpdsuggest) +-{ +- clock_t timelimit; +- int timer; +- +- int wl = strlen(word); +- if (wl < 2 || ! pAMgr) return ns; +- +- int nummap = pAMgr->get_nummap(); +- struct mapentry* maptable = pAMgr->get_maptable(); +- if (maptable==NULL) return ns; +- +- timelimit = clock(); +- timer = MINTIMER; +- if (utf8) { +- w_char w[MAXSWL]; +- int len = u8_u16(w, MAXSWL, word); +- ns = map_related_utf(w, len, 0, cpdsuggest, wlst, ns, maptable, nummap, &timer, &timelimit); +- } else ns = map_related(word, 0, wlst, cpdsuggest, ns, maptable, nummap, &timer, &timelimit); +- return ns; +-} +- +-int SuggestMgr::map_related(const char * word, int i, char** wlst, +- int cpdsuggest, int ns, +- const mapentry* maptable, int nummap, int * timer, clock_t * timelimit) +-{ +- char c = *(word + i); +- if (c == 0) { +- int cwrd = 1; +- int wl = strlen(word); +- for (int m=0; m < ns; m++) +- if (strcmp(word,wlst[m]) == 0) cwrd = 0; +- if ((cwrd) && checkword(word, wl, cpdsuggest, timer, timelimit)) { +- if (ns < maxSug) { +- wlst[ns] = mystrdup(word); +- if (wlst[ns] == NULL) return -1; +- ns++; +- } +- } +- return ns; +- } +- int in_map = 0; +- for (int j = 0; j < nummap; j++) { +- if (strchr(maptable[j].set,c) != 0) { +- in_map = 1; +- char * newword = mystrdup(word); +- for (int k = 0; k < maptable[j].len; k++) { +- *(newword + i) = *(maptable[j].set + k); +- ns = map_related(newword, (i+1), wlst, cpdsuggest, +- ns, maptable, nummap, timer, timelimit); +- if (!(*timer)) return ns; +- } +- free(newword); +- } +- } +- if (!in_map) { +- i++; +- ns = map_related(word, i, wlst, cpdsuggest, +- ns, maptable, nummap, timer, timelimit); +- } +- return ns; +-} +- +-int SuggestMgr::map_related_utf(w_char * word, int len, int i, int cpdsuggest, +- char** wlst, int ns, const mapentry* maptable, int nummap, +- int * timer, clock_t * timelimit) +-{ +- if (i == len) { +- int cwrd = 1; +- int wl; +- char s[MAXSWUTF8L]; +- u16_u8(s, MAXSWUTF8L, word, len); +- wl = strlen(s); +- for (int m=0; m < ns; m++) +- if (strcmp(s,wlst[m]) == 0) cwrd = 0; +- if ((cwrd) && checkword(s, wl, cpdsuggest, timer, timelimit)) { +- if (ns < maxSug) { +- wlst[ns] = mystrdup(s); +- if (wlst[ns] == NULL) return -1; +- ns++; +- } +- } +- return ns; +- } +- int in_map = 0; +- unsigned short c = *((unsigned short *) word + i); +- for (int j = 0; j < nummap; j++) { +- if (flag_bsearch((unsigned short *) maptable[j].set_utf16, c, maptable[j].len)) { +- in_map = 1; +- for (int k = 0; k < maptable[j].len; k++) { +- *(word + i) = *(maptable[j].set_utf16 + k); +- ns = map_related_utf(word, len, i + 1, cpdsuggest, +- wlst, ns, maptable, nummap, timer, timelimit); +- if (!(*timer)) return ns; +- } +- *((unsigned short *) word + i) = c; +- } +- } +- if (!in_map) { +- i++; +- ns = map_related_utf(word, len, i, cpdsuggest, +- wlst, ns, maptable, nummap, timer, timelimit); +- } +- return ns; +-} +- +- +- +-// suggestions for a typical fault of spelling, that +-// differs with more, than 1 letter from the right form. +-int SuggestMgr::replchars(char** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- const char * r; +- int lenr, lenp; +- int wl = strlen(word); +- if (wl < 2 || ! pAMgr) return ns; +- int numrep = pAMgr->get_numrep(); +- struct replentry* reptable = pAMgr->get_reptable(); +- if (reptable==NULL) return ns; +- for (int i=0; i < numrep; i++ ) { +- r = word; +- lenr = strlen(reptable[i].pattern2); +- lenp = strlen(reptable[i].pattern); +- // search every occurence of the pattern in the word +- while ((r=strstr(r, reptable[i].pattern)) != NULL) { +- strcpy(candidate, word); +- if (r-word + lenr + strlen(r+lenp) >= MAXSWUTF8L) break; +- strcpy(candidate+(r-word),reptable[i].pattern2); +- strcpy(candidate+(r-word)+lenr, r+lenp); +- ns = testsug(wlst, candidate, wl-lenp+lenr, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- // check REP suggestions with space +- char * sp = strchr(candidate, ' '); +- if (sp) { +- *sp = '\0'; +- if (checkword(candidate, strlen(candidate), 0, NULL, NULL)) { +- int oldns = ns; +- *sp = ' '; +- ns = testsug(wlst, sp + 1, strlen(sp + 1), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- if (oldns < ns) { +- free(wlst[ns - 1]); +- wlst[ns - 1] = mystrdup(candidate); +- } +- } +- *sp = ' '; +- } +- r++; // search for the next letter +- } +- } +- return ns; +-} +- +-// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation) +-int SuggestMgr::doubletwochars(char** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- int state=0; +- int wl = strlen(word); +- if (wl < 5 || ! pAMgr) return ns; +- for (int i=2; i < wl; i++ ) { +- if (word[i]==word[i-2]) { +- state++; +- if (state==3) { +- strcpy(candidate,word); +- strcpy(candidate+i-1,word+i+1); +- ns = testsug(wlst, candidate, wl-2, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- state=0; +- } +- } else { +- state=0; +- } +- } +- return ns; +-} +- +-// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation) +-int SuggestMgr::doubletwochars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- int state=0; +- if (wl < 5 || ! pAMgr) return ns; +- for (int i=2; i < wl; i++) { +- if (w_char_eq(word[i], word[i-2])) { +- state++; +- if (state==3) { +- memcpy(candidate_utf, word, (i - 1) * sizeof(w_char)); +- memcpy(candidate_utf+i-1, word+i+1, (wl-i-1) * sizeof(w_char)); +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl-2); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- state=0; +- } +- } else { +- state=0; +- } +- } +- return ns; +-} +- +-// error is wrong char in place of correct one (case and keyboard related version) +-int SuggestMgr::badcharkey(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char tmpc; +- char candidate[MAXSWUTF8L]; +- int wl = strlen(word); +- strcpy(candidate, word); +- // swap out each char one by one and try uppercase and neighbor +- // keyboard chars in its place to see if that makes a good word +- +- for (int i=0; i < wl; i++) { +- tmpc = candidate[i]; +- // check with uppercase letters +- candidate[i] = csconv[((unsigned char)tmpc)].cupper; +- if (tmpc != candidate[i]) { +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- candidate[i] = tmpc; +- } +- // check neighbor characters in keyboard string +- if (!ckey) continue; +- char * loc = strchr(ckey, tmpc); +- while (loc) { +- if ((loc > ckey) && (*(loc - 1) != '|')) { +- candidate[i] = *(loc - 1); +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- if ((*(loc + 1) != '|') && (*(loc + 1) != '\0')) { +- candidate[i] = *(loc + 1); +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- loc = strchr(loc + 1, tmpc); +- } +- candidate[i] = tmpc; +- } +- return ns; +-} +- +-// error is wrong char in place of correct one (case and keyboard related version) +-int SuggestMgr::badcharkey_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char tmpc; +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- memcpy(candidate_utf, word, wl * sizeof(w_char)); +- // swap out each char one by one and try all the tryme +- // chars in its place to see if that makes a good word +- for (int i=0; i < wl; i++) { +- tmpc = candidate_utf[i]; +- // check with uppercase letters +- mkallcap_utf(candidate_utf + i, 1, langnum); +- if (!w_char_eq(tmpc, candidate_utf[i])) { +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- candidate_utf[i] = tmpc; +- } +- // check neighbor characters in keyboard string +- if (!ckey) continue; +- w_char * loc = ckey_utf; +- while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc)) loc++; +- while (loc < (ckey_utf + ckeyl)) { +- if ((loc > ckey_utf) && !w_char_eq(*(loc - 1), W_VLINE)) { +- candidate_utf[i] = *(loc - 1); +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- if (((loc + 1) < (ckey_utf + ckeyl)) && !w_char_eq(*(loc + 1), W_VLINE)) { +- candidate_utf[i] = *(loc + 1); +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- do { loc++; } while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc)); +- } +- candidate_utf[i] = tmpc; +- } +- return ns; +-} +- +-// error is wrong char in place of correct one +-int SuggestMgr::badchar(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char tmpc; +- char candidate[MAXSWUTF8L]; +- clock_t timelimit = clock(); +- int timer = MINTIMER; +- int wl = strlen(word); +- strcpy(candidate, word); +- // swap out each char one by one and try all the tryme +- // chars in its place to see if that makes a good word +- for (int i=0; i < wl; i++) { +- tmpc = candidate[i]; +- for (int j=0; j < ctryl; j++) { +- if (ctry[j] == tmpc) continue; +- candidate[i] = ctry[j]; +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, &timer, &timelimit); +- if (ns == -1) return -1; +- if (!timer) return ns; +- candidate[i] = tmpc; +- } +- } +- return ns; +-} +- +-// error is wrong char in place of correct one +-int SuggestMgr::badchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char tmpc; +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- clock_t timelimit = clock(); +- int timer = MINTIMER; +- memcpy(candidate_utf, word, wl * sizeof(w_char)); +- // swap out each char one by one and try all the tryme +- // chars in its place to see if that makes a good word +- for (int i=0; i < wl; i++) { +- tmpc = candidate_utf[i]; +- for (int j=0; j < ctryl; j++) { +- if (w_char_eq(tmpc, ctry_utf[j])) continue; +- candidate_utf[i] = ctry_utf[j]; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit); +- if (ns == -1) return -1; +- if (!timer) return ns; +- candidate_utf[i] = tmpc; +- } +- } +- return ns; +-} +- +-// error is word has an extra letter it does not need +-int SuggestMgr::extrachar_utf(char** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- w_char candidate_utf[MAXSWL]; +- const w_char * p; +- w_char * r; +- if (wl < 2) return ns; +- // try omitting one char of word at a time +- memcpy(candidate_utf, word + 1, (wl - 1) * sizeof(w_char)); +- for (p = word, r = candidate_utf; p < word + wl; ) { +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl - 1); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- *r++ = *p++; +- } +- return ns; +-} +- +-// error is word has an extra letter it does not need +-int SuggestMgr::extrachar(char** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- const char * p; +- char * r; +- int wl = strlen(word); +- if (wl < 2) return ns; +- // try omitting one char of word at a time +- strcpy (candidate, word + 1); +- for (p = word, r = candidate; *p != 0; ) { +- ns = testsug(wlst, candidate, wl-1, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- *r++ = *p++; +- } +- return ns; +-} +- +- +-// error is missing a letter it needs +-int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- const char * p; +- char * q; +- clock_t timelimit = clock(); +- int timer = MINTIMER; +- int wl = strlen(word); +- // try inserting a tryme character before every letter +- strcpy(candidate + 1, word); +- for (p = word, q = candidate; *p != 0; ) { +- for (int i = 0; i < ctryl; i++) { +- *q = ctry[i]; +- ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, &timer, &timelimit); +- if (ns == -1) return -1; +- if (!timer) return ns; +- } +- *q++ = *p++; +- } +- // now try adding one to end */ +- for (int i = 0; i < ctryl; i++) { +- *q = ctry[i]; +- ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- return ns; +-} +- +-// error is missing a letter it needs +-int SuggestMgr::forgotchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- const w_char * p; +- w_char * q; +- int cwrd; +- clock_t timelimit = clock(); +- int timer = MINTIMER; +- // try inserting a tryme character before every letter +- memcpy (candidate_utf + 1, word, wl * sizeof(w_char)); +- for (p = word, q = candidate_utf; p < (word + wl); ) { +- for (int i = 0; i < ctryl; i++) { +- *q = ctry_utf[i]; +- cwrd = 1; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit); +- if (ns == -1) return -1; +- if (!timer) return ns; +- } +- *q++ = *p++; +- } +- // now try adding one to end */ +- for (int i = 0; i < ctryl; i++) { +- *q = ctry_utf[i]; +- cwrd = 1; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- return ns; +-} +- +- +-/* error is should have been two words */ +-int SuggestMgr::twowords(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- char * p; +- int c1, c2; +- int forbidden = 0; +- int cwrd; +- +- int wl=strlen(word); +- if (wl < 3) return ns; +- +- if (langnum == LANG_hu) forbidden = check_forbidden(word, wl); +- +- strcpy(candidate + 1, word); +- // split the string into two pieces after every char +- // if both pieces are good words make them a suggestion +- for (p = candidate + 1; p[1] != '\0'; p++) { +- p[-1] = *p; +- // go to end of the UTF-8 character +- while (utf8 && ((p[1] & 0xc0) == 0x80)) { +- *p = p[1]; +- p++; +- } +- if (utf8 && p[1] == '\0') break; // last UTF-8 character +- *p = '\0'; +- c1 = checkword(candidate,strlen(candidate), cpdsuggest, NULL, NULL); +- if (c1) { +- c2 = checkword((p+1),strlen(p+1), cpdsuggest, NULL, NULL); +- if (c2) { +- *p = ' '; +- +- // spec. Hungarian code (need a better compound word support) +- if ((langnum == LANG_hu) && !forbidden && +- // if 3 repeating letter, use - instead of space +- (((p[-1] == p[1]) && (((p>candidate+1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) || +- // or multiple compounding, with more, than 6 syllables +- ((c1 == 3) && (c2 >= 2)))) *p = '-'; +- +- cwrd = 1; +- for (int k=0; k < ns; k++) +- if (strcmp(candidate,wlst[k]) == 0) cwrd = 0; +- if (ns < maxSug) { +- if (cwrd) { +- wlst[ns] = mystrdup(candidate); +- if (wlst[ns] == NULL) return -1; +- ns++; +- } +- } else return ns; +- } +- } +- } +- return ns; +-} +- +- +-// error is adjacent letter were swapped +-int SuggestMgr::swapchar(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- char * p; +- char tmpc; +- int wl=strlen(word); +- // try swapping adjacent chars one by one +- strcpy(candidate, word); +- for (p = candidate; p[1] != 0; p++) { +- tmpc = *p; +- *p = p[1]; +- p[1] = tmpc; +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- p[1] = *p; +- *p = tmpc; +- } +- // try double swaps for short words +- // ahev -> have, owudl -> would +- if (wl == 4 || wl == 5) { +- candidate[0] = word[1]; +- candidate[1] = word[0]; +- candidate[2] = word[2]; +- candidate[wl - 2] = word[wl - 1]; +- candidate[wl - 1] = word[wl - 2]; +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- if (wl == 5) { +- candidate[0] = word[0]; +- candidate[1] = word[2]; +- candidate[2] = word[1]; +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- } +- return ns; +-} +- +-// error is adjacent letter were swapped +-int SuggestMgr::swapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- w_char * p; +- w_char tmpc; +- int len = 0; +- // try swapping adjacent chars one by one +- memcpy (candidate_utf, word, wl * sizeof(w_char)); +- for (p = candidate_utf; p < (candidate_utf + wl - 1); p++) { +- tmpc = *p; +- *p = p[1]; +- p[1] = tmpc; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- if (len == 0) len = strlen(candidate); +- ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- p[1] = *p; +- *p = tmpc; +- } +- // try double swaps for short words +- // ahev -> have, owudl -> would, suodn -> sound +- if (wl == 4 || wl == 5) { +- candidate_utf[0] = word[1]; +- candidate_utf[1] = word[0]; +- candidate_utf[2] = word[2]; +- candidate_utf[wl - 2] = word[wl - 1]; +- candidate_utf[wl - 1] = word[wl - 2]; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- if (wl == 5) { +- candidate_utf[0] = word[0]; +- candidate_utf[1] = word[2]; +- candidate_utf[2] = word[1]; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- } +- return ns; +-} +- +-// error is not adjacent letter were swapped +-int SuggestMgr::longswapchar(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- char * p; +- char * q; +- char tmpc; +- int wl=strlen(word); +- // try swapping not adjacent chars one by one +- strcpy(candidate, word); +- for (p = candidate; *p != 0; p++) { +- for (q = candidate; *q != 0; q++) { +- if (abs(p-q) > 1) { +- tmpc = *p; +- *p = *q; +- *q = tmpc; +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- *q = *p; +- *p = tmpc; +- } +- } +- } +- return ns; +-} +- +- +-// error is adjacent letter were swapped +-int SuggestMgr::longswapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- w_char * p; +- w_char * q; +- w_char tmpc; +- // try swapping not adjacent chars +- memcpy (candidate_utf, word, wl * sizeof(w_char)); +- for (p = candidate_utf; p < (candidate_utf + wl); p++) { +- for (q = candidate_utf; q < (candidate_utf + wl); q++) { +- if (abs(p-q) > 1) { +- tmpc = *p; +- *p = *q; +- *q = tmpc; +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- *q = *p; +- *p = tmpc; +- } +- } +- } +- return ns; +-} +- +-// error is a letter was moved +-int SuggestMgr::movechar(char ** wlst, const char * word, int ns, int cpdsuggest) +-{ +- char candidate[MAXSWUTF8L]; +- char * p; +- char * q; +- char tmpc; +- +- int wl=strlen(word); +- // try moving a char +- strcpy(candidate, word); +- for (p = candidate; *p != 0; p++) { +- for (q = p + 1; (*q != 0) && ((q - p) < 10); q++) { +- tmpc = *(q-1); +- *(q-1) = *q; +- *q = tmpc; +- if ((q-p) < 2) continue; // omit swap char +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- strcpy(candidate, word); +- } +- for (p = candidate + wl - 1; p > candidate; p--) { +- for (q = p - 1; (q >= candidate) && ((p - q) < 10); q--) { +- tmpc = *(q+1); +- *(q+1) = *q; +- *q = tmpc; +- if ((p-q) < 2) continue; // omit swap char +- ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- strcpy(candidate, word); +- } +- return ns; +-} +- +-// error is a letter was moved +-int SuggestMgr::movechar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest) +-{ +- w_char candidate_utf[MAXSWL]; +- char candidate[MAXSWUTF8L]; +- w_char * p; +- w_char * q; +- w_char tmpc; +- // try moving a char +- memcpy (candidate_utf, word, wl * sizeof(w_char)); +- for (p = candidate_utf; p < (candidate_utf + wl); p++) { +- for (q = p + 1; (q < (candidate_utf + wl)) && ((q - p) < 10); q++) { +- tmpc = *(q-1); +- *(q-1) = *q; +- *q = tmpc; +- if ((q-p) < 2) continue; // omit swap char +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- memcpy (candidate_utf, word, wl * sizeof(w_char)); +- } +- for (p = candidate_utf + wl - 1; p > candidate_utf; p--) { +- for (q = p - 1; (q >= candidate_utf) && ((p - q) < 10); q--) { +- tmpc = *(q+1); +- *(q+1) = *q; +- *q = tmpc; +- if ((p-q) < 2) continue; // omit swap char +- u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl); +- ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL); +- if (ns == -1) return -1; +- } +- memcpy (candidate_utf, word, wl * sizeof(w_char)); +- } +- return ns; +-} +- +-// generate a set of suggestions for very poorly spelled words +-int SuggestMgr::ngsuggest(char** wlst, char * w, int ns, HashMgr* pHMgr) +-{ +- +- int i, j; +- int lval; +- int sc, scphon; +- int lp, lpphon; +- int nonbmp = 0; +- +- if (!pHMgr) return ns; +- +- // exhaustively search through all root words +- // keeping track of the MAX_ROOTS most similar root words +- struct hentry * roots[MAX_ROOTS]; +- char * rootsphon[MAX_ROOTS]; +- int scores[MAX_ROOTS]; +- int scoresphon[MAX_ROOTS]; +- for (i = 0; i < MAX_ROOTS; i++) { +- roots[i] = NULL; +- scores[i] = -100 * i; +- rootsphon[i] = NULL; +- scoresphon[i] = -100 * i; +- } +- lp = MAX_ROOTS - 1; +- lpphon = MAX_ROOTS - 1; +- scphon = scoresphon[MAX_ROOTS-1]; +- +- char w2[MAXWORDUTF8LEN]; +- char * word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- strcpy(w2, w); +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- word = w2; +- } +- +- char mw[MAXSWUTF8L]; +- w_char u8[MAXSWL]; +- int nc = strlen(word); +- int n = (utf8) ? u8_u16(u8, MAXSWL, word) : nc; +- +- // set character based ngram suggestion for words with non-BMP Unicode characters +- if (n == -1) { +- utf8 = 0; +- n = nc; +- nonbmp = 1; +- } +- +- struct hentry* hp = NULL; +- int col = -1; +- phonetable * ph = (pAMgr) ? pAMgr->get_phonetable() : NULL; +- char target[MAXSWUTF8L]; +- char candidate[MAXSWUTF8L]; +- if (ph) { +- strcpy(candidate, word); +- mkallcap(candidate, csconv); +- phonet(candidate, target, n, *ph); +-// fprintf(stderr, "Tip: %s->%s\n", candidate, target); +- } +- +- while ((hp = pHMgr->walk_hashtable(col, hp))) { +- if ((hp->astr) && (pAMgr) && +- (TESTAFF(hp->astr, pAMgr->get_forbiddenword(), hp->alen) || +- TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) || +- TESTAFF(hp->astr, pAMgr->get_nosuggest(), hp->alen) || +- TESTAFF(hp->astr, pAMgr->get_onlyincompound(), hp->alen))) continue; +- +- sc = ngram(3, word, &(hp->word), NGRAM_LONGER_WORSE + NGRAM_LOWERING) + +- leftcommonsubstring(word, &(hp->word)); +- +- // check special pronounciation +- if (hp->var) { +- int sc2 = ngram(3, word, &(hp->word) + hp->blen + 1, NGRAM_LONGER_WORSE + NGRAM_LOWERING) + +- leftcommonsubstring(word, &(hp->word) + hp->blen + 1); +- if (sc2 > sc) sc = sc2; +- } +- +- if (ph && (sc > 2) && (abs(n - (int) hp->clen) <= 3)) { +- char target2[MAXSWUTF8L]; +- strcpy(candidate, &(hp->word)); +- mkallcap(candidate, csconv); +- phonet(candidate, target2, -1, *ph); +- scphon = 2 * ngram(3, target, target2, NGRAM_LONGER_WORSE); +- } +- +- if (sc > scores[lp]) { +- scores[lp] = sc; +- roots[lp] = hp; +- lval = sc; +- for (j=0; j < MAX_ROOTS; j++) +- if (scores[j] < lval) { +- lp = j; +- lval = scores[j]; +- } +- } +- +- if (scphon > scoresphon[lpphon]) { +- scoresphon[lpphon] = scphon; +- rootsphon[lpphon] = &(hp->word); +- lval = scphon; +- for (j=0; j < MAX_ROOTS; j++) +- if (scoresphon[j] < lval) { +- lpphon = j; +- lval = scoresphon[j]; +- } +- } +- } +- +- // find minimum threshhold for a passable suggestion +- // mangle original word three differnt ways +- // and score them to generate a minimum acceptable score +- int thresh = 0; +- for (int sp = 1; sp < 4; sp++) { +- if (utf8) { +- for (int k=sp; k < n; k+=4) *((unsigned short *) u8 + k) = '*'; +- u16_u8(mw, MAXSWUTF8L, u8, n); +- thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING); +- } else { +- strcpy(mw, word); +- for (int k=sp; k < n; k+=4) *(mw + k) = '*'; +- thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING); +- } +- } +- thresh = thresh / 3; +- thresh--; +- +- // now expand affixes on each of these root words and +- // and use length adjusted ngram scores to select +- // possible suggestions +- char * guess[MAX_GUESS]; +- char * guessorig[MAX_GUESS]; +- int gscore[MAX_GUESS]; +- for(i=0;iexpand_rootword(glst, MAX_WORDS, &(rp->word), rp->blen, +- rp->astr, rp->alen, word, nc, +- ((rp->var) ? &(rp->word) + rp->blen + 1 : NULL)); +- +- for (int k = 0; k < nw ; k++) { +- sc = ngram(n, word, glst[k].word, NGRAM_ANY_MISMATCH + NGRAM_LOWERING) + +- leftcommonsubstring(word, glst[k].word); +- +- if ((sc > thresh)) { +- if (sc > gscore[lp]) { +- if (guess[lp]) { +- free (guess[lp]); +- if (guessorig[lp]) { +- free(guessorig[lp]); +- guessorig[lp] = NULL; +- } +- } +- gscore[lp] = sc; +- guess[lp] = glst[k].word; +- guessorig[lp] = glst[k].orig; +- lval = sc; +- for (j=0; j < MAX_GUESS; j++) +- if (gscore[j] < lval) { +- lp = j; +- lval = gscore[j]; +- } +- } else { +- free(glst[k].word); +- if (glst[k].orig) free(glst[k].orig); +- } +- } else { +- free(glst[k].word); +- if (glst[k].orig) free(glst[k].orig); +- } +- } +- } +- } +- free(glst); +- +- // now we are done generating guesses +- // sort in order of decreasing score +- +- +- bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS); +- if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS); +- +- // weight suggestions with a similarity index, based on +- // the longest common subsequent algorithm and resort +- +- int is_swap; +- for (i=0; i < MAX_GUESS; i++) { +- if (guess[i]) { +- // lowering guess[i] +- char gl[MAXSWUTF8L]; +- int len; +- if (utf8) { +- w_char _w[MAXSWL]; +- len = u8_u16(_w, MAXSWL, guess[i]); +- mkallsmall_utf(_w, len, langnum); +- u16_u8(gl, MAXSWUTF8L, _w, len); +- } else { +- strcpy(gl, guess[i]); +- mkallsmall(gl, csconv); +- len = strlen(guess[i]); +- } +- +- int _lcs = lcslen(word, gl); +- +- // same characters with different casing +- if ((n == len) && (n == _lcs)) { +- gscore[i] += 2000; +- break; +- } +- +- // heuristic weigthing of ngram scores +- gscore[i] += +- // length of longest common subsequent minus length difference +- 2 * _lcs - abs((int) (n - len)) + +- // weight length of the left common substring +- leftcommonsubstring(word, gl) + +- // weight equal character positions +- ((_lcs == commoncharacterpositions(word, gl, &is_swap)) ? 1: 0) + +- // swap character (not neighboring) +- ((is_swap) ? 1000 : 0); +- } +- } +- +- bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS); +- +-// phonetic version +- if (ph) for (i=0; i < MAX_ROOTS; i++) { +- if (rootsphon[i]) { +- // lowering rootphon[i] +- char gl[MAXSWUTF8L]; +- int len; +- if (utf8) { +- w_char _w[MAXSWL]; +- len = u8_u16(_w, MAXSWL, rootsphon[i]); +- mkallsmall_utf(_w, len, langnum); +- u16_u8(gl, MAXSWUTF8L, _w, len); +- } else { +- strcpy(gl, rootsphon[i]); +- mkallsmall(gl, csconv); +- len = strlen(rootsphon[i]); +- } +- +- // heuristic weigthing of ngram scores +- scoresphon[i] += 2 * lcslen(word, gl) - abs((int) (n - len)) + +- // weight length of the left common substring +- leftcommonsubstring(word, gl); +- } +- } +- +- if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS); +- +- // copy over +- int oldns = ns; +- +- int same = 0; +- for (i=0; i < MAX_GUESS; i++) { +- if (guess[i]) { +- if ((ns < oldns + maxngramsugs) && (ns < maxSug) && (!same || (gscore[i] > 1000))) { +- int unique = 1; +- // leave only excellent suggestions, if exists +- if (gscore[i] > 1000) same = 1; +- for (j = 0; j < ns; j++) { +- // don't suggest previous suggestions or a previous suggestion with prefixes or affixes +- if ((!guessorig[i] && strstr(guess[i], wlst[j])) || +- (guessorig[i] && strstr(guessorig[i], wlst[j])) || +- // check forbidden words +- !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) unique = 0; +- } +- if (unique) { +- wlst[ns++] = guess[i]; +- if (guessorig[i]) { +- free(guess[i]); +- wlst[ns-1] = guessorig[i]; +- } +- } else { +- free(guess[i]); +- if (guessorig[i]) free(guessorig[i]); +- } +- } else { +- free(guess[i]); +- if (guessorig[i]) free(guessorig[i]); +- } +- } +- } +- +- oldns = ns; +- if (ph) for (i=0; i < MAX_ROOTS; i++) { +- if (rootsphon[i]) { +- if ((ns < oldns + MAXPHONSUGS) && (ns < maxSug)) { +- int unique = 1; +- for (j = 0; j < ns; j++) { +- // don't suggest previous suggestions or a previous suggestion with prefixes or affixes +- if (strstr(rootsphon[i], wlst[j]) || +- // check forbidden words +- !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) unique = 0; +- } +- if (unique) wlst[ns++] = mystrdup(rootsphon[i]); +- } +- } +- } +- +- if (nonbmp) utf8 = 1; +- return ns; +-} +- +- +-// see if a candidate suggestion is spelled correctly +-// needs to check both root words and words with affixes +- +-// obsolote MySpell-HU modifications: +-// return value 2 and 3 marks compounding with hyphen (-) +-// `3' marks roots without suffix +-int SuggestMgr::checkword(const char * word, int len, int cpdsuggest, int * timer, clock_t * timelimit) +-{ +- struct hentry * rv=NULL; +- int nosuffix = 0; +- +- // check time limit +- if (timer) { +- (*timer)--; +- if (!(*timer) && timelimit) { +- if ((clock() - *timelimit) > TIMELIMIT) return 0; +- *timer = MAXPLUSTIMER; +- } +- } +- +- if (pAMgr) { +- if (cpdsuggest==1) { +- if (pAMgr->get_compound()) { +- rv = pAMgr->compound_check(word,len,0,0,0,0,NULL,0,NULL,NULL,1); +- if (rv) return 3; // XXX obsolote categorisation +- } +- return 0; +- } +- +- rv = pAMgr->lookup(word); +- +- if (rv) { +- if ((rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen) +- || TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen))) return 0; +- while (rv) { +- if (rv->astr && (TESTAFF(rv->astr,pAMgr->get_pseudoroot(),rv->alen) || +- TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) || +- TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) { +- rv = rv->next_homonym; +- } else break; +- } +- } else rv = pAMgr->prefix_check(word, len, 0); // only prefix, and prefix + suffix XXX +- +- if (rv) { +- nosuffix=1; +- } else { +- rv = pAMgr->suffix_check(word, len, 0, NULL, NULL, 0, NULL); // only suffix +- } +- +- if (!rv && pAMgr->have_contclass()) { +- rv = pAMgr->suffix_check_twosfx(word, len, 0, NULL, FLAG_NULL); +- if (!rv) rv = pAMgr->prefix_check_twosfx(word, len, 1, FLAG_NULL); +- } +- +- // check forbidden words +- if ((rv) && (rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen) || +- TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) || +- TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen) || +- TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) return 0; +- +- if (rv) { // XXX obsolote +- if ((pAMgr->get_compoundflag()) && +- TESTAFF(rv->astr, pAMgr->get_compoundflag(), rv->alen)) return 2 + nosuffix; +- return 1; +- } +- } +- return 0; +-} +- +-int SuggestMgr::check_forbidden(const char * word, int len) +-{ +- struct hentry * rv = NULL; +- +- if (pAMgr) { +- rv = pAMgr->lookup(word); +- if (rv && rv->astr && (TESTAFF(rv->astr,pAMgr->get_pseudoroot(),rv->alen) || +- TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) rv = NULL; +- if (!(pAMgr->prefix_check(word,len,1))) +- rv = pAMgr->suffix_check(word,len, 0, NULL, NULL, 0, NULL); // prefix+suffix, suffix +- // check forbidden words +- if ((rv) && (rv->astr) && TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen)) return 1; +- } +- return 0; +-} +- +-#ifdef HUNSPELL_EXPERIMENTAL +-// suggest stems, XXX experimental code +-int SuggestMgr::suggest_stems(char*** slst, const char * w, int nsug) +-{ +- char buf[MAXSWUTF8L]; +- char ** wlst; +- int prevnsug = nsug; +- +- char w2[MAXWORDUTF8LEN]; +- const char * word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- strcpy(w2, w); +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- word = w2; +- } +- +- if (*slst) { +- wlst = *slst; +- } else { +- wlst = (char **) calloc(maxSug, sizeof(char *)); +- if (wlst == NULL) return -1; +- } +- // perhaps there are a fix stem in the dictionary +- if ((nsug < maxSug) && (nsug > -1)) { +- +- nsug = fixstems(wlst, word, nsug); +- if (nsug == prevnsug) { +- char * s = mystrdup(word); +- char * p = s + strlen(s); +- while ((*p != '-') && (p != s)) p--; +- if (*p == '-') { +- *p = '\0'; +- nsug = fixstems(wlst, s, nsug); +- if ((nsug == prevnsug) && (nsug < maxSug) && (nsug >= 0)) { +- char * t; +- buf[0] = '\0'; +- for (t = s; (t[0] != '\0') && ((t[0] >= '0') || (t[0] <= '9')); t++); // is a number? +- if (*t != '\0') strcpy(buf, "# "); +- strcat(buf, s); +- wlst[nsug] = mystrdup(buf); +- if (wlst[nsug] == NULL) return -1; +- nsug++; +- } +- p++; +- nsug = fixstems(wlst, p, nsug); +- } +- +- free(s); +- } +- } +- +- if (nsug < 0) { +- for (int i=0;ilookup(word); +- if (rv) { +- dicstem = 0; +- } else { +- // try stripping off affixes +- rv = pAMgr->affix_check(word, wl); +- +- // else try check compound word +- if (!rv && pAMgr->get_compound()) { +- rv = pAMgr->compound_check(word, wl, +- 0, 0, 100, 0, NULL, 0, &cmpdstemnum, cmpdstem,1); +- +- if (rv) { +- dicstem = 2; +- for (int j = 0; j < cmpdstemnum; j++) { +- cpdindex += cmpdstem[j]; +- } +- if(! (pAMgr->lookup(word + cpdindex))) +- pAMgr->affix_check(word + cpdindex, wl - cpdindex); // for prefix +- } +- } +- +- +- if (pAMgr->get_prefix()) { +- strcpy(prefix, pAMgr->get_prefix()); +- } +- +- // XXX obsolete, will be a general solution for stemming +- if ((prefix) && (strncmp(prefix, "leg", 3)==0)) prefix[0] = '\0'; // (HU) +- } +- +- } +- +- +- +- if ((rv) && (ns < maxSug)) { +- +- // check fixstem flag and not_valid_stem flag +- // first word +- if ((ns < maxSug) && (dicstem < 2)) { +- strcpy(buf, prefix); +- if ((dicstem > 0) && pAMgr->get_derived()) { +- // XXX obsolote +- if (strlen(prefix) == 1) { +- strcat(buf, (pAMgr->get_derived()) + 1); +- } else { +- strcat(buf, pAMgr->get_derived()); +- } +- } else { +- // special stem in affix description +- const char * wordchars = pAMgr->get_wordchars(); +- if (rv->description && +- (strchr(wordchars, *(rv->description)))) { +- char * desc = (rv->description) + 1; +- while (strchr(wordchars, *desc)) desc++; +- strncat(buf, rv->description, desc - (rv->description)); +- } else { +- strcat(buf, rv->word); +- } +- } +- wlst[ns] = mystrdup(buf); +- if (wlst[ns] == NULL) return -1; +- ns++; +- } +- +- if (dicstem == 2) { +- +- // compound stem +- +-// if (rv->astr && (strchr(rv->astr, '0') == NULL)) { +- if (rv->astr) { +- strcpy(buf, word); +- buf[cpdindex] = '\0'; +- if (prefix) strcat(buf, prefix); +- if (pAMgr->get_derived()) { +- strcat(buf, pAMgr->get_derived()); +- } else { +- // special stem in affix description +- const char * wordchars = pAMgr->get_wordchars(); +- if (rv->description && +- (strchr(wordchars, *(rv->description)))) { +- char * desc = (rv->description) + 1; +- while (strchr(wordchars, *desc)) desc++; +- strncat(buf, rv->description, desc - (rv->description)); +- } else { +- strcat(buf, rv->word); +- } +- } +- if (ns < maxSug) { +- wlst[ns] = mystrdup(buf); +- if (wlst[ns] == NULL) return -1; +- ns++; +- } +- } +- } +- } +- return ns; +-} +- +-// suggest possible stems +-int SuggestMgr::suggest_pos_stems(char*** slst, const char * w, int nsug) +-{ +- char ** wlst; +- +- struct hentry * rv = NULL; +- +- char w2[MAXSWUTF8L]; +- const char * word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- strcpy(w2, w); +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- word = w2; +- } +- +- int wl = strlen(word); +- +- +- if (*slst) { +- wlst = *slst; +- } else { +- wlst = (char **) calloc(maxSug, sizeof(char *)); +- if (wlst == NULL) return -1; +- } +- +- rv = pAMgr->suffix_check(word, wl, 0, NULL, wlst, maxSug, &nsug); +- +- // delete dash from end of word +- if (nsug > 0) { +- for (int j=0; j < nsug; j++) { +- if (wlst[j][strlen(wlst[j]) - 1] == '-') wlst[j][strlen(wlst[j]) - 1] = '\0'; +- } +- } +- +- *slst = wlst; +- return nsug; +-} +- +- +-char * SuggestMgr::suggest_morph(const char * w) +-{ +- char result[MAXLNLEN]; +- char * r = (char *) result; +- char * st; +- +- struct hentry * rv = NULL; +- +- *result = '\0'; +- +- if (! pAMgr) return NULL; +- +- char w2[MAXSWUTF8L]; +- const char * word = w; +- +- // word reversing wrapper for complex prefixes +- if (complexprefixes) { +- strcpy(w2, w); +- if (utf8) reverseword_utf(w2); else reverseword(w2); +- word = w2; +- } +- +- rv = pAMgr->lookup(word); +- +- while (rv) { +- if ((!rv->astr) || !(TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) || +- TESTAFF(rv->astr, pAMgr->get_pseudoroot(), rv->alen) || +- TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) { +- if (rv->description && ((!rv->astr) || +- !TESTAFF(rv->astr, pAMgr->get_lemma_present(), rv->alen))) +- strcat(result, word); +- if (rv->description) strcat(result, rv->description); +- strcat(result, "\n"); +- } +- rv = rv->next_homonym; +- } +- +- st = pAMgr->affix_check_morph(word,strlen(word)); +- if (st) { +- strcat(result, st); +- free(st); +- } +- +- if (pAMgr->get_compound() && (*result == '\0')) +- pAMgr->compound_check_morph(word, strlen(word), +- 0, 0, 100, 0,NULL, 0, &r, NULL); +- +- return (*result) ? mystrdup(line_uniq(delete_zeros(result))) : NULL; +-} +- +-char * SuggestMgr::suggest_morph_for_spelling_error(const char * word) +-{ +- char * p = NULL; +- char ** wlst = (char **) calloc(maxSug, sizeof(char *)); +- if (!**wlst) return NULL; +- // we will use only the first suggestion +- for (int i = 0; i < maxSug - 1; i++) wlst[i] = ""; +- int ns = suggest(&wlst, word, maxSug - 1); +- if (ns == maxSug) { +- p = suggest_morph(wlst[maxSug - 1]); +- free(wlst[maxSug - 1]); +- } +- if (wlst) free(wlst); +- return p; +-} +-#endif // END OF HUNSPELL_EXPERIMENTAL CODE +- +- +-// generate an n-gram score comparing s1 and s2 +-int SuggestMgr::ngram(int n, char * s1, const char * s2, int opt) +-{ +- int nscore = 0; +- int ns; +- int l1; +- int l2; +- +- if (utf8) { +- w_char su1[MAXSWL]; +- w_char su2[MAXSWL]; +- l1 = u8_u16(su1, MAXSWL, s1); +- l2 = u8_u16(su2, MAXSWL, s2); +- if ((l2 <= 0) || (l1 == -1)) return 0; +- // lowering dictionary word +- if (opt & NGRAM_LOWERING) mkallsmall_utf(su2, l2, langnum); +- for (int j = 1; j <= n; j++) { +- ns = 0; +- for (int i = 0; i <= (l1-j); i++) { +- for (int l = 0; l <= (l2-j); l++) { +- int k; +- for (k = 0; (k < j); k++) { +- w_char * c1 = su1 + i + k; +- w_char * c2 = su2 + l + k; +- if ((c1->l != c2->l) || (c1->h != c2->h)) break; +- } +- if (k == j) { +- ns++; +- break; +- } +- } +- } +- nscore = nscore + ns; +- if (ns < 2) break; +- } +- } else { +- char t[MAXSWUTF8L]; +- l1 = strlen(s1); +- l2 = strlen(s2); +- if (l2 == 0) return 0; +- strcpy(t, s2); +- if (opt & NGRAM_LOWERING) mkallsmall(t, csconv); +- for (int j = 1; j <= n; j++) { +- ns = 0; +- for (int i = 0; i <= (l1-j); i++) { +- char c = *(s1 + i + j); +- *(s1 + i + j) = '\0'; +- if (strstr(t,(s1+i))) ns++; +- *(s1 + i + j ) = c; +- } +- nscore = nscore + ns; +- if (ns < 2) break; +- } +- } +- +- ns = 0; +- if (opt & NGRAM_LONGER_WORSE) ns = (l2-l1)-2; +- if (opt & NGRAM_ANY_MISMATCH) ns = abs(l2-l1)-2; +- ns = (nscore - ((ns > 0) ? ns : 0)); +- return ns; +-} +- +-// length of the left common substring of s1 and (decapitalised) s2 +-int SuggestMgr::leftcommonsubstring(char * s1, const char * s2) { +- if (utf8) { +- w_char su1[MAXSWL]; +- w_char su2[MAXSWL]; +- // decapitalize dictionary word +- if (complexprefixes) { +- int l1 = u8_u16(su1, MAXSWL, s1); +- int l2 = u8_u16(su2, MAXSWL, s2); +- if (*((short *)su1+l1-1) == *((short *)su2+l2-1)) return 1; +- } else { +- int i; +- u8_u16(su1, 1, s1); +- u8_u16(su2, 1, s2); +- unsigned short idx = (su2->h << 8) + su2->l; +- if (*((short *)su1) != *((short *)su2) && +- (*((unsigned short *)su1) != unicodetolower(idx, langnum))) return 0; +- int l1 = u8_u16(su1, MAXSWL, s1); +- int l2 = u8_u16(su2, MAXSWL, s2); +- for(i = 1; (i < l1) && (i < l2) && +- (*((short *)(su1 + i)) == *((short *)(su2 + i))); i++); +- return i; +- } +- } else { +- if (complexprefixes) { +- int l1 = strlen(s1); +- int l2 = strlen(s2); +- if (*(s2+l1-1) == *(s2+l2-1)) return 1; +- } else { +- char * olds = s1; +- // decapitalise dictionary word +- if ((*s1 != *s2) && (*s1 != csconv[((unsigned char)*s2)].clower)) return 0; +- do { +- s1++; s2++; +- } while ((*s1 == *s2) && (*s1 != '\0')); +- return s1 - olds; +- } +- } +- return 0; +-} +- +-int SuggestMgr::commoncharacterpositions(char * s1, const char * s2, int * is_swap) { +- int num = 0; +- int diff = 0; +- int diffpos[2]; +- *is_swap = 0; +- if (utf8) { +- w_char su1[MAXSWL]; +- w_char su2[MAXSWL]; +- int l1 = u8_u16(su1, MAXSWL, s1); +- int l2 = u8_u16(su2, MAXSWL, s2); +- // decapitalize dictionary word +- if (complexprefixes) { +- mkallsmall_utf(su2+l2-1, 1, langnum); +- } else { +- mkallsmall_utf(su2, 1, langnum); +- } +- for (int i = 0; (i < l1) && (i < l2); i++) { +- if (((short *) su1)[i] == ((short *) su2)[i]) { +- num++; +- } else { +- if (diff < 2) diffpos[diff] = i; +- diff++; +- } +- } +- if ((diff == 2) && (l1 == l2) && +- (((short *) su1)[diffpos[0]] == ((short *) su2)[diffpos[1]]) && +- (((short *) su1)[diffpos[1]] == ((short *) su2)[diffpos[0]])) *is_swap = 1; +- } else { +- int i; +- char t[MAXSWUTF8L]; +- strcpy(t, s2); +- // decapitalize dictionary word +- if (complexprefixes) { +- int l2 = strlen(t); +- *(t+l2-1) = csconv[((unsigned char)*(t+l2-1))].clower; +- } else { +- mkallsmall(t, csconv); +- } +- for (i = 0; (*(s1+i) != 0) && (*(t+i) != 0); i++) { +- if (*(s1+i) == *(t+i)) { +- num++; +- } else { +- if (diff < 2) diffpos[diff] = i; +- diff++; +- } +- } +- if ((diff == 2) && (*(s1+i) == 0) && (*(t+i) == 0) && +- (*(s1+diffpos[0]) == *(t+diffpos[1])) && +- (*(s1+diffpos[1]) == *(t+diffpos[0]))) *is_swap = 1; +- } +- return num; +-} +- +-int SuggestMgr::mystrlen(const char * word) { +- if (utf8) { +- w_char w[MAXSWL]; +- return u8_u16(w, MAXSWL, word); +- } else return strlen(word); +-} +- +-// sort in decreasing order of score +-void SuggestMgr::bubblesort(char** rword, char** rword2, int* rsc, int n ) +-{ +- int m = 1; +- while (m < n) { +- int j = m; +- while (j > 0) { +- if (rsc[j-1] < rsc[j]) { +- int sctmp = rsc[j-1]; +- char * wdtmp = rword[j-1]; +- rsc[j-1] = rsc[j]; +- rword[j-1] = rword[j]; +- rsc[j] = sctmp; +- rword[j] = wdtmp; +- if (rword2) { +- wdtmp = rword2[j-1]; +- rword2[j-1] = rword2[j]; +- rword2[j] = wdtmp; +- } +- j--; +- } else break; +- } +- m++; +- } +- return; +-} +- +-// longest common subsequence +-void SuggestMgr::lcs(const char * s, const char * s2, int * l1, int * l2, char ** result) { +- int n, m; +- w_char su[MAXSWL]; +- w_char su2[MAXSWL]; +- char * b; +- char * c; +- int i; +- int j; +- if (utf8) { +- m = u8_u16(su, MAXSWL, s); +- n = u8_u16(su2, MAXSWL, s2); +- } else { +- m = strlen(s); +- n = strlen(s2); +- } +- c = (char *) malloc((m + 1) * (n + 1)); +- b = (char *) malloc((m + 1) * (n + 1)); +- if (!c || !b) { +- if (c) free(c); +- if (b) free(b); +- *result = NULL; +- return; +- } +- for (i = 1; i <= m; i++) c[i*(n+1)] = 0; +- for (j = 0; j <= n; j++) c[j] = 0; +- for (i = 1; i <= m; i++) { +- for (j = 1; j <= n; j++) { +- if ((utf8) && (*((short *) su+i-1) == *((short *)su2+j-1)) +- || (!utf8) && ((*(s+i-1)) == (*(s2+j-1)))) { +- c[i*(n+1) + j] = c[(i-1)*(n+1) + j-1]+1; +- b[i*(n+1) + j] = LCS_UPLEFT; +- } else if (c[(i-1)*(n+1) + j] >= c[i*(n+1) + j-1]) { +- c[i*(n+1) + j] = c[(i-1)*(n+1) + j]; +- b[i*(n+1) + j] = LCS_UP; +- } else { +- c[i*(n+1) + j] = c[i*(n+1) + j-1]; +- b[i*(n+1) + j] = LCS_LEFT; +- } +- } +- } +- *result = b; +- free(c); +- *l1 = m; +- *l2 = n; +-} +- +-int SuggestMgr::lcslen(const char * s, const char* s2) { +- int m; +- int n; +- int i; +- int j; +- char * result; +- int len = 0; +- lcs(s, s2, &m, &n, &result); +- if (!result) return 0; +- i = m; +- j = n; +- while ((i != 0) && (j != 0)) { +- if (result[i*(n+1) + j] == LCS_UPLEFT) { +- len++; +- i--; +- j--; +- } else if (result[i*(n+1) + j] == LCS_UP) { +- i--; +- } else j--; +- } +- free(result); +- return len; +-} +Index: mozilla/extensions/spellcheck/hunspell/src/suggestmgr.hxx +=================================================================== +--- mozilla.orig/extensions/spellcheck/hunspell/src/suggestmgr.hxx ++++ /dev/null +@@ -1,160 +0,0 @@ +-/******* BEGIN LICENSE BLOCK ******* +- * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * The contents of this file are subject to the Mozilla Public License Version +- * 1.1 (the "License"); you may not use this file except in compliance with +- * the License. You may obtain a copy of the License at +- * http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS IS" basis, +- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +- * for the specific language governing rights and limitations under the +- * License. +- * +- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) +- * and László Németh (Hunspell). Portions created by the Initial Developers +- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. +- * +- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) +- * David Einstein (deinst@world.std.com) +- * László Németh (nemethl@gyorsposta.hu) +- * Davide Prina +- * Giuseppe Modugno +- * Gianluca Turconi +- * Simon Brouwer +- * Noll Janos +- * Biro Arpad +- * Goldman Eleonora +- * Sarlos Tamas +- * Bencsath Boldizsar +- * Halacsy Peter +- * Dvornik Laszlo +- * Gefferth Andras +- * Nagy Viktor +- * Varga Daniel +- * Chris Halls +- * Rene Engelhard +- * Bram Moolenaar +- * Dafydd Jones +- * Harri Pitkanen +- * Andras Timar +- * Tor Lillqvist +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the MPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the MPL, the GPL or the LGPL. +- * +- ******* END LICENSE BLOCK *******/ +- +-#ifndef _SUGGESTMGR_HXX_ +-#define _SUGGESTMGR_HXX_ +- +-#define MAXSWL 100 +-#define MAXSWUTF8L (MAXSWL * 4) +-#define MAX_ROOTS 100 +-#define MAX_WORDS 100 +-#define MAX_GUESS 200 +-#define MAXNGRAMSUGS 4 +-#define MAXPHONSUGS 2 +- +-// timelimit: max ~1/4 sec (process time on Linux) for a time consuming function +-#define TIMELIMIT (CLOCKS_PER_SEC >> 2) +-#define MINTIMER 100 +-#define MAXPLUSTIMER 100 +- +-#define NGRAM_LONGER_WORSE (1 << 0) +-#define NGRAM_ANY_MISMATCH (1 << 1) +-#define NGRAM_LOWERING (1 << 2) +- +-#include "atypes.hxx" +-#include "affixmgr.hxx" +-#include "hashmgr.hxx" +-#include "langnum.hxx" +-#include +- +-enum { LCS_UP, LCS_LEFT, LCS_UPLEFT }; +- +-class SuggestMgr +-{ +- char * ckey; +- int ckeyl; +- w_char * ckey_utf; +- +- char * ctry; +- int ctryl; +- w_char * ctry_utf; +- +- AffixMgr* pAMgr; +- int maxSug; +- struct cs_info * csconv; +- int utf8; +- int langnum; +- int nosplitsugs; +- int maxngramsugs; +- int complexprefixes; +- +- +-public: +- SuggestMgr(const char * tryme, int maxn, AffixMgr *aptr); +- ~SuggestMgr(); +- +- int suggest(char*** slst, const char * word, int nsug, int * onlycmpdsug); +- int ngsuggest(char ** wlst, char * word, int ns, HashMgr* pHMgr); +- int suggest_auto(char*** slst, const char * word, int nsug); +- int suggest_stems(char*** slst, const char * word, int nsug); +- int suggest_pos_stems(char*** slst, const char * word, int nsug); +- +- char * suggest_morph(const char * word); +- char * suggest_morph_for_spelling_error(const char * word); +- +-private: +- int testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest, +- int * timer, clock_t * timelimit); +- int checkword(const char *, int, int, int *, clock_t *); +- int check_forbidden(const char *, int); +- +- int capchars(char **, const char *, int, int); +- int replchars(char**, const char *, int, int); +- int doubletwochars(char**, const char *, int, int); +- int forgotchar(char **, const char *, int, int); +- int swapchar(char **, const char *, int, int); +- int longswapchar(char **, const char *, int, int); +- int movechar(char **, const char *, int, int); +- int extrachar(char **, const char *, int, int); +- int badcharkey(char **, const char *, int, int); +- int badchar(char **, const char *, int, int); +- int twowords(char **, const char *, int, int); +- int fixstems(char **, const char *, int); +- +- int capchars_utf(char **, const w_char *, int wl, int, int); +- int doubletwochars_utf(char**, const w_char *, int wl, int, int); +- int forgotchar_utf(char**, const w_char *, int wl, int, int); +- int extrachar_utf(char**, const w_char *, int wl, int, int); +- int badcharkey_utf(char **, const w_char *, int wl, int, int); +- int badchar_utf(char **, const w_char *, int wl, int, int); +- int swapchar_utf(char **, const w_char *, int wl, int, int); +- int longswapchar_utf(char **, const w_char *, int, int, int); +- int movechar_utf(char **, const w_char *, int, int, int); +- +- int mapchars(char**, const char *, int, int); +- int map_related(const char *, int, char ** wlst, int, int, const mapentry*, int, int *, clock_t *); +- int map_related_utf(w_char *, int, int, int, char ** wlst, int, const mapentry*, int, int *, clock_t *); +- int ngram(int n, char * s1, const char * s2, int opt); +- int mystrlen(const char * word); +- int leftcommonsubstring(char * s1, const char * s2); +- int commoncharacterpositions(char * s1, const char * s2, int * is_swap); +- void bubblesort( char ** rwd, char ** rwd2, int * rsc, int n); +- void lcs(const char * s, const char * s2, int * l1, int * l2, char ** result); +- int lcslen(const char * s, const char* s2); +- +-}; +- +-#endif +Index: mozilla/extensions/spellcheck/src/Makefile.in +=================================================================== +--- mozilla.orig/extensions/spellcheck/src/Makefile.in ++++ mozilla/extensions/spellcheck/src/Makefile.in +@@ -77,16 +77,22 @@ + $(NULL) + + ifeq (camino,$(MOZ_BUILD_APP)) + SHARED_LIBRARY_LIBS += ../osxspell/src/$(LIB_PREFIX)osxspell_s.$(LIB_SUFFIX) + LOCAL_INCLUDES += -I$(srcdir)/../osxspell/src + else + SHARED_LIBRARY_LIBS += ../hunspell/src/$(LIB_PREFIX)hunspell_s.$(LIB_SUFFIX) + LOCAL_INCLUDES += -I$(srcdir)/../hunspell/src ++ifndef MOZ_NATIVE_HUNSPELL ++LOCAL_INCLUDES += -I$(srcdir)/../hunspell/hunspell ++SHARED_LIBRARY_LIBS += ../hunspell/hunspell/$(LIB_PREFIX)libhunspell_s.$(LIB_SUFFIX) ++else ++LOCAL_INCLUDES += $(MOZ_HUNSPELL_CFLAGS) ++endif + endif + + EXTRA_DSO_LDOPTS = \ + $(LIBS_DIR) \ + $(MOZ_COMPONENT_LIBS) \ + $(MOZ_UNICHARUTIL_LIBS) \ + $(MOZ_HUNSPELL_LIBS) \ + $(NULL) +Index: mozilla/extensions/spellcheck/hunspell/hunspell/Makefile.in +=================================================================== +--- /dev/null ++++ mozilla/extensions/spellcheck/hunspell/hunspell/Makefile.in +@@ -0,0 +1,66 @@ ++# ****** BEGIN LICENSE BLOCK ****** ++# Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++# ++# The contents of this file are subject to the Mozilla Public License Version ++# 1.1 (the "License"); you may not use this file except in compliance with ++# the License. You may obtain a copy of the License at ++# http://www.mozilla.org/MPL/ ++# ++# Software distributed under the License is distributed on an "AS IS" basis, ++# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++# for the specific language governing rights and limitations under the ++# License. ++# ++# The Initial Developers of the Original Code are Kevin Hendricks (MySpell) ++# and László Németh (Hunspell). Portions created by the Initial Developers ++# are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. ++# ++# Contributor(s): David Einstein (deinst@world.std.com) ++# László Németh (nemethl@gyorsposta.hu) ++# Ryan VanderMeulen (ryanvm@gmail.com) ++# ++# Alternatively, the contents of this file may be used under the terms of ++# either the GNU General Public License Version 2 or later (the "GPL"), or ++# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++# in which case the provisions of the GPL or the LGPL are applicable instead ++# of those above. If you wish to allow use of your version of this file only ++# under the terms of either the GPL or the LGPL, and not to allow others to ++# use your version of this file under the terms of the MPL, indicate your ++# decision by deleting the provisions above and replace them with the notice ++# and other provisions required by the GPL or the LGPL. If you do not delete ++# the provisions above, a recipient may use your version of this file under ++# the terms of any one of the MPL, the GPL or the LGPL. ++# ++# ****** END LICENSE BLOCK ****** ++ ++DEPTH = ../../../.. ++topsrcdir = @top_srcdir@ ++srcdir = @srcdir@ ++VPATH = @srcdir@ ++ ++include $(DEPTH)/config/autoconf.mk ++ ++MODULE = hunspell ++LIBRARY_NAME = libhunspell_s ++FORCE_STATIC_LIB = 1 ++LIBXUL_LIBRARY = 1 ++ ++REQUIRES = xpcom \ ++ string \ ++ uconv \ ++ unicharutil \ ++ spellchecker \ ++ xulapp \ ++ $(NULL) ++ ++CPPSRCS += affentry.cpp \ ++ affixmgr.cpp \ ++ csutil.cpp \ ++ hashmgr.cpp \ ++ hunspell.cpp \ ++ phonet.cpp \ ++ suggestmgr.cpp \ ++ $(NULL) ++ ++include $(topsrcdir)/config/rules.mk ++ --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_deb469020_lockPref_everywhere.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_deb469020_lockPref_everywhere.patch @@ -0,0 +1,94 @@ +--- xulrunner-1.9~rc2.orig/modules/libpref/src/prefread.cpp ++++ xulrunner-1.9~rc2/modules/libpref/src/prefread.cpp +@@ -75,6 +75,7 @@ + #define BITS_PER_HEX_DIGIT 4 + + static const char kUserPref[] = "user_pref"; ++static const char kLockPref[] = "lockPref"; + static const char kPref[] = "pref"; + static const char kTrue[] = "true"; + static const char kFalse[] = "false"; +@@ -161,7 +162,7 @@ + default: + break; + } +- (*ps->reader)(ps->closure, ps->lb, value, ps->vtype, ps->fdefault); ++ (*ps->reader)(ps->closure, ps->lb, value, ps->vtype, ps->fdefault, ps->flock); + return PR_TRUE; + } + +@@ -220,6 +221,7 @@ + ps->vb = NULL; + ps->vtype = PREF_INVALID; + ps->fdefault = PR_FALSE; ++ ps->flock = PR_FALSE; + } + switch (c) { + case '/': /* begin comment block or line? */ +@@ -230,7 +232,9 @@ + break; + case 'u': /* indicating user_pref */ + case 'p': /* indicating pref */ +- ps->smatch = (c == 'u' ? kUserPref : kPref); ++ case 'l': /* indicating lockPref */ ++ ps->smatch = (c == 'u' ? kUserPref : ++ (c == 'p' ? kPref : kLockPref)); + ps->sindex = 1; + ps->nextstate = PREF_PARSE_UNTIL_OPEN_PAREN; + state = PREF_PARSE_MATCH_STRING; +@@ -274,7 +278,8 @@ + /* name parsing */ + case PREF_PARSE_UNTIL_NAME: + if (c == '\"' || c == '\'') { +- ps->fdefault = (ps->smatch == kPref); ++ ps->fdefault = (ps->smatch != kUserPref); ++ ps->flock = (ps->smatch == kLockPref); + ps->quotechar = c; + ps->nextstate = PREF_PARSE_UNTIL_COMMA; /* return here when done */ + state = PREF_PARSE_QUOTED_STRING; +--- xulrunner-1.9~rc2.orig/modules/libpref/src/prefread.h ++++ xulrunner-1.9~rc2/modules/libpref/src/prefread.h +@@ -62,7 +62,8 @@ + const char *pref, + PrefValue val, + PrefType type, +- PRBool defPref); ++ PRBool defPref, ++ PRBool lockPref); + + /* structure fields are private */ + typedef struct PrefParseState { +@@ -83,6 +84,7 @@ + char *vb; /* value buffer (ptr into lb) */ + PrefType vtype; /* PREF_STRING,INT,BOOL */ + PRBool fdefault; /* PR_TRUE if (default) pref */ ++ PRBool flock; /* PR_TRUE if pref to be locked */ + } PrefParseState; + + /** +--- xulrunner-1.9~rc2.orig/modules/libpref/src/prefapi.cpp ++++ xulrunner-1.9~rc2/modules/libpref/src/prefapi.cpp +@@ -957,7 +957,10 @@ + const char *pref, + PrefValue value, + PrefType type, +- PRBool isDefault) ++ PRBool isDefault, ++ PRBool isLocked) + { + pref_HashPref(pref, value, type, isDefault); ++ if (isLocked) ++ PREF_LockPref(pref, PR_TRUE); + } +--- xulrunner-1.9~rc2.orig/modules/libpref/src/prefapi.h ++++ xulrunner-1.9~rc2/modules/libpref/src/prefapi.h +@@ -207,7 +207,8 @@ + const char *pref, + PrefValue value, + PrefType type, +- PRBool isDefault); ++ PRBool isDefault, ++ PRBool isLocked); + + NSPR_END_EXTERN_C + #endif --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_sysplugin_support.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_sysplugin_support.patch @@ -0,0 +1,87 @@ +Debian compatibility patch that is supposed to make xulrunner also +consider /usr/lib/mozilla/plugins/ in sid as of xulrunner 1.9~rc2-4 + +--- +--- + xpcom/io/nsAppFileLocationProvider.cpp | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +Index: mozilla/xpcom/io/nsAppFileLocationProvider.cpp +=================================================================== +--- mozilla.orig/xpcom/io/nsAppFileLocationProvider.cpp ++++ mozilla/xpcom/io/nsAppFileLocationProvider.cpp +@@ -94,16 +94,18 @@ + // Locally defined keys used by nsAppDirectoryEnumerator + #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH + #define NS_USER_PLUGINS_DIR "UserPlugins" + + #ifdef XP_MACOSX + #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins" + #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins" + #define NS_MAC_CLASSIC_PLUGIN_DIR "MacSysPlugins" ++#elif XP_UNIX ++#define NS_SYSTEM_PLUGINS_DIR "SysPlugins" + #endif + + #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults") + #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref") + #define DEFAULTS_SYSPREF_DIR_NAME NS_LITERAL_CSTRING("syspref") + #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile") + #define RES_DIR_NAME NS_LITERAL_CSTRING("res") + #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome") +@@ -265,16 +267,23 @@ + rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), PR_TRUE, getter_AddRefs(localFile)); + } + else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0) + { + rv = GetProductDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); + } ++#ifdef XP_UNIX ++ else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) { ++ static const char *const sysLPlgDir = "/usr/lib/mozilla/plugins"; ++ rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir), ++ PR_FALSE, getter_AddRefs(localFile)); ++ } ++#endif + #endif + else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0) + { + rv = CloneMozBinDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME); + } + else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0) +@@ -630,29 +639,29 @@ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nsnull; + nsresult rv = NS_ERROR_FAILURE; + + if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST)) + { + #ifdef XP_MACOSX + static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull }; +- static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull }; ++ static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, NS_SYSTEM_PLUGINS_DIR, nsnull }; + static const char** keys; + + if (!keys) { + OSErr err; + long response; + err = ::Gestalt(gestaltSystemVersion, &response); + keys = (!err && response >= 0x00001000) ? osXKeys : os9Keys; + } + + *_retval = new nsAppDirectoryEnumerator(this, keys); + #else +- static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, nsnull }; ++ static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nsnull }; + if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) { + static const char nullstr = 0; + keys[0] = &nullstr; + } + *_retval = new nsPathsDirectoryEnumerator(this, keys); + #endif + NS_IF_ADDREF(*_retval); + rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/jemalloc_in_xul.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/jemalloc_in_xul.patch @@ -0,0 +1,62 @@ +--- + xulrunner/app/Makefile.in | 10 ++++++++++ + xulrunner/stub/Makefile.in | 10 ++++++++++ + 2 files changed, 20 insertions(+) + +Index: mozilla/xulrunner/app/Makefile.in +=================================================================== +--- mozilla.orig/xulrunner/app/Makefile.in ++++ mozilla/xulrunner/app/Makefile.in +@@ -173,16 +173,25 @@ + RESFILE=splashos2.res + RCFLAGS += -DMOZ_XULRUNNER + ifdef DEBUG + RCFLAGS += -DDEBUG + endif + RCFLAGS += -DXULRUNNER_ICO=\"$(DIST)/branding/xulrunner.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" + endif + ++ifdef MOZ_MEMORY ++ifneq ($(OS_ARCH),WINNT) ++LIBS += \ ++ -L$(DEPTH)/memory/jemalloc/ \ ++ -ljemalloc \ ++ $(NULL) ++endif ++endif ++ + include $(topsrcdir)/config/rules.mk + + DEFINES += -DXULRUNNER_ICO=\"$(DIST)/branding/xulrunner.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" + + ifeq ($(MOZ_WIDGET_TOOLKIT),photon) + LIBS += -lphexlib + endif + +Index: mozilla/xulrunner/stub/Makefile.in +=================================================================== +--- mozilla.orig/xulrunner/stub/Makefile.in ++++ mozilla/xulrunner/stub/Makefile.in +@@ -92,13 +92,22 @@ + endif + + include $(topsrcdir)/config/config.mk + + ifdef _MSC_VER + WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup + endif + ++ifdef MOZ_MEMORY ++ifneq ($(OS_ARCH),WINNT) ++LIBS += \ ++ -L$(DEPTH)/memory/jemalloc/ \ ++ -ljemalloc \ ++ $(NULL) ++endif ++endif ++ + include $(topsrcdir)/config/rules.mk + + ifeq ($(OS_ARCH),WINNT) + OS_LIBS += $(call EXPAND_LIBNAME,shell32) + endif --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/add_syspref_dir.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/add_syspref_dir.patch @@ -0,0 +1,148 @@ +--- + modules/libpref/src/nsPrefService.cpp | 8 ++++++++ + toolkit/xre/nsXREDirProvider.cpp | 4 ++++ + xpcom/io/nsAppDirectoryServiceDefs.h | 1 + + xpcom/io/nsAppFileLocationProvider.cpp | 10 ++++++++++ + 4 files changed, 23 insertions(+) + +Index: mozilla/toolkit/xre/nsXREDirProvider.cpp +=================================================================== +--- mozilla.orig/toolkit/xre/nsXREDirProvider.cpp ++++ mozilla/toolkit/xre/nsXREDirProvider.cpp +@@ -609,16 +609,17 @@ + nsCOMPtr subdir; + while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(subdir))) && subdir) { + mAppBundleDirectories.AppendObject(subdir); + LoadPlatformDirectory(subdir, mAppBundleDirectories); + } + } + + static const char *const kAppendPrefDir[] = { "defaults", "preferences", nsnull }; ++static const char *const kAppendSysPrefDir[] = { "defaults", "syspref", nsnull }; + + #ifdef DEBUG_bsmedberg + static void + DumpFileArray(const char *key, + nsCOMArray dirs) + { + fprintf(stderr, "nsXREDirProvider::GetFilesInternal(%s)\n", key); + +@@ -665,16 +666,19 @@ + else if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST)) { + nsCOMArray directories; + + LoadBundleDirectories(); + + LoadAppDirIntoArray(mXULAppDir, kAppendPrefDir, directories); + LoadDirsIntoArray(mAppBundleDirectories, + kAppendPrefDir, directories); ++ LoadAppDirIntoArray(mXULAppDir, kAppendSysPrefDir, directories); ++ LoadDirsIntoArray(mAppBundleDirectories, ++ kAppendSysPrefDir, directories); + + rv = NS_NewArrayEnumerator(aResult, directories); + } + else if (!strcmp(aProperty, NS_EXT_PREFS_DEFAULTS_DIR_LIST)) { + nsCOMArray directories; + + LoadBundleDirectories(); + LoadDirsIntoArray(mExtensionDirectories, +Index: mozilla/modules/libpref/src/nsPrefService.cpp +=================================================================== +--- mozilla.orig/modules/libpref/src/nsPrefService.cpp ++++ mozilla/modules/libpref/src/nsPrefService.cpp +@@ -807,16 +807,24 @@ + #endif + }; + + rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles)); + if (NS_FAILED(rv)) { + NS_WARNING("Error parsing application default preferences."); + } + ++ /* now, parse the "application" default system preferences */ ++ rv = NS_GetSpecialDirectory(NS_APP_SYSPREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir)); ++ NS_ENSURE_SUCCESS(rv, rv); ++ rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles)); ++ if (NS_FAILED(rv)) { ++ NS_WARNING("Error parsing application default preferences."); ++ } ++ + rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST); + NS_ENSURE_SUCCESS(rv, rv); + + NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, + nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID); + + nsCOMPtr observerService = + do_GetService("@mozilla.org/observer-service;1", &rv); +Index: mozilla/xpcom/io/nsAppDirectoryServiceDefs.h +=================================================================== +--- mozilla.orig/xpcom/io/nsAppDirectoryServiceDefs.h ++++ mozilla/xpcom/io/nsAppDirectoryServiceDefs.h +@@ -58,16 +58,17 @@ + // Files and directories which exist on a per-product basis + // -------------------------------------------------------------------------------------- + + #define NS_APP_APPLICATION_REGISTRY_FILE "AppRegF" + #define NS_APP_APPLICATION_REGISTRY_DIR "AppRegD" + + #define NS_APP_DEFAULTS_50_DIR "DefRt" // The root dir of all defaults dirs + #define NS_APP_PREF_DEFAULTS_50_DIR "PrfDef" ++#define NS_APP_SYSPREF_DEFAULTS_50_DIR "SysPrfDef" + #define NS_APP_PROFILE_DEFAULTS_50_DIR "profDef" // The profile defaults of the "current" + // locale. Should be first choice. + #define NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR "ProfDefNoLoc" // The profile defaults of the "default" + // installed locale. Second choice + // when above is not available. + + #define NS_APP_USER_PROFILES_ROOT_DIR "DefProfRt" // The dir where user profile dirs live. + #define NS_APP_USER_PROFILES_LOCAL_ROOT_DIR "DefProfLRt" // The dir where user profile temp dirs live. +Index: mozilla/xpcom/io/nsAppFileLocationProvider.cpp +=================================================================== +--- mozilla.orig/xpcom/io/nsAppFileLocationProvider.cpp ++++ mozilla/xpcom/io/nsAppFileLocationProvider.cpp +@@ -98,16 +98,17 @@ + #ifdef XP_MACOSX + #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins" + #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins" + #define NS_MAC_CLASSIC_PLUGIN_DIR "MacSysPlugins" + #endif + + #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults") + #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref") ++#define DEFAULTS_SYSPREF_DIR_NAME NS_LITERAL_CSTRING("syspref") + #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile") + #define RES_DIR_NAME NS_LITERAL_CSTRING("res") + #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome") + #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins") + #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins") + + //***************************************************************************** + // nsAppFileLocationProvider::Constructor/Destructor +@@ -164,16 +165,25 @@ + { + rv = CloneMozBinDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) { + rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME); + } + } ++ else if (nsCRT::strcmp(prop, NS_APP_SYSPREF_DEFAULTS_50_DIR) == 0) ++ { ++ rv = CloneMozBinDirectory(getter_AddRefs(localFile)); ++ if (NS_SUCCEEDED(rv)) { ++ rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); ++ if (NS_SUCCEEDED(rv)) ++ rv = localFile->AppendRelativeNativePath(DEFAULTS_SYSPREF_DIR_NAME); ++ } ++ } + else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 || + nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0) + { + rv = CloneMozBinDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) { + rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME); --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz449188_att350098_plugin_for_mimetype_pref.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz449188_att350098_plugin_for_mimetype_pref.patch @@ -0,0 +1,73 @@ +Introduce a new preference that allows users to set a preferred +plugin for a given mime-type. + +For example: + + pref ("modules.plugins.mimetype.application/x-shockwave-flash", "libflashplayer.so") + +would make the plugin with libflashplayer.so filename the preferred choice for the +encoded content type. + +If there is no such match, we just go ahead and search for the first match for the +requested mime-type. + +--- + modules/plugin/base/src/nsPluginHostImpl.cpp | 33 +++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +Index: mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +=================================================================== +--- mozilla.orig/modules/plugin/base/src/nsPluginHostImpl.cpp ++++ mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +@@ -4493,18 +4493,51 @@ + nsPluginTag *plugins = nsnull; + PRInt32 variants, cnt; + + LoadPlugins(); + + // if we have a mimetype passed in, search the mPlugins + // linked list for a match + if (nsnull != aMimeType) { ++ nsresult res; ++ nsCOMPtr prefB (do_QueryInterface(mPrefService)); ++ ++ char *preferredPluginPath = NULL; ++ nsCAutoString mimetypePrefString ("modules.plugins.mimetype."); ++ mimetypePrefString.Append(aMimeType); ++ const char *mimetypePrefChar = mimetypePrefString.get(); ++ res = prefB->GetCharPref(mimetypePrefChar, &preferredPluginPath); ++ ++ if(!NS_SUCCEEDED(res)) preferredPluginPath = NULL; ++ + plugins = mPlugins; ++ if(preferredPluginPath) { ++ while (nsnull != plugins) { ++ if (0 == PL_strcasecmp(plugins->mFileName.get(), preferredPluginPath) || ++ 0 == PL_strcasecmp(plugins->mFullPath.get(), preferredPluginPath)) { ++ return plugins; ++ } ++ plugins = plugins->mNext; ++ } + ++ // now lets search for substrings ++ plugins=mPlugins; ++ while (nsnull != plugins) { ++ if (nsnull != PL_strstr(plugins->mFileName.get(), preferredPluginPath) || ++ nsnull != PL_strstr(plugins->mFullPath.get(), preferredPluginPath)) { ++ return plugins; ++ } ++ plugins = plugins->mNext; ++ } ++ } ++ ++ // if there is no pref for this mime-type, or if the plugin named in pref ++ // isn't found, we pick the first that matches for this mime-type ++ plugins = mPlugins; + while (nsnull != plugins) { + variants = plugins->mVariants; + + for (cnt = 0; cnt < variants; cnt++) { + if ((!aCheckEnabled || plugins->IsEnabled()) && + plugins->mMimeTypeArray[cnt] && + (0 == PL_strcasecmp(plugins->mMimeTypeArray[cnt], aMimeType))) { + return plugins; --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_urlclassifier_prefs_in_toolkit.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_urlclassifier_prefs_in_toolkit.patch @@ -0,0 +1,37 @@ +--- + toolkit/components/url-classifier/Makefile.in | 3 + toolkit/components/url-classifier/pref/url-classifier.js | 8 + + toolkit/components/url-classifier/src/nsUrlClassifierDBService.cpp | 62 +++++++--- + 3 files changed, 59 insertions(+), 14 deletions(-) + +Index: mozilla/toolkit/components/url-classifier/pref/url-classifier.js +=================================================================== +--- /dev/null ++++ mozilla/toolkit/components/url-classifier/pref/url-classifier.js +@@ -0,0 +1,8 @@ ++ ++// Maximum size of the sqlite3 cache during an update, in bytes ++#ifdef MOZ_WIDGET_GTK2 ++pref("urlclassifier.updatecachemax", 104857600); ++#else ++pref("urlclassifier.updatecachemax", -1); ++#endif ++ +Index: mozilla/toolkit/components/url-classifier/Makefile.in +=================================================================== +--- mozilla.orig/toolkit/components/url-classifier/Makefile.in ++++ mozilla/toolkit/components/url-classifier/Makefile.in +@@ -46,10 +46,13 @@ + DIRS = public src + + ifdef ENABLE_TESTS + ifndef MOZ_ENABLE_LIBXUL + TOOL_DIRS += tests + endif + endif + ++PREF_JS_EXPORTS = $(srcdir)/pref/url-classifier.js ++GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/,url-classifier.js) ++ + include $(topsrcdir)/config/rules.mk + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz436133_att322801.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz436133_att322801.patch @@ -0,0 +1,80 @@ +Cherry Pick for Mozilla Bug: + 436133 - "Cookies build failure on hppa" + https://bugzilla.mozilla.org/show_bug.cgi?id=436133 + +From Attachment: + https://bugzilla.mozilla.org/attachment.cgi?id=322801 + +-- +Index: configure.in +=================================================================== +RCS file: /cvsroot/mozilla/configure.in,v +retrieving revision 1.1992 +diff -u -b -B -u -8 -p -r1.1992 configure.in +--- a/configure.in 5 May 2008 21:08:14 -0000 1.1992 ++++ b/configure.in 28 May 2008 16:45:58 -0000 +@@ -1237,16 +1237,20 @@ case "$OS_TEST" in + powerpc* | ppc) + CPU_ARCH=ppc + ;; + + Alpha | alpha | ALPHA) + CPU_ARCH=Alpha + ;; + ++hppa* | parisc) ++ CPU_ARCH=hppa ++ ;; ++ + sun4u | sparc*) + CPU_ARCH=sparc + ;; + + x86_64 | ia64) + CPU_ARCH="$OS_TEST" + ;; + esac +@@ -1287,19 +1291,19 @@ if test "$GNU_CC"; then + # -Wall - turn on all warnings + # -pedantic - make compiler warn about non-ANSI stuff, and + # be a little bit stricter + # Warnings slamm took out for now (these were giving more noise than help): + # -Wbad-function-cast - warns when casting a function to a new return type + # -Wconversion - complained when char's or short's were used a function args + # -Wshadow - removed because it generates more noise than help --pete + _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith" +- if test "$CPU_ARCH" != "ia64" && test "$CPU_ARCH" != "sparc" \ ++ if test "$CPU_ARCH" != "hppa" && test "$CPU_ARCH" != "ia64" && test "$CPU_ARCH" != "sparc" \ + && test -z "$INTEL_CC"; then +- # don't use -Wcast-align on ia64 or sparc, it's noisy on those platforms ++ # don't use -Wcast-align on hppa, ia64 or sparc, it's noisy on those platforms + # icc doesn't support this flag. + _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align" + fi + + dnl Turn pedantic on but disable the warnings for long long + _PEDANTIC=1 + + if test -z "$INTEL_CC"; then +@@ -1327,19 +1331,19 @@ else + _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT' + fi + + if test "$GNU_CXX"; then + # FIXME: Let us build with strict aliasing. bug 414641. + CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" + # Turn on GNU specific features + _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wconversion -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor" +- if test "$CPU_ARCH" != "ia64" && test "$CPU_ARCH" != "sparc" \ ++ if test "$CPU_ARCH" != "hppa" && test "$CPU_ARCH" != "ia64" && test "$CPU_ARCH" != "sparc" \ + && test -z "$INTEL_CC"; then +- # don't use -Wcast-align on ia64 or sparc, it's noisy on those platforms ++ # don't use -Wcast-align on hppa, ia64 or sparc, it's noisy on those platforms + # icc doesn't support this flag. + _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wcast-align" + fi + + _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h' + _USE_CPP_INCLUDE_FLAG=1 + else + _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)' --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/system_path_launch_child.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/system_path_launch_child.patch @@ -0,0 +1,62 @@ +--- + toolkit/xre/nsAppRunner.cpp | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +Index: mozilla/toolkit/xre/nsAppRunner.cpp +=================================================================== +--- mozilla.orig/toolkit/xre/nsAppRunner.cpp 2008-07-28 04:13:09.000000000 +0200 ++++ mozilla/toolkit/xre/nsAppRunner.cpp 2008-09-12 23:57:41.000000000 +0200 +@@ -1557,32 +1557,52 @@ + } + + PR_SetEnv("MOZ_LAUNCHED_CHILD=1"); + + #if defined(XP_MACOSX) + LaunchChildMac(gRestartArgc, gRestartArgv); + #else + nsCOMPtr lf; ++ nsCOMPtr sf = nsnull; // system-file + nsresult rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf)); + if (NS_FAILED(rv)) + return rv; + ++ ++ nsCString nativeLeaf; ++ rv = lf->GetNativeLeafName(nativeLeaf); ++ if (NS_FAILED(rv)) ++ return rv; ++ ++ nsCString systemPath = NS_LITERAL_CSTRING("/usr/bin/") + nativeLeaf; ++ rv = NS_NewNativeLocalFile(nsDependentCString(systemPath), PR_TRUE, ++ getter_AddRefs(sf)); ++ PRBool sfExists = false; ++ rv = sf->Exists(&sfExists); ++ ++ if (NS_FAILED(rv) || !sfExists) ++ sf = nsnull; // we gracefully accept if there is no binary for system path ++ + #if defined(XP_WIN) + nsAutoString exePath; + rv = lf->GetPath(exePath); + if (NS_FAILED(rv)) + return rv; + + if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, 0)) + return NS_ERROR_FAILURE; + + #else + nsCAutoString exePath; +- rv = lf->GetNativePath(exePath); ++ if (sf) ++ rv = sf->GetNativePath(exePath); ++ else ++ rv = lf->GetNativePath(exePath); ++ + if (NS_FAILED(rv)) + return rv; + + #if defined(XP_OS2) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3) + // implementation of _execv() is broken with GCC 3.3.x on OS/2 + if (OS2LaunchChild(exePath.get(), gRestartArgc, gRestartArgv) == -1) + return NS_ERROR_FAILURE; + #elif defined(XP_OS2) --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz372826_att337031_about_style.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz372826_att337031_about_style.patch @@ -0,0 +1,175 @@ +--- + toolkit/content/about.xhtml | 2 -- + toolkit/content/buildconfig.html.in | 3 ++- + toolkit/content/license.html | 4 +++- + toolkit/themes/winstripe/global/about.css | 14 +++++++------- + 4 files changed, 12 insertions(+), 11 deletions(-) + +Index: mozilla/toolkit/content/about.xhtml +=================================================================== +--- mozilla.orig/toolkit/content/about.xhtml ++++ mozilla/toolkit/content/about.xhtml +@@ -53,17 +53,16 @@ + + + + About: + + + + +-
+ + +
    +@@ -93,11 +92,10 @@ + var list = document.getElementById("aboutPageList"); + var listItem = list.appendChild(document.createElement("li")); + listItem.appendChild(document.createTextNode("&about.buildIdentifier;")); + listItem.appendChild(document.createTextNode(ua)); + } + +
+ +-
+ + +Index: mozilla/toolkit/content/buildconfig.html.in +=================================================================== +--- mozilla.orig/toolkit/content/buildconfig.html.in ++++ mozilla/toolkit/content/buildconfig.html.in +@@ -1,14 +1,15 @@ + + + + about:buildconfig ++ + +- ++ +

about:buildconfig

+

+

Build platform

+ + + + + +Index: mozilla/toolkit/content/license.html +=================================================================== +--- mozilla.orig/toolkit/content/license.html ++++ mozilla/toolkit/content/license.html +@@ -16,16 +16,17 @@ + - The Original Code is mozilla.org code. + - + - The Initial Developer of the Original Code is + - Gervase Markham. + - Portions created by the Initial Developer are Copyright (C) 2006 + - the Initial Developer. All Rights Reserved. + - + - Contributor(s): ++ - Ehsan Akhgari + - + - Alternatively, the contents of this file may be used under the terms of + - either the GNU General Public License Version 2 or later (the "GPL"), or + - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + - in which case the provisions of the GPL or the LGPL are applicable instead + - of those above. If you wish to allow use of your version of this file only + - under the terms of either the GPL or the LGPL, and not to allow others to + - use your version of this file under the terms of the MPL, indicate your +@@ -57,16 +58,17 @@ + dd p { + margin: 0; + } + + .gnu-number { + font-weight: bold; + } + ++ + + + + +- ++ +

about:license

+ +
+ + #ifdef APP_EULA_BLOCK + #includesubst @APP_EULA_BLOCK@ + #endif + +Index: mozilla/toolkit/themes/winstripe/global/about.css +=================================================================== +--- mozilla.orig/toolkit/themes/winstripe/global/about.css ++++ mozilla/toolkit/themes/winstripe/global/about.css +@@ -1,33 +1,29 @@ + html { + background: -moz-Dialog; +-} +- +-body { +- margin: 0; + padding: 0 1em; +- color: -moz-FieldText; + font: message-box; + } + +-#aboutPageContainer { ++body { ++ color: -moz-FieldText; + position: relative; + min-width: 330px; + max-width: 50em; + margin: 4em auto; + border: 1px solid ThreeDShadow; + -moz-border-radius: 10px; + padding: 3em; + -moz-padding-start: 30px; + background: -moz-Field; + } + + .aboutPageWideContainer { +- max-width: 80% !important; ++ max-width: 80%; + } + + #aboutLogoContainer { + border: 1px solid ThreeDLightShadow; + width: 300px; + margin-bottom: 2em; + } + +@@ -46,8 +42,12 @@ + -moz-margin-start: 1.5em; + padding: 0; + list-style: square; + } + + ul > li { + margin-top: .5em; + } ++ ++th, td { ++ padding: 0 5px; ++} --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/series +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/series @@ -0,0 +1,28 @@ +installer_use_stdout_for_missing_files.patch +dont_install_so_in_dev.patch +rename_venkman_addon.patch +protect_tests_by_ifdefs.patch +dom_inspector_support_for_prism.patch +bzXXX_pc_honour_system_nspr_nss.patch +bzXXX_no_zlib_export_if_native.patch +bzXXX_gre_extension_plugin_support.patch +bz233371_att297343_fix_outofscreen_embed_tooltip.patch +bzXXX_attXXX_fix_remember_password_for_embedders_without_branding.patch +add_syspref_dir.patch +bzXXX_autoconfig_in_gre.patch +bzXXX_gre_autoreg.patch +bzXXX-dont-reset-user-prefs-on-upgrade.patch +bzXXX_urlclassifier_prefs_in_toolkit.patch +bz368428_attachment_308130.patch +bz429747_att317495+move_hunspell_1.2.patch +bz436133_att322801.patch +bzXXX_deb469020_lockPref_everywhere.patch +bzXXX_sysplugin_support.patch +bzXXX_sysplugin_support_xre_part.patch +#jemalloc_in_xul.patch +#jemalloc_static.patch +bz449188_att350098_plugin_for_mimetype_pref.patch +bz412610_att335369_realpath_overflow.patch +system_path_launch_child.patch +bz372826_att337031_about_style.patch +ARMEL_Wno_error_in_network_cookie_src.patch --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/dont_install_so_in_dev.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/dont_install_so_in_dev.patch @@ -0,0 +1,28 @@ +--- + toolkit/mozapps/installer/packager.mk | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +Index: mozilla/toolkit/mozapps/installer/packager.mk +=================================================================== +--- mozilla.orig/toolkit/mozapps/installer/packager.mk ++++ mozilla/toolkit/mozapps/installer/packager.mk +@@ -419,17 +419,18 @@ + (cd $(DESTDIR)$(idldir)/stable && tar -xf -) + (cd $(DIST)/idl && tar $(TAR_CREATE_FLAGS) - .) | \ + (cd $(DESTDIR)$(idldir)/unstable && tar -xf -) + # SDK directory is the libs + a bunch of symlinks + $(NSINSTALL) -D $(DESTDIR)$(sdkdir)/sdk/lib + if test -f $(DIST)/sdk/include/xpcom-config.h; then \ + $(SYSINSTALL) $(IFLAGS1) $(DIST)/sdk/include/xpcom-config.h $(DESTDIR)$(sdkdir); \ + fi +- (cd $(DIST)/sdk/lib && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DESTDIR)$(sdkdir)/sdk/lib && tar -xf -) ++ (cd $(DIST)/sdk/lib && tar --exclude='*.so' $(TAR_CREATE_FLAGS) - .) | (cd $(DESTDIR)$(sdkdir)/sdk/lib && tar -xf -) ++ ln -s $(addprefix $(installdir)/,$(notdir $(wildcard $(DIST)/sdk/lib/*.so))) $(DESTDIR)$(sdkdir)/sdk/lib + $(RM) -f $(DESTDIR)$(sdkdir)/lib $(DESTDIR)$(sdkdir)/bin $(DESTDIR)$(sdkdir)/sdk/include $(DESTDIR)$(sdkdir)/include $(DESTDIR)$(sdkdir)/sdk/idl $(DESTDIR)$(sdkdir)/idl + ln -s $(sdkdir)/sdk/lib $(DESTDIR)$(sdkdir)/lib + ln -s $(installdir) $(DESTDIR)$(sdkdir)/bin + ln -s $(includedir)/stable $(DESTDIR)$(sdkdir)/sdk/include + ln -s $(includedir)/unstable $(DESTDIR)$(sdkdir)/include + ln -s $(idldir)/stable $(DESTDIR)$(sdkdir)/sdk/idl + ln -s $(idldir)/unstable $(DESTDIR)$(sdkdir)/idl + endif # INSTALL_SDK --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz368428_attachment_308130.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz368428_attachment_308130.patch @@ -0,0 +1,147 @@ + + * fix Bug 368428 – XUL FastLoad cache corruption when application running + while upgrading ... updated patch with "antiLockZipGrip" + +-- +--- + modules/libjar/nsJAR.cpp | 18 ++++++++++++++++-- + modules/libjar/nsJAR.h | 5 +++++ + 2 files changed, 21 insertions(+), 2 deletions(-) + +Index: mozilla/modules/libjar/nsJAR.cpp +=================================================================== +--- mozilla.orig/modules/libjar/nsJAR.cpp ++++ mozilla/modules/libjar/nsJAR.cpp +@@ -122,16 +122,17 @@ + + // The following initialization makes a guess of 10 entries per jarfile. + nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10), + mParsedManifest(PR_FALSE), + mGlobalStatus(JAR_MANIFEST_NOT_PARSED), + mReleaseTime(PR_INTERVAL_NO_TIMEOUT), + mCache(nsnull), + mLock(nsnull), ++ mMtime(0), + mTotalItemsInManifest(0) + { + } + + nsJAR::~nsJAR() + { + Close(); + } +@@ -162,26 +163,30 @@ + + //---------------------------------------------- + // nsIZipReader implementation + //---------------------------------------------- + + NS_IMETHODIMP + nsJAR::Open(nsIFile* zipFile) + { ++ NS_ENSURE_TRUE(zipFile, NS_ERROR_FAILURE); + if (mLock) return NS_ERROR_FAILURE; // Already open! + + mZipFile = zipFile; ++ nsresult rv = zipFile->GetLastModifiedTime(&mMtime); ++ if (NS_FAILED(rv)) return rv; ++ + mLock = PR_NewLock(); + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); + + PRFileDesc *fd = OpenFile(); + NS_ENSURE_TRUE(fd, NS_ERROR_FAILURE); + +- nsresult rv = mZip.OpenArchive(fd); ++ rv = mZip.OpenArchive(fd); + if (NS_FAILED(rv)) Close(); + + return rv; + } + + NS_IMETHODIMP + nsJAR::GetFile(nsIFile* *result) + { +@@ -1116,35 +1121,44 @@ + #endif + } + + NS_IMETHODIMP + nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result) + { + NS_ENSURE_ARG_POINTER(zipFile); + nsresult rv; ++ nsCOMPtr antiLockZipGrip; + nsAutoLock lock(mLock); + + #ifdef ZIP_CACHE_HIT_RATE + mZipCacheLookups++; + #endif + + nsCAutoString path; + rv = zipFile->GetNativePath(path); + if (NS_FAILED(rv)) return rv; + ++ PRInt64 Mtime; ++ rv = zipFile->GetLastModifiedTime(&Mtime); ++ if (NS_FAILED(rv)) return rv; ++ + nsCStringKey key(path); + nsJAR* zip = static_cast(static_cast(mZips.Get(&key))); // AddRefs +- if (zip) { ++ if (zip && Mtime == zip->GetMtime()) { + #ifdef ZIP_CACHE_HIT_RATE + mZipCacheHits++; + #endif + zip->ClearReleaseTime(); + } + else { ++ if (zip) { ++ antiLockZipGrip = zip; ++ mZips.Remove(&key); ++ } + zip = new nsJAR(); + if (zip == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(zip); + zip->SetZipReaderCache(this); + + rv = zip->Open(zipFile); + if (NS_FAILED(rv)) { +Index: mozilla/modules/libjar/nsJAR.h +=================================================================== +--- mozilla.orig/modules/libjar/nsJAR.h ++++ mozilla/modules/libjar/nsJAR.h +@@ -128,27 +128,32 @@ + void ClearReleaseTime() { + mReleaseTime = PR_INTERVAL_NO_TIMEOUT; + } + + void SetZipReaderCache(nsZipReaderCache* cache) { + mCache = cache; + } + ++ PRInt64 GetMtime() { ++ return mMtime; ++ } ++ + protected: + //-- Private data members + nsCOMPtr mZipFile; // The zip/jar file on disk + nsZipArchive mZip; // The underlying zip archive + nsObjectHashtable mManifestData; // Stores metadata for each entry + PRBool mParsedManifest; // True if manifest has been parsed + nsCOMPtr mPrincipal; // The entity which signed this file + PRInt16 mGlobalStatus; // Global signature verification status + PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries + nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in + PRLock* mLock; ++ PRInt64 mMtime; + PRInt32 mTotalItemsInManifest; + + //-- Private functions + PRFileDesc* OpenFile(); + + nsresult ParseManifest(); + void ReportError(const char* aFilename, PRInt16 errorCode); + nsresult LoadEntry(const char* aFilename, char** aBuf, --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/dom_inspector_support_for_prism.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/dom_inspector_support_for_prism.patch @@ -0,0 +1,34 @@ +--- + extensions/inspector/install.rdf | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: mozilla/extensions/inspector/install.rdf +=================================================================== +--- mozilla.orig/extensions/inspector/install.rdf ++++ mozilla/extensions/inspector/install.rdf +@@ -40,16 +40,25 @@ + + {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} + 2.0a + 2.0.* + + + + ++ ++ ++ prism@developer.mozilla.org ++ 0.4 ++ 1.0.0.* ++ ++ ++ ++ + + + toolkit@mozilla.org + 1.9a1 + 1.9.0.* + + + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_gre_autoreg.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_gre_autoreg.patch @@ -0,0 +1,82 @@ +Index: xpcom/build/nsXPComInit.cpp +=================================================================== +RCS file: /cvsroot/mozilla/xpcom/build/nsXPComInit.cpp,v +retrieving revision 1.261 +diff -u -p -8 -r1.261 nsXPComInit.cpp +--- a/xpcom/build/nsXPComInit.cpp 8 Mar 2008 09:50:29 -0000 1.261 ++++ b/xpcom/build/nsXPComInit.cpp 2 Apr 2008 20:39:53 -0000 +@@ -284,52 +284,63 @@ RegisterGenericFactory(nsIComponentRegis + // In order to support the installer, we need + // to be told out of band if we should cause + // an autoregister. If the file ".autoreg" exists in the binary + // directory, we check its timestamp against the timestamp of the + // compreg.dat file. If the .autoreg file is newer, we autoregister. + static PRBool CheckUpdateFile() + { + nsresult rv; +- nsCOMPtr file; ++ ++ nsCOMPtr pfile; + rv = nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), +- getter_AddRefs(file)); +- ++ getter_AddRefs(pfile)); + if (NS_FAILED(rv)) { + NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed"); + return PR_FALSE; + } ++ pfile->AppendNative(nsDependentCString(".autoreg")); ++ PRBool pexists; ++ pfile->Exists(&pexists); + +- file->AppendNative(nsDependentCString(".autoreg")); +- +- PRBool exists; +- file->Exists(&exists); +- if (!exists) ++ ++ nsCOMPtr gfile; ++ rv = nsDirectoryService::gService->Get(NS_GRE_DIR, ++ NS_GET_IID(nsIFile), ++ getter_AddRefs(gfile)); ++ gfile->AppendNative(nsDependentCString(".autoreg")); ++ PRBool gexists; ++ gfile->Exists(&gexists); ++ ++ ++ if (!pexists && !gexists) + return PR_FALSE; + + nsCOMPtr compregFile; + rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE, + NS_GET_IID(nsIFile), + getter_AddRefs(compregFile)); + + + if (NS_FAILED(rv)) { + NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed"); + return PR_FALSE; + } + ++ PRBool exists; + if (NS_FAILED(compregFile->Exists(&exists)) || !exists) + return PR_TRUE; + +- PRInt64 compregModTime, autoregModTime; ++ PRInt64 compregModTime, autoreg1ModTime, autoreg2ModTime; + compregFile->GetLastModifiedTime(&compregModTime); +- file->GetLastModifiedTime(&autoregModTime); ++ pfile->GetLastModifiedTime(&autoreg1ModTime); ++ gfile->GetLastModifiedTime(&autoreg2ModTime); + +- return LL_CMP(autoregModTime, >, compregModTime); ++ return LL_CMP(PR_MAX(autoreg1ModTime, autoreg2ModTime), >, compregModTime); + } + + + nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL; + PRBool gXPCOMShuttingDown = PR_FALSE; + + // For each class that wishes to support nsIClassInfo, add a line like this + // NS_DECL_CLASSINFO(nsMyClass) --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_attXXX_fix_remember_password_for_embedders_without_branding.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_attXXX_fix_remember_password_for_embedders_without_branding.patch @@ -0,0 +1,35 @@ +Index: ./toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js +=================================================================== +RCS file: /cvsroot/mozilla/toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js,v +retrieving revision 1.30 +diff -u -p -8 -r1.30 nsLoginManagerPrompter.js +--- a/toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js 9 Mar 2008 02:25:40 -0000 1.30 ++++ b/toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js 9 Mar 2008 23:33:24 -0000 +@@ -560,18 +560,25 @@ LoginManagerPrompter.prototype = { + this._getLocalizedString("notifyBarRememberButtonText"); + var rememberButtonAccessKey = + this._getLocalizedString("notifyBarRememberButtonAccessKey"); + var notNowButtonText = + this._getLocalizedString("notifyBarNotNowButtonText"); + var notNowButtonAccessKey = + this._getLocalizedString("notifyBarNotNowButtonAccessKey"); + +- var brandShortName = +- this._brandBundle.GetStringFromName("brandShortName"); ++ // XXX asac: anything more reasonable than "" we can guess for ++ // embedders that don't provide branding?) ++ var brandShortName = ""; ++ try { ++ brandShortName = ++ this._brandBundle.GetStringFromName("brandShortName"); ++ } catch (e) { ++ this.log ("no brandShortName available for prompting - most likely incomplete embedding."); ++ } + var notificationText = this._getLocalizedString( + "savePasswordText", [brandShortName]); + + // The callbacks in |buttons| have a closure to access the variables + // in scope here; set one to |this._pwmgr| so we can get back to pwmgr + // without a getService() call. + var pwmgr = this._pwmgr; + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz412610_att335369_realpath_overflow.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz412610_att335369_realpath_overflow.patch @@ -0,0 +1,83 @@ +--- + toolkit/mozapps/update/src/updater/updater.cpp | 4 +++- + toolkit/xre/nsAppRunner.h | 6 +++++- + xpcom/build/nsXPCOMPrivate.h | 1 + + 3 files changed, 9 insertions(+), 2 deletions(-) + +Index: mozilla/toolkit/mozapps/update/src/updater/updater.cpp +=================================================================== +--- mozilla.orig/toolkit/mozapps/update/src/updater/updater.cpp ++++ mozilla/toolkit/mozapps/update/src/updater/updater.cpp +@@ -113,17 +113,19 @@ + # define NULL (0) + #endif + + #ifndef SSIZE_MAX + # define SSIZE_MAX LONG_MAX + #endif + + #ifndef MAXPATHLEN +-# ifdef MAX_PATH ++# ifdef PATH_MAX ++# define MAXPATHLEN PATH_MAX ++# elif defined(_MAX_PATH) + # define MAXPATHLEN MAX_PATH + # elif defined(_MAX_PATH) + # define MAXPATHLEN _MAX_PATH + # elif defined(CCHMAXPATH) + # define MAXPATHLEN CCHMAXPATH + # else + # define MAXPATHLEN 1024 + # endif +Index: mozilla/toolkit/xre/nsAppRunner.h +=================================================================== +--- mozilla.orig/toolkit/xre/nsAppRunner.h ++++ mozilla/toolkit/xre/nsAppRunner.h +@@ -35,20 +35,24 @@ + * + * ***** END LICENSE BLOCK ***** */ + + #ifndef nsAppRunner_h__ + #define nsAppRunner_h__ + + #ifdef XP_WIN + #include ++#else ++#include + #endif + + #ifndef MAXPATHLEN +-#ifdef _MAX_PATH ++#ifdef PATH_MAX ++#define MAXPATHLEN PATH_MAX ++#elif defined(_MAX_PATH) + #define MAXPATHLEN _MAX_PATH + #elif defined(CCHMAXPATH) + #define MAXPATHLEN CCHMAXPATH + #else + #define MAXPATHLEN 1024 + #endif + #endif + +Index: mozilla/xpcom/build/nsXPCOMPrivate.h +=================================================================== +--- mozilla.orig/xpcom/build/nsXPCOMPrivate.h ++++ mozilla/xpcom/build/nsXPCOMPrivate.h +@@ -226,16 +226,17 @@ + #define XPCOM_SEARCH_KEY "ADDON_PATH" + #define GRE_CONF_NAME "gre.config" + #define GRE_CONF_PATH "gre.conf" + #define GRE_CONF_DIR "gre.d" + #define XPCOM_DLL "libxpcom"MOZ_DLL_SUFFIX + #define XUL_DLL "libxul"MOZ_DLL_SUFFIX + + #else // Unix ++#include // for PATH_MAX + + #define XPCOM_DLL "libxpcom"MOZ_DLL_SUFFIX + + // you have to love apple.. + #ifdef XP_MACOSX + #define XPCOM_SEARCH_KEY "DYLD_LIBRARY_PATH" + #define GRE_FRAMEWORK_NAME "XUL.framework" + #define XUL_DLL "XUL" --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/installer_use_stdout_for_missing_files.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/installer_use_stdout_for_missing_files.patch @@ -0,0 +1,27 @@ +--- + xpinstall/packager/Packager.pm | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: mozilla/xpinstall/packager/Packager.pm +=================================================================== +--- mozilla.orig/xpinstall/packager/Packager.pm ++++ mozilla/xpinstall/packager/Packager.pm +@@ -142,17 +142,17 @@ + (-d "$srcdir/$line") && do { + ($debug >= 10) && print "directory copy.\n"; + do_copydir ("$srcdir/$line"); + next LINE; + }; + + # if we hit this, it's either a file in the package file that is + # not in the src directory, or it is not a valid entry. +- warn "Warning: package error or possible missing or unnecessary file: $line ($package, $lineno).\n"; ++ print "Warning: package error or possible missing or unnecessary file: $line ($package, $lineno).\n"; + + } # LINE + + close (MANIFEST); + chdir ($saved_cwd); + + } + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/ARMEL_Wno_error_in_network_cookie_src.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/ARMEL_Wno_error_in_network_cookie_src.patch @@ -0,0 +1,9 @@ +--- a/netwerk/cookie/src/Makefile.in ++++ b/netwerk/cookie/src/Makefile.in +@@ -60,5 +60,4 @@ + + include $(topsrcdir)/config/rules.mk + +-CXXFLAGS += $(WARNINGS_AS_ERRORS) + DEFINES += -DIMPL_NS_NET + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bz321315_gconf_backend_for_19.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bz321315_gconf_backend_for_19.patch @@ -0,0 +1,3437 @@ +diff -Naur mozilla.orig/config/autoconf.mk.in mozilla/config/autoconf.mk.in +--- mozilla.orig/config/autoconf.mk.in 2008-03-18 10:37:00.000000000 -0700 ++++ mozilla/config/autoconf.mk.in 2008-04-10 11:33:28.000000000 -0700 +@@ -246,6 +246,7 @@ + MOZ_GNOMEVFS_CFLAGS = @MOZ_GNOMEVFS_CFLAGS@ + MOZ_GNOMEVFS_LIBS = @MOZ_GNOMEVFS_LIBS@ + ++MOZ_ENABLE_GCONF = @MOZ_ENABLE_GCONF@ + MOZ_GCONF_CFLAGS = @MOZ_GCONF_CFLAGS@ + MOZ_GCONF_LIBS = @MOZ_GCONF_LIBS@ + +diff -Naur mozilla.orig/configure.in mozilla/configure.in +--- mozilla.orig/configure.in 2008-03-20 12:17:09.000000000 -0700 ++++ mozilla/configure.in 2008-04-10 11:39:22.000000000 -0700 +@@ -4957,6 +4957,7 @@ + ]) + fi + ++ AC_SUBST(MOZ_ENABLE_GCONF) + AC_SUBST(MOZ_GCONF_CFLAGS) + AC_SUBST(MOZ_GCONF_LIBS) + +diff -Naur mozilla.orig/extensions/pref/system-pref/src/gconf/Makefile.in mozilla/extensions/pref/system-pref/src/gconf/Makefile.in +--- mozilla.orig/extensions/pref/system-pref/src/gconf/Makefile.in 2006-04-28 07:54:52.000000000 -0700 ++++ mozilla/extensions/pref/system-pref/src/gconf/Makefile.in 2008-04-01 16:50:49.000000000 -0700 +@@ -42,45 +42,37 @@ + + include $(DEPTH)/config/autoconf.mk + +-MODULE = system-pref +-LIBRARY_NAME = system-pref ++MODULE = syspref-gconf ++MODULE_NAME = nsSystemPrefServiceModule ++LIBRARY_NAME = syspref-gconf ++ifneq ($(OS_ARCH),WINNT) ++SHORT_LIBNAME = spgconf ++endif ++ ++EXPORT_LIBRARY = 1 ++IS_COMPONENT = 1 ++FORCE_STATIC_LIB = 1 + LIBXUL_LIBRARY = 1 + + REQUIRES = pref \ ++ system-pref \ + string \ + xpcom \ + embedcomponents \ ++ necko \ + $(NULL) + + CPPSRCS = \ + nsSystemPrefService.cpp \ +- nsSystemPrefFactory.cpp \ + $(NULL) + +-SHARED_LIBRARY_LIBS = ../libsystem-pref_s.a +- + EXTRA_DSO_LDOPTS = \ +- -L$(DIST)/bin \ + $(MOZ_COMPONENT_LIBS) \ +- $(MOZ_GTK2_LIBS) \ +- $(NULL) +- +-EXPORT_LIBRARY = 1 +-IS_COMPONENT = 1 +-MODULE_NAME = nsSystemPrefModule +- +-EXPORTS = \ +- nsSystemPrefService.h \ ++ $(MOZ_GTK2_LIBS) \ ++ $(MOZ_GCONF_LIBS) \ + $(NULL) + + include $(topsrcdir)/config/rules.mk + +-CFLAGS += $(MOZ_GTK2_CFLAGS) +-CXXFLAGS += $(MOZ_GTK2_CFLAGS) +- +-LOCAL_INCLUDES = -I$(srcdir)/.. +- +-export:: +- $(INSTALL) $(srcdir)/../nsSystemPrefFactory.cpp . +- +-GARBAGE += nsSystemPrefFactory.cpp ++CFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GCONF_CFLAGS) ++CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GCONF_CFLAGS) +diff -Naur mozilla.orig/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp mozilla/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp +--- mozilla.orig/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp 2007-07-08 00:08:21.000000000 -0700 ++++ mozilla/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp 2008-04-01 16:50:49.000000000 -0700 +@@ -23,7 +23,7 @@ + * + * Original Author: Bolian Yin (bolian.yin@sun.com) + * +- * Contributor(s): ++ * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -41,6 +41,7 @@ + + #include + #include ++#include + + #include "plstr.h" + #include "nsCOMPtr.h" +@@ -48,867 +49,1270 @@ + #include "nsIServiceManager.h" + #include "nsIObserver.h" + #include "nsWeakReference.h" +- ++#include "nsIPrefBranch2.h" ++#include "nsISystemPrefService.h" ++#include "nsDataHashtable.h" ++#include "nsHashKeys.h" ++#include "nsICategoryManager.h" ++#include "nsIGenericFactory.h" + #include "nsString.h" +-#include "nsSystemPrefLog.h" +-#include "nsSystemPrefService.h" +- +-/************************************************************************* +- * The strange thing here is that we load the gconf library manually and +- * search the function pointers we need. If that process fails, no gconf +- * support is available in mozilla. The aim is to make mozilla independent +- * on gconf, in both compile time and run time. +- ************************************************************************/ +- +-//gconf types +-extern "C" { +- +- typedef enum { +- GCONF_VALUE_INVALID, +- GCONF_VALUE_STRING, +- GCONF_VALUE_INT, +- GCONF_VALUE_FLOAT, +- GCONF_VALUE_BOOL, +- GCONF_VALUE_SCHEMA, +- +- GCONF_VALUE_LIST, +- GCONF_VALUE_PAIR +- +- }GConfValueType; +- +- typedef struct { +- GConfValueType type; +- }GConfValue; +- +- typedef void * (*GConfClientGetDefaultType) (void); +- typedef PRBool (*GConfClientGetBoolType) (void *client, const gchar *key, +- GError **err); +- typedef gchar* (*GConfClientGetStringType) (void *client, const gchar *key, +- GError **err); +- typedef PRInt32 (*GConfClientGetIntType) (void *client, const gchar *key, +- GError **err); +- typedef GSList* (*GConfClientGetListType) (void *client, const gchar *key, +- GConfValueType list_type, +- GError **err); +- typedef void (*GConfClientNotifyFuncType) (void* client, guint cnxn_id, +- void *entry, +- gpointer user_data); +- typedef guint (*GConfClientNotifyAddType) (void* client, +- const gchar* namespace_section, +- GConfClientNotifyFuncType func, +- gpointer user_data, +- GFreeFunc destroy_notify, +- GError** err); +- typedef void (*GConfClientNotifyRemoveType) (void *client, +- guint cnxn); +- typedef void (*GConfClientAddDirType) (void *client, +- const gchar *dir, +- guint8 preload, +- GError **err); +- typedef void (*GConfClientRemoveDirType) (void *client, +- const gchar *dir, +- GError **err); +- +- typedef const char* (*GConfEntryGetKeyType) (const void *entry); +- typedef GConfValue* (*GConfEntryGetValueType) (const void *entry); +- +- typedef const char* (*GConfValueGetStringType) (const GConfValue *value); +- typedef PRInt32 (*GConfValueGetIntType) (const GConfValue *value); +- typedef PRBool (*GConfValueGetBoolType) (const GConfValue *value); ++#include "nsIPermissionManager.h" + +- +- static void gconf_key_listener (void* client, guint cnxn_id, +- void *entry, gpointer user_data); +-} ++#define NS_SYSTEMPREF_SERVICE_CID \ ++ { /* {3724e748-b088-4bf8-9298-aad426b66293} */ \ ++ 0x3724e748, \ ++ 0xb088, \ ++ 0x4bf8, \ ++ { 0x92, 0x98, 0xaa, 0xd4, 0x26, 0xb6, 0x62, 0x93 } \ ++ } ++ ++#define NS_SYSTEMPREF_SERVICE_CLASSNAME "System Preferences Platform Service" ++ ++/** ++ * We can link directly to the gconf library. If it's not available, ++ * this component just won't load and no system prefs will be offered. ++ */ ++ ++#define NUM_ELEM(a) (sizeof(a)/sizeof(a[0])) ++ ++class nsSystemPrefService; ++ ++/** ++ * List the preferences that have a simple mapping between Moz and gconf. ++ * These preferences have the same meaning and their values are ++ * automatically converted. ++ */ ++struct SimplePrefMapping { ++ const char *mozPrefName; ++ const char *gconfPrefName; ++ /** ++ * If this is PR_FALSE, then we never allow Mozilla to change ++ * this setting. The Mozilla pref will always be locked. ++ * If this is PR_TRUE then Mozilla will be allowed to change ++ * the setting --- but only if it is writable in gconf. ++ */ ++ PRBool allowWritesFromMozilla; ++}; ++typedef nsresult (* ComplexGConfPrefChanged)(nsSystemPrefService* aPrefService, ++ GConfClient* aClient); ++typedef nsresult (* ComplexMozPrefChanged)(nsSystemPrefService* aPrefService, ++ GConfClient* aClient); ++struct ComplexGConfPrefMapping { ++ const char* gconfPrefName; ++ ComplexGConfPrefChanged callback; ++}; + +-struct GConfCallbackData +-{ +- GConfProxy *proxy; +- void * userData; +- PRUint32 atom; +- PRUint32 notifyId; ++struct ComplexMozPrefMapping { ++ const char* mozPrefName; ++ ComplexMozPrefChanged callback; + }; +-////////////////////////////////////////////////////////////////////// +-// GConPrxoy is a thin wrapper for easy use of gconf funcs. It loads the +-// gconf library and initializes the func pointers for later use. +-////////////////////////////////////////////////////////////////////// +-class GConfProxy ++ ++class nsSystemPrefService : public nsISystemPrefService + { + public: +- GConfProxy(nsSystemPrefService* aSysPrefService); +- ~GConfProxy(); +- PRBool Init(); +- +- nsresult GetBoolPref(const char *aMozKey, PRBool *retval); +- nsresult GetCharPref(const char *aMozKey, char **retval); +- nsresult GetIntPref(const char *aMozKey, PRInt32 *retval); ++ NS_DECL_ISUPPORTS + +- nsresult NotifyAdd (PRUint32 aAtom, void *aUserData); +- nsresult NotifyRemove (PRUint32 aAtom, const void *aUserData); ++ nsresult Init(); + +- nsresult GetAtomForMozKey(const char *aMozKey, PRUint32 *aAtom) { +- return GetAtom(aMozKey, 0, aAtom); +- } +- const char *GetMozKey(PRUint32 aAtom) { +- return GetKey(aAtom, 0); ++ virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs); ++ virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName); ++ virtual nsresult NotifyUnloadSystemPreferences(); ++ ++ nsSystemPrefService(); ++ virtual ~nsSystemPrefService(); ++ ++ nsISystemPref* GetPrefs() { return mPref; } ++ SimplePrefMapping* GetSimpleCallbackData(PRUint32 aKey) { ++ SimplePrefMapping* result = nsnull; ++ mGConfSimpleCallbacks.Get(aKey, &result); ++ return result; ++ } ++ ComplexGConfPrefMapping* GetComplexCallbackData(PRUint32 aKey) { ++ ComplexGConfPrefMapping* result = nsnull; ++ mGConfComplexCallbacks.Get(aKey, &result); ++ return result; + } + +- void OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId, +- GConfCallbackData *aData); +- + private: +- void *mGConfClient; +- PRLibrary *mGConfLib; +- PRBool mInitialized; +- nsSystemPrefService *mSysPrefService; +- +- //listeners +- nsAutoVoidArray *mObservers; +- +- void InitFuncPtrs(); +- //gconf public func ptrs +- +- //gconf client funcs +- GConfClientGetDefaultType GConfClientGetDefault; +- GConfClientGetBoolType GConfClientGetBool; +- GConfClientGetStringType GConfClientGetString; +- GConfClientGetIntType GConfClientGetInt; +- GConfClientGetListType GConfClientGetList; +- GConfClientNotifyAddType GConfClientNotifyAdd; +- GConfClientNotifyRemoveType GConfClientNotifyRemove; +- GConfClientAddDirType GConfClientAddDir; +- GConfClientRemoveDirType GConfClientRemoveDir; +- +- //gconf entry funcs +- GConfEntryGetValueType GConfEntryGetValue; +- GConfEntryGetKeyType GConfEntryGetKey; +- +- //gconf value funcs +- GConfValueGetBoolType GConfValueGetBool; +- GConfValueGetStringType GConfValueGetString; +- GConfValueGetIntType GConfValueGetInt; +- +- //pref name translating stuff +- nsresult GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom); +- nsresult GetAtomForGConfKey(const char *aGConfKey, PRUint32 *aAtom) \ +- {return GetAtom(aGConfKey, 1, aAtom);} +- const char *GetKey(PRUint32 aAtom, PRUint8 aNameType); +- const char *GetGConfKey(PRUint32 aAtom) \ +- {return GetKey(aAtom, 1); } +- inline const char *MozKey2GConfKey(const char *aMozKey); +- +- //const strings +- static const char sPrefGConfKey[]; +- static const char sDefaultLibName1[]; +- static const char sDefaultLibName2[]; ++ nsISystemPref* mPref; ++ nsDataHashtable mGConfSimpleCallbacks; ++ nsDataHashtable mGConfComplexCallbacks; ++ // This is set to PR_FALSE temporarily to stop listening to gconf ++ // change notifications (while we change gconf values) ++ PRPackedBool mListenToGConf; + }; + +-struct SysPrefCallbackData { +- nsISupports *observer; +- PRBool bIsWeakRef; +- PRUint32 prefAtom; +-}; +- +-PRBool PR_CALLBACK +-sysPrefDeleteObserver(void *aElement, void *aData) { +- SysPrefCallbackData *pElement = +- static_cast(aElement); +- NS_RELEASE(pElement->observer); +- nsMemory::Free(pElement); +- return PR_TRUE; +-} +- +-NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2) +- +-/* public */ + nsSystemPrefService::nsSystemPrefService() +- :mInitialized(PR_FALSE), +- mGConf(nsnull), +- mObservers(nsnull) ++ : mPref(nsnull), mListenToGConf(PR_TRUE) + { ++ mGConfSimpleCallbacks.Init(); ++ mGConfComplexCallbacks.Init(); + } + + nsSystemPrefService::~nsSystemPrefService() + { +- mInitialized = PR_FALSE; +- +- if (mGConf) +- delete mGConf; +- if (mObservers) { +- (void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull); +- delete mObservers; +- } ++ NotifyUnloadSystemPreferences(); + } + + nsresult + nsSystemPrefService::Init() + { +- if (!gSysPrefLog) { +- gSysPrefLog = PR_NewLogModule("Syspref"); +- if (!gSysPrefLog) return NS_ERROR_OUT_OF_MEMORY; +- } +- +- SYSPREF_LOG(("Init SystemPref Service\n")); +- if (mInitialized) +- return NS_ERROR_FAILURE; +- +- if (!mGConf) { +- mGConf = new GConfProxy(this); +- if (!mGConf->Init()) { +- delete mGConf; +- mGConf = nsnull; +- return NS_ERROR_FAILURE; +- } +- } +- +- mInitialized = PR_TRUE; + return NS_OK; + } + +-/* readonly attribute string root; */ +-NS_IMETHODIMP nsSystemPrefService::GetRoot(char * *aRoot) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++NS_IMPL_ISUPPORTS1(nsSystemPrefService, nsISystemPrefService) + +-/* long getPrefType (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::GetPrefType(const char *aPrefName, PRInt32 *_retval) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; ++static GConfClient* GetGConf() { ++ return gconf_client_get_default(); + } + +-/* boolean getBoolPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::GetBoolPref(const char *aPrefName, PRBool *_retval) ++static PRBool VerifyMatchingTypes(nsISystemPref* aPrefs, ++ const char* aMozPref, GConfValue* aVal) + { +- return mInitialized ? +- mGConf->GetBoolPref(aPrefName, _retval) : NS_ERROR_FAILURE; +-} ++ nsCOMPtr prefBranch = aPrefs->GetPrefUserBranch(); ++ PRInt32 type; ++ nsresult rv = prefBranch->GetPrefType(aMozPref, &type); ++ if (NS_FAILED(rv)) { ++ // pref probably doesn't exist. Let gconf set it. ++ return PR_TRUE; ++ } + +-/* void setBoolPref (in string aPrefName, in long aValue); */ +-NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, PRInt32 aValue) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; ++ PRBool ok; ++ switch (aVal->type) { ++ case GCONF_VALUE_STRING: ++ ok = type == nsIPrefBranch2::PREF_STRING; ++ break; ++ case GCONF_VALUE_INT: ++ ok = type == nsIPrefBranch2::PREF_INT; ++ break; ++ case GCONF_VALUE_BOOL: ++ ok = type == nsIPrefBranch2::PREF_BOOL; ++ break; ++ default: ++ NS_ERROR("Unhandled gconf preference type"); ++ return PR_FALSE; ++ } ++ ++ NS_ASSERTION(ok, "Mismatched gconf/Mozilla pref types"); ++ return ok; + } + +-/* string getCharPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::GetCharPref(const char *aPrefName, char **_retval) +-{ +- return mInitialized ? +- mGConf->GetCharPref(aPrefName, _retval) : NS_ERROR_FAILURE; +-} ++/** ++ * Map a gconf pref value into the corresponding Mozilla pref. ++ */ ++static nsresult ApplySimpleMapping(SimplePrefMapping* aMap, ++ nsISystemPref* aPrefs, ++ GConfClient* aClient) ++{ ++ GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull); ++ if (!val) { ++ // No gconf key, so there's really nothing to do ++ return NS_OK; ++ } + +-/* void setCharPref (in string aPrefName, in string aValue); */ +-NS_IMETHODIMP nsSystemPrefService::SetCharPref(const char *aPrefName, const char *aValue) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val); + +-/* long getIntPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::GetIntPref(const char *aPrefName, PRInt32 *_retval) +-{ +- return mInitialized ? +- mGConf->GetIntPref(aPrefName, _retval) : NS_ERROR_FAILURE; +-} ++ PRBool locked = !aMap->allowWritesFromMozilla || ++ !gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull); ++ nsresult rv; ++ switch (val->type) { ++ case GCONF_VALUE_STRING: { ++ const char* str = gconf_value_get_string(val); ++ rv = aPrefs->SetOverridingMozillaStringPref(aMap->mozPrefName, str, locked); ++ // XXX do we need to free 'str' here? ++ break; ++ } ++ case GCONF_VALUE_INT: ++ rv = aPrefs->SetOverridingMozillaIntPref(aMap->mozPrefName, ++ gconf_value_get_int(val), locked); ++ break; ++ case GCONF_VALUE_BOOL: ++ rv = aPrefs->SetOverridingMozillaBoolPref(aMap->mozPrefName, ++ gconf_value_get_bool(val), locked); ++ break; ++ default: ++ NS_ERROR("Unusable gconf value type"); ++ rv = NS_ERROR_FAILURE; ++ break; ++ } ++ ++ gconf_value_free(val); ++ return rv; ++} ++ ++/** ++ * Map a Mozilla pref into the corresponding gconf pref, if ++ * that's allowed. ++ */ ++static nsresult ReverseApplySimpleMapping(SimplePrefMapping* aMap, ++ nsISystemPref* aPrefs, ++ GConfClient* aClient) ++{ ++ // Verify that the gconf key has the right type, if it exists ++ GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull); ++ if (val) { ++ VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val); ++ gconf_value_free(val); ++ } ++ ++ PRBool writable = aMap->allowWritesFromMozilla && ++ gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull); ++ if (!writable) { ++ NS_ERROR("Gconf key is not writable"); ++ return NS_ERROR_FAILURE; ++ } + +-/* void setIntPref (in string aPrefName, in long aValue); */ +-NS_IMETHODIMP nsSystemPrefService::SetIntPref(const char *aPrefName, PRInt32 aValue) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ nsCOMPtr prefBranch = aPrefs->GetPrefUserBranch(); ++ PRInt32 type; ++ nsresult rv = prefBranch->GetPrefType(aMap->mozPrefName, &type); ++ if (NS_FAILED(rv)) { ++ NS_ERROR("Writing back a pref that doesn't exist?"); ++ return rv; ++ } + +-/* void getComplexValue (in string aPrefName, in nsIIDRef aType, [iid_is (aType), retval] out nsQIResult aValue); */ +-NS_IMETHODIMP nsSystemPrefService::GetComplexValue(const char *aPrefName, const nsIID & aType, void * *aValue) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ switch (type) { ++ case nsIPrefBranch2::PREF_STRING: ++ { ++ char* result; ++ rv = prefBranch->GetCharPref(aMap->mozPrefName, &result); ++ if (NS_FAILED(rv)) ++ return rv; + +-/* void setComplexValue (in string aPrefName, in nsIIDRef aType, in nsISupports aValue); */ +-NS_IMETHODIMP nsSystemPrefService::SetComplexValue(const char *aPrefName, const nsIID & aType, nsISupports *aValue) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ gconf_client_set_string(aClient, aMap->gconfPrefName, result, nsnull); ++ nsMemory::Free(result); ++ } ++ break; ++ case nsIPrefBranch2::PREF_INT: ++ { ++ PRInt32 result; ++ rv = prefBranch->GetIntPref(aMap->mozPrefName, &result); ++ if (NS_FAILED(rv)) ++ return rv; + +-/* void clearUserPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::ClearUserPref(const char *aPrefName) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ gconf_client_set_int(aClient, aMap->gconfPrefName, result, nsnull); ++ } ++ break; ++ case nsIPrefBranch2::PREF_BOOL: ++ { ++ PRBool result; ++ rv = prefBranch->GetBoolPref(aMap->mozPrefName, &result); ++ if (NS_FAILED(rv)) ++ return rv; + +-/* void lockPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::LockPref(const char *aPrefName) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++ gconf_client_set_bool(aClient, aMap->gconfPrefName, result, nsnull); ++ } ++ break; ++ default: ++ NS_ERROR("Unhandled gconf preference type"); ++ return NS_ERROR_FAILURE; ++ } + +-/* boolean prefHasUserValue (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::PrefHasUserValue(const char *aPrefName, PRBool *_retval) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; ++ return NS_OK; + } + +-/* boolean prefIsLocked (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::PrefIsLocked(const char *aPrefName, PRBool *_retval) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; +-} ++/* BEGIN preference mapping definition area ++ * ++ * There are a few rules that our preference maps have to obey: ++ * ++ * 1) Each mapping defines a relationship R between a set of GConf preferences and ++ * a set of Mozilla preferences that must *always* be true. Thus, when a Mozilla ++ * pref changes or a gconf pref changes, we may need to change something on the ++ * other side to preserve R. If a GConf preference is read-only, then we may ++ * need to lock one or more Mozilla preferences to avoid a situation where the ++ * Mozilla preference changes and we can't update the GConf preference to ++ * ensure R continues to hold. ++ * ++ * 2) If an unlocked Mozilla preference is changed, then we can only ++ * preserve R by changing GConf preferences; we are not allowed to ++ * change Mozilla preferences. ++ * ++ * 3) If a GConf preference is changed, then we can only preserve R by ++ * changing Moozilla preferences; we are nt allowed to change GConf ++ * preferences. ++ * ++ * For "simple" mappings, the relationship R is just of the form ++ * "GConf preference 'A' is equal to Mozilla preference 'B'". R is ++ * preserved by setting A to B when B changes, and by setting B to A ++ * when A changes. If A is read-only then we lock B (or we may just ++ * decide to lock B for other reasons). Thus rules 1-3 are satisfied. ++ * ++ * For "complex" mappings we have more complicated ++ * relationships. These are documented below. ++ */ ++ ++static SimplePrefMapping sSimplePrefMappings[] = { ++ // GNOME proxy settings; allow these to be set through the Firefox UI ++ {"network.proxy.http", "/system/http_proxy/host", PR_TRUE}, ++ {"network.proxy.http_port", "/system/http_proxy/port", PR_TRUE}, ++ {"network.proxy.ftp", "/system/proxy/ftp_host", PR_TRUE}, ++ {"network.proxy.ftp_port", "/system/proxy/ftp_port", PR_TRUE}, ++ {"network.proxy.ssl", "/system/proxy/secure_host", PR_TRUE}, ++ {"network.proxy.ssl_port", "/system/proxy/secure_port", PR_TRUE}, ++ {"network.proxy.socks", "/system/proxy/socks_host", PR_TRUE}, ++ {"network.proxy.socks_port", "/system/proxy/socks_port", PR_TRUE}, ++ {"network.proxy.autoconfig_url", "/system/proxy/autoconfig_url", PR_TRUE}, ++ ++ // GNOME accessibility setting; never allow this to be set by Firefox ++ {"config.use_system_prefs.accessibility", ++ "/desktop/gnome/interface/accessibility", PR_FALSE}, ++ ++ // GConf Firefox preferences; allow these to be set through the Firefox UI ++ {"security.enable_java", "/apps/firefox/web/java_enabled", PR_TRUE}, ++ {"javascript.enabled", "/apps/firefox/web/javascript_enabled", PR_TRUE}, ++ {"browser.startup.homepage", "/apps/firefox/general/homepage_url", PR_TRUE}, ++ {"browser.cache.disk.capacity", "/apps/firefox/web/cache_size", PR_TRUE}, ++ {"network.cookie.lifetimePolicy", "/apps/firefox/web/cookie_accept", PR_TRUE}, ++ ++ // UI lockdown settings; never allow these to be set by Firefox. There is no ++ // Firefox UI for these but they could otherwise be set via about:config. ++ {"config.lockdown.printing", "/desktop/gnome/lockdown/disable_printing", PR_FALSE}, ++ {"config.lockdown.printsetup", "/desktop/gnome/lockdown/disable_print_setup", PR_FALSE}, ++ {"config.lockdown.savepage", "/desktop/gnome/lockdown/disable_save_to_disk", PR_FALSE}, ++ {"config.lockdown.history", "/apps/firefox/lockdown/disable_history", PR_FALSE}, ++ {"config.lockdown.toolbarediting", "/apps/firefox/lockdown/disable_toolbar_editing", PR_FALSE}, ++ {"config.lockdown.urlbar", "/apps/firefox/lockdown/disable_url_bar", PR_FALSE}, ++ {"config.lockdown.bookmark", "/apps/firefox/lockdown/disable_bookmark_editing", PR_FALSE}, ++ {"config.lockdown.disable_themes", "/apps/firefox/lockdown/disable_themes", PR_FALSE}, ++ {"config.lockdown.disable_extensions", "/apps/firefox/lockdown/disable_extensions", PR_FALSE}, ++ {"config.lockdown.searchbar", "/apps/firefox/lockdown/disable_searchbar", PR_FALSE}, ++ {"config.lockdown.hidebookmark", "/apps/firefox/lockdown/hide_bookmark", PR_FALSE}, ++}; + +-/* void unlockPref (in string aPrefName); */ +-NS_IMETHODIMP nsSystemPrefService::UnlockPref(const char *aPrefName) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; ++static nsresult ApplyListPref(nsSystemPrefService* aPrefService, ++ GConfClient* aClient, ++ const char* aGConfKey, const char* aMozKey, ++ char aSeparator) ++{ ++ GSList* list = gconf_client_get_list(aClient, aGConfKey, ++ GCONF_VALUE_STRING, nsnull); ++ nsCAutoString str; ++ for (GSList* l = list; l; l = l->next) { ++ str.Append((const char*)l->data); ++ if (l->next) { ++ str.Append(aSeparator); ++ } ++ } ++ PRBool lock = !gconf_client_key_is_writable(aClient, aGConfKey, nsnull); ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaStringPref(aMozKey, str.get(), lock); ++ // XXX does this free the strings? Should it? ++ g_slist_free(list); ++ return rv; ++} ++static nsresult ReverseApplyListPref(nsSystemPrefService* aPrefService, ++ GConfClient* aClient, ++ const char* aGConfKey, const char* aMozKey, ++ char aSeparator) ++{ ++ char* data = nsnull; ++ nsCOMPtr prefs = ++ aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetCharPref(aMozKey, &data); ++ if (!data) ++ return NS_ERROR_FAILURE; ++ nsresult rv = NS_OK; ++ GSList* list = nsnull; ++ PRInt32 i = 0; ++ while (data[i]) { ++ const char* nextComma = strchr(data+i, ','); ++ PRInt32 tokLen = nextComma ? nextComma - (data+i) : strlen(data+i); ++ char* tok = strndup(data+i, tokLen); ++ if (!tok) ++ break; ++ GSList* newList = g_slist_append(list, tok); ++ if (!newList) { ++ rv = NS_ERROR_OUT_OF_MEMORY; ++ break; ++ } ++ list = newList; ++ if (!nextComma) ++ break; ++ i = nextComma + 1 - data; ++ } ++ nsMemory::Free(data); ++ if (NS_SUCCEEDED(rv)) { ++ gconf_client_set_list(aClient, aGConfKey, GCONF_VALUE_STRING, list, nsnull); ++ } ++ for (GSList* l = list; l; l = l->next) { ++ free(l->data); ++ } ++ g_slist_free(list); ++ return rv; + } + +-/* void deleteBranch (in string aStartingAt); */ +-NS_IMETHODIMP nsSystemPrefService::DeleteBranch(const char *aStartingAt) ++/** ++ * The relationship R is ++ * "network.negotiate-auth.trusted-uris" is the comma-separated concatenation ++ * of the elements of the list "/apps/firefox/general/trusted_URIs" ++ */ ++static const char GConfKey_TrustedURIs[] = "/apps/firefox/general/trusted_URIs"; ++static const char MozKey_TrustedURIs[] = "network.negotiate-auth.trusted-uris"; ++static nsresult ApplyTrustedURIs(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ApplyListPref(aPrefService, aClient, ++ GConfKey_TrustedURIs, MozKey_TrustedURIs, ','); ++} ++static nsresult ReverseApplyTrustedURIs(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ReverseApplyListPref(aPrefService, aClient, ++ GConfKey_TrustedURIs, MozKey_TrustedURIs, ','); ++} ++ ++/** ++ * The relationship R is ++ * "network.negotiate-auth.delegation-uris" is the comma-separated concatenation ++ * of the elements of the list "/apps/firefox/general/delegation_URIs" ++ */ ++static const char GConfKey_DelegationURIs[] = "/apps/firefox/general/delegation_URIs"; ++static const char MozKey_DelegationURIs[] = "network.negotiate-auth.delegation-uris"; ++static nsresult ApplyDelegationURIs(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ApplyListPref(aPrefService, aClient, ++ GConfKey_DelegationURIs, MozKey_DelegationURIs, ','); ++} ++static nsresult ReverseApplyDelegationURIs(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ReverseApplyListPref(aPrefService, aClient, ++ GConfKey_DelegationURIs, MozKey_DelegationURIs, ','); ++} ++ ++/** ++ * The relationship R is ++ * "network.proxy.no_proxies_on" is the comma-separated concatenation ++ * of the elements of the list "/system/http_proxy/ignore_hosts" ++ */ ++static const char GConfKey_IgnoreHosts[] = "/system/http_proxy/ignore_hosts"; ++static const char MozKey_IgnoreHosts[] = "network.proxy.no_proxies_on"; ++static nsresult ApplyIgnoreHosts(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ApplyListPref(aPrefService, aClient, ++ GConfKey_IgnoreHosts, MozKey_IgnoreHosts, ','); ++} ++static nsresult ReverseApplyIgnoreHosts(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ return ReverseApplyListPref(aPrefService, aClient, ++ GConfKey_IgnoreHosts, MozKey_IgnoreHosts, ','); ++} ++ ++/** ++ * The relationship R is ++ * ("/system/proxy/mode" is 'manual' if and only if "network.proxy.type" is eProxyConfig_Manual (1)) ++ * AND ("/system/proxy/mode" is 'auto' if and only if "network.proxy.type" is eProxyConfig_PAC (2)) ++ * ++ * [This means 'none' matches any value of "network.proxy.type" other than 1 or 2.] ++ */ ++static const char GConfKey_ProxyMode[] = "/system/proxy/mode"; ++static const char MozKey_ProxyMode[] = "network.proxy.type"; ++static nsresult ApplyProxyMode(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) + { +- return NS_ERROR_NOT_IMPLEMENTED; ++ char* str = gconf_client_get_string(aClient, GConfKey_ProxyMode, nsnull); ++ if (!str) ++ return NS_ERROR_FAILURE; ++ PRInt32 val = -1; ++ nsCOMPtr prefs = ++ aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetIntPref(MozKey_ProxyMode, &val); ++ if (val < 0) ++ return NS_ERROR_FAILURE; ++ if (!strcmp(str, "manual")) { ++ val = 1; ++ } else if (!strcmp(str, "auto")) { ++ val = 2; ++ } else if (strcmp(str, "none")) { ++ // invalid value for this gconf pref; do nothing ++ g_free(str); ++ return NS_OK; ++ } else { ++ if (val == 1 || val == 2) { ++ // We need to make it something that 'none' maps to ++ val = 0; ++ } ++ } ++ g_free(str); ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_ProxyMode, nsnull); ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaIntPref(MozKey_ProxyMode, val, lock); ++ return rv; ++} ++static nsresult ReverseApplyProxyMode(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRInt32 val = -1; ++ nsCOMPtr prefs = ++ aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetIntPref(MozKey_ProxyMode, &val); ++ if (val < 0) ++ return NS_ERROR_FAILURE; ++ const char* str; ++ switch (val) { ++ case 1: str = "manual"; break; ++ case 2: str = "auto"; break; ++ default: str = "none"; break; ++ } ++ gconf_client_set_string(aClient, GConfKey_ProxyMode, str, nsnull); ++ return NS_OK; + } + +-/* void getChildList (in string aStartingAt, out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */ +-NS_IMETHODIMP nsSystemPrefService::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray) ++/** ++ * The relationship R is ++ * If "/apps/firefox/web/download_defaultfolder" is the empty string, then ++ * "browser.download.useDownloadDir" is false; ++ * otherwise "browser.download.useDownloadDir" is true and "browser.download.folderList" ++ * is (0 if "/apps/firefox/web/download_defaultfolder" is "Desktop"; ++ * 1 if "/apps/firefox/web/download_defaultfolder" is "My Downloads"; ++ * 3 if "/apps/firefox/web/download_defaultfolder" is "Home"; ++ * otherwise 2 and "browser.download.dir" = "/apps/firefox/web/download_defaultfolder") ++ */ ++static const char GConfKey_DownloadFolder[] = "/apps/firefox/web/download_defaultfolder"; ++static const char MozKey_UseDownloadDir[] = "browser.download.useDownloadDir"; ++static const char MozKey_DownloadDirType[] = "browser.download.folderList"; ++static const char MozKey_DownloadDirExplicit[] = "browser.download.dir"; ++static nsresult ApplyDownloadFolder(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) + { +- return NS_ERROR_NOT_IMPLEMENTED; ++ char* str = gconf_client_get_string(aClient, GConfKey_DownloadFolder, nsnull); ++ if (!str) ++ return NS_ERROR_FAILURE; ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DownloadFolder, nsnull); ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_UseDownloadDir, *str != 0, lock); ++ if (NS_FAILED(rv)) { ++ g_free(str); ++ return rv; ++ } ++ PRInt32 dirType = 0; ++ if (!strcmp(str, "Desktop")) { ++ dirType = 0; ++ } else if (!strcmp(str, "My Downloads")) { ++ dirType = 1; ++ } else if (!strcmp(str, "Home")) { ++ dirType = 3; ++ } else { ++ dirType = 2; ++ } ++ // Always set all three Mozilla preferences. This is simpler and avoids ++ // problems; e.g., if the gconf value changes from "/home/rocallahan" to "Desktop" ++ // we might leave MozKey_DownloadDirType accidentally locked. ++ rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaIntPref(MozKey_DownloadDirType, dirType, lock); ++ if (NS_SUCCEEDED(rv)) { ++ rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaStringPref(MozKey_DownloadDirExplicit, str, lock); ++ } ++ g_free(str); ++ return rv; + } + +-/* void resetBranch (in string aStartingAt); */ +-NS_IMETHODIMP nsSystemPrefService::ResetBranch(const char *aStartingAt) +-{ +- return NS_ERROR_NOT_IMPLEMENTED; ++static nsresult ReverseApplyDownloadFolder(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool useDownloadDir = PR_FALSE; ++ const char* result; ++ char* explicitStr = nsnull; ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetBoolPref(MozKey_UseDownloadDir, &useDownloadDir); ++ if (!useDownloadDir) { ++ result = ""; ++ } else { ++ PRInt32 type = -1; ++ prefs->GetIntPref(MozKey_DownloadDirType, &type); ++ if (type < 0) ++ return NS_ERROR_FAILURE; ++ switch (type) { ++ case 0: result = "Desktop"; break; ++ case 1: result = "My Downloads"; break; ++ case 2: ++ prefs->GetCharPref(MozKey_DownloadDirExplicit, &explicitStr); ++ result = explicitStr; ++ break; ++ case 3: result = "Home"; break; ++ default: ++ NS_ERROR("Unknown download dir type"); ++ return NS_ERROR_FAILURE; ++ } ++ } ++ if (!result) ++ return NS_ERROR_FAILURE; ++ gconf_client_set_string(aClient, GConfKey_DownloadFolder, ++ result, nsnull); ++ nsMemory::Free(explicitStr); ++ return NS_OK; + } + +-/* void addObserver (in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak); */ +-NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak) +-{ +- nsresult rv; +- +- NS_ENSURE_ARG_POINTER(aDomain); +- NS_ENSURE_ARG_POINTER(aObserver); +- +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- +- PRUint32 prefAtom; +- // make sure the pref name is supported +- rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom); +- NS_ENSURE_SUCCESS(rv, rv); +- +- if (!mObservers) { +- mObservers = new nsAutoVoidArray(); +- if (mObservers == nsnull) +- return NS_ERROR_OUT_OF_MEMORY; +- } +- +- SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *) +- nsMemory::Alloc(sizeof(SysPrefCallbackData)); +- if (pCallbackData == nsnull) +- return NS_ERROR_OUT_OF_MEMORY; +- +- pCallbackData->bIsWeakRef = aHoldWeak; +- pCallbackData->prefAtom = prefAtom; +- // hold a weak reference to the observer if so requested +- nsCOMPtr observerRef; +- if (aHoldWeak) { +- nsCOMPtr weakRefFactory = +- do_QueryInterface(aObserver); +- if (!weakRefFactory) { +- // the caller didn't give us a object that supports weak reference. +- // ... tell them +- nsMemory::Free(pCallbackData); +- return NS_ERROR_INVALID_ARG; +- } +- nsCOMPtr tmp = do_GetWeakReference(weakRefFactory); +- observerRef = tmp; ++/** ++ * The relationship R is ++ * "/apps/firefox/web/disable_cookies" is true if and only if ++ * "network.cookie.cookieBehavior" is 2 ('dontUse') ++ */ ++static const char GConfKey_DisableCookies[] = "/apps/firefox/web/disable_cookies"; ++static const char MozKey_CookieBehavior[] = "network.cookie.cookieBehavior"; ++static const char MozKey_CookieExceptions[] = "network.cookie.honorExceptions"; ++static const char MozKey_CookieViewExceptions[] = "pref.privacy.disable_button.cookie_exceptions"; ++static nsresult ApplyDisableCookies(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableCookies, nsnull); ++ PRInt32 behavior = -1; ++ nsCOMPtr prefs = ++ aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetIntPref(MozKey_CookieBehavior, &behavior); ++ if (behavior < 0) ++ return NS_ERROR_FAILURE; ++ if (disable) { ++ behavior = 2; + } else { +- observerRef = aObserver; ++ if (behavior == 2) { ++ behavior = 0; ++ } + } ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableCookies, nsnull); ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_CookieExceptions, !lock, lock); ++ if (NS_FAILED(rv)) ++ return rv; ++ rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_CookieViewExceptions, lock, lock); ++ if (NS_FAILED(rv)) ++ return rv; ++ return aPrefService->GetPrefs()-> ++ SetOverridingMozillaIntPref(MozKey_CookieBehavior, behavior, lock); ++} ++static nsresult ReverseApplyDisableCookies(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRInt32 behavior = -1; ++ nsCOMPtr prefs = ++ aPrefService->GetPrefs()->GetPrefUserBranch(); ++ prefs->GetIntPref(MozKey_CookieBehavior, &behavior); ++ if (behavior < 0) ++ return NS_ERROR_FAILURE; ++ gconf_client_set_bool(aClient, GConfKey_DisableCookies, behavior == 2, nsnull); ++ return NS_OK; ++} + +- rv = mGConf->NotifyAdd(prefAtom, pCallbackData); +- if (NS_FAILED(rv)) { +- nsMemory::Free(pCallbackData); +- return rv; ++static char const* windowOpenFeatures[] = { ++ "dom.disable_window_open_feature.close", ++ "dom.disable_window_open_feature.directories", ++ "dom.disable_window_open_feature.location", ++ "dom.disable_window_open_feature.menubar", ++ "dom.disable_window_open_feature.minimizable", ++ "dom.disable_window_open_feature.personalbar", ++ "dom.disable_window_open_feature.resizable", ++ "dom.disable_window_open_feature.scrollbars", ++ "dom.disable_window_open_feature.status", ++ "dom.disable_window_open_feature.titlebar", ++ "dom.disable_window_open_feature.toolbar" ++}; ++/** ++ * The relationship R is ++ * "/apps/firefox/lockdown/disable_javascript_chrome" is true if and only if ++ * all of windowOpenFeatures are true ++ */ ++static const char GConfKey_DisableJSChrome[] = ++ "/apps/firefox/lockdown/disable_javascript_chrome"; ++static nsresult ApplyWindowOpen(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableJSChrome, nsnull); ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableJSChrome, nsnull); ++ PRBool curValues[NUM_ELEM(windowOpenFeatures)]; ++ PRUint32 i; ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRBool allDisabled = PR_TRUE; ++ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { ++ nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]); ++ if (NS_FAILED(rv)) ++ return rv; ++ if (!curValues[i]) { ++ allDisabled = PR_FALSE; ++ } ++ } ++ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { ++ PRBool newVal = curValues[i]; ++ if (disable) { ++ newVal = PR_TRUE; ++ } else if (allDisabled) { ++ // If all disable-window-open-feature prefs are currently ++ // PR_TRUE, then we need to set at least one of them to ++ // PR_FALSE. Set all of them to PR_FALSE. ++ newVal = PR_FALSE; ++ } // If at least one disable-window-open-feature pref is ++ // currently PR_FALSE, then we don't need to change anything ++ // when the gconf pref says don't disable ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(windowOpenFeatures[i], newVal, lock); ++ if (NS_FAILED(rv)) ++ return rv; + } +- +- pCallbackData->observer = observerRef; +- NS_ADDREF(pCallbackData->observer); +- +- mObservers->AppendElement(pCallbackData); + return NS_OK; + } + +-/* void removeObserver (in string aDomain, in nsIObserver aObserver); */ +-NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserver *aObserver) ++static nsresult ReverseApplyWindowOpen(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) + { +- nsresult rv; +- +- NS_ENSURE_ARG_POINTER(aDomain); +- NS_ENSURE_ARG_POINTER(aObserver); +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- +- if (!mObservers) +- return NS_OK; +- +- PRUint32 prefAtom; +- // make sure the pref name is supported +- rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom); +- NS_ENSURE_SUCCESS(rv, rv); +- +- // need to find the index of observer, so we can remove it +- PRIntn count = mObservers->Count(); +- if (count <= 0) +- return NS_OK; +- +- PRIntn i; +- SysPrefCallbackData *pCallbackData; +- for (i = 0; i < count; ++i) { +- pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i); +- if (pCallbackData) { +- nsCOMPtr observerRef; +- if (pCallbackData->bIsWeakRef) { +- nsCOMPtr weakRefFactory = +- do_QueryInterface(aObserver); +- if (weakRefFactory) { +- nsCOMPtr tmp = +- do_GetWeakReference(aObserver); +- observerRef = tmp; +- } +- } +- if (!observerRef) +- observerRef = aObserver; +- +- if (pCallbackData->observer == observerRef && +- pCallbackData->prefAtom == prefAtom) { +- rv = mGConf->NotifyRemove(prefAtom, pCallbackData); +- if (NS_SUCCEEDED(rv)) { +- mObservers->RemoveElementAt(i); +- NS_RELEASE(pCallbackData->observer); +- nsMemory::Free(pCallbackData); +- } +- return rv; +- } ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRBool allDisabled = PR_TRUE; ++ PRBool curValues[NUM_ELEM(windowOpenFeatures)]; ++ for (PRUint32 i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { ++ nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]); ++ if (NS_FAILED(rv)) ++ return rv; ++ if (!curValues[i]) { ++ allDisabled = PR_FALSE; + } + } ++ gconf_client_set_bool(aClient, GConfKey_DisableJSChrome, allDisabled, nsnull); + return NS_OK; + } + +-void +-nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData) +-{ +- if (!mInitialized) +- return; ++/** ++ * The relationship R is ++ * If "/apps/firefox/lockdown/disable_unsafe_protocol" is true then ++ * -- "network.protocol-handler.blocked-default" is true ++ * -- "network.protocol-handler.blocked.XYZ" is false if and only if ++ * XYZ is a builtin non-disablable protocol or in ++ * "/apps/firefox/lockdown/additional_safe_protocols" ++ * AND if "/apps/firefox/lockdown/disable_unsafe_protocol" is false then ++ * -- "network.protocol-handler.blocked-default" is false ++ * -- if "network.protocol-handler.blocked.XYZ" exists then it is false ++ */ ++static const char GConfKey_DisableUnsafeProtocols[] = ++ "/apps/firefox/lockdown/disable_unsafe_protocol"; ++static const char GConfKey_AdditionalSafeProtocols[] = ++ "/apps/firefox/lockdown/additional_safe_protocols"; ++static const char MozKey_BlockedDefault[] = ++ "network.protocol-handler.blocked-default"; ++static const char MozKey_BlockedPrefix[] = ++ "network.protocol-handler.blocked."; ++static const char* nonDisablableBuiltinProtocols[] = ++ { "about", "data", "jar", "keyword", "resource", "viewsource", ++ "chrome", "moz-icon", "javascript", "file" }; ++static PRBool FindString(const char** aList, PRInt32 aCount, ++ const char* aStr) ++{ ++ for (PRInt32 i = 0; i < aCount; ++i) { ++ if (!strcmp(aStr, aList[i])) ++ return PR_TRUE; ++ } ++ return PR_FALSE; ++} ++typedef nsDataHashtable StringSet; ++/** Collect the set of protocol names that we want to set preferences for */ ++static nsresult AddAllProtocols(nsSystemPrefService* aPrefService, ++ const char* aSafeProtocols, ++ StringSet* aProtocolSet, ++ StringSet* aSafeSet) ++{ ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRUint32 childCount; ++ char **childArray = nsnull; ++ nsresult rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray); ++ if (NS_FAILED(rv)) ++ return rv; ++ PRUint32 i; ++ for (i = 0; i < childCount; ++i) { ++ nsDependentCString tmp(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1); ++ aProtocolSet->Put(tmp, 1); // copies ++ } ++ for (i = 0; i < NUM_ELEM(nonDisablableBuiltinProtocols); ++i) { ++ nsDependentCString tmp(nonDisablableBuiltinProtocols[i]); ++ aProtocolSet->Put(tmp, 1); ++ } ++ i = 0; ++ while (aSafeProtocols[i]) { ++ const char* nextComma = strchr(aSafeProtocols+i, ','); ++ PRUint32 tokLen = nextComma ? nextComma - (aSafeProtocols+i) ++ : strlen(aSafeProtocols+i); ++ nsCAutoString tok(aSafeProtocols+i, tokLen); ++ aProtocolSet->Put(tok, 1); ++ aSafeSet->Put(tok, 1); ++ if (nextComma) { ++ i = nextComma - aSafeProtocols + 1; ++ } else { ++ break; ++ } ++ } ++ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); ++ return NS_OK; ++} + +- SysPrefCallbackData *pData = (SysPrefCallbackData *)aData; +- if (pData->prefAtom != aPrefAtom) +- return; ++struct ProtocolPrefClosure { ++ StringSet safeProtocolSet; ++ nsIPrefBranch2* prefs; ++ nsISystemPref* prefSetter; ++ PRPackedBool disableUnsafe; ++ PRPackedBool lock; ++}; + +- nsCOMPtr observer; +- if (pData->bIsWeakRef) { +- nsCOMPtr weakRef = +- do_QueryInterface(pData->observer); +- if(weakRef) +- observer = do_QueryReferent(weakRef); +- if (!observer) { +- // this weak referenced observer went away, remove it from the list +- nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData); +- if (NS_SUCCEEDED(rv)) { +- mObservers->RemoveElement(pData); +- NS_RELEASE(pData->observer); +- nsMemory::Free(pData); ++static PLDHashOperator PR_CALLBACK SetProtocolPref(const nsACString& aKey, ++ int aItem, ++ void* aClosure) ++{ ++ ProtocolPrefClosure* closure = static_cast(aClosure); ++ const nsCString& protocol = PromiseFlatCString(aKey); ++ PRBool blockProtocol = PR_FALSE; ++ if (closure->disableUnsafe && ++ !FindString(nonDisablableBuiltinProtocols, ++ NUM_ELEM(nonDisablableBuiltinProtocols), protocol.get()) && ++ !closure->safeProtocolSet.Get(aKey, nsnull)) { ++ blockProtocol = PR_TRUE; ++ } ++ ++ nsCAutoString prefName; ++ prefName.Append(MozKey_BlockedPrefix); ++ prefName.Append(protocol); ++ closure->prefSetter->SetOverridingMozillaBoolPref(prefName.get(), blockProtocol, ++ closure->lock); ++ return PL_DHASH_NEXT; ++} ++static nsresult ApplyUnsafeProtocols(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableUnsafeProtocols, nsnull) ++ || !gconf_client_key_is_writable(aClient, GConfKey_AdditionalSafeProtocols, nsnull); ++ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableUnsafeProtocols, nsnull); ++ char* protocols = gconf_client_get_string(aClient, GConfKey_AdditionalSafeProtocols, nsnull); ++ if (!protocols) ++ return NS_ERROR_FAILURE; ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_BlockedDefault, disable, lock); ++ StringSet protocolSet; ++ ProtocolPrefClosure closure; ++ protocolSet.Init(); ++ closure.safeProtocolSet.Init(); ++ if (NS_SUCCEEDED(rv)) { ++ rv = AddAllProtocols(aPrefService, protocols, &protocolSet, ++ &closure.safeProtocolSet); ++ } ++ if (NS_SUCCEEDED(rv)) { ++ closure.disableUnsafe = disable; ++ closure.lock = lock; ++ closure.prefSetter = aPrefService->GetPrefs(); ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ closure.prefs = prefs; ++ protocolSet.EnumerateRead(SetProtocolPref, &closure); ++ } ++ g_free(protocols); ++ return rv; ++} ++ ++static nsresult ReverseApplyUnsafeProtocols(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRBool blockedDefault; ++ nsresult rv = prefs->GetBoolPref(MozKey_BlockedDefault, &blockedDefault); ++ if (NS_FAILED(rv)) ++ return rv; ++ nsCAutoString enabledProtocols; ++ PRUint32 childCount; ++ char **childArray = nsnull; ++ rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray); ++ if (NS_FAILED(rv)) ++ return rv; ++ for (PRUint32 i = 0; i < childCount; ++i) { ++ PRBool val = PR_FALSE; ++ prefs->GetBoolPref(childArray[i], &val); ++ if (val) { ++ if (enabledProtocols.Length() > 0) { ++ enabledProtocols.Append(','); + } +- return; ++ enabledProtocols.Append(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1); + } + } +- else +- observer = do_QueryInterface(pData->observer); ++ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); ++ gconf_client_set_bool(aClient, GConfKey_DisableUnsafeProtocols, blockedDefault, nsnull); ++ gconf_client_set_string(aClient, GConfKey_AdditionalSafeProtocols, ++ enabledProtocols.get(), nsnull); ++ return NS_OK; ++} + +- if (observer) +- observer->Observe(static_cast(this), +- NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID, +- NS_ConvertUTF8toUTF16(mGConf->GetMozKey(aPrefAtom)). +- get()); ++/** ++ * Set config.lockdown.setwallpaper if and only if ++ * /desktop/gnome/background/picture_filename is write-only. Always ++ * lock it. ++ */ ++static const char MozKey_LockdownWallpaper[] = "config.lockdown.setwallpaper"; ++static const char GConfKey_WallpaperSetting[] = ++ "/desktop/gnome/background/picture_filename"; ++static nsresult ApplyWallpaper(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool canSetWallpaper = ++ gconf_client_key_is_writable(aClient, GConfKey_WallpaperSetting, nsnull); ++ return aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_LockdownWallpaper, ++ !canSetWallpaper, PR_TRUE); ++} ++// No ReverseApplyWallpaper because this Mozilla pref can never be ++// modified ++ ++/** ++ * The relationship R is ++ * "signon.rememberSignons" is true if and only if "/apps/firefox/web/disable_save_password" ++ * is false. ++ */ ++static const char MozKey_RememberSignons[] = "signon.rememberSignons"; ++static const char GConfKey_DisableSavePassword[] = "/apps/firefox/web/disable_save_password"; ++static nsresult ApplyDisableSavePassword(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableSavePassword, nsnull); ++ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableSavePassword, nsnull); ++ return aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_RememberSignons, !disable, lock); ++} ++ ++static nsresult ReverseApplyDisableSavePassword(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRBool remember; ++ nsresult rv = prefs->GetBoolPref(MozKey_RememberSignons, &remember); ++ if (NS_FAILED(rv)) ++ return rv; ++ gconf_client_set_bool(aClient, GConfKey_DisableSavePassword, !remember, nsnull); ++ return NS_OK; + } + +-/************************************************************* +- * GConfProxy ++/** ++ * The relationship R is ++ * "permissions.default.image" is 1 (nsIPermissionManager::ALLOW_ACTION) if and only if ++ * "/apps/firefox/web/images_load" is 0, AND ++ * "permissions.default.image" is 2 (nsIPermissionManager::DENY_ACTION) if and only if ++ * "/apps/firefox/web/images_load" is 2, AND ++ * "permissions.default.image" is 3 if and only if "/apps/firefox/web/images_load" is 1 + * +- ************************************************************/ +- +-struct GConfFuncListType { +- const char *FuncName; +- PRFuncPtr FuncPtr; +-}; +- +-struct PrefNamePair { +- const char *mozPrefName; +- const char *gconfPrefName; +-}; +- +-const char +-GConfProxy::sPrefGConfKey[] = "accessibility.unix.gconf2.shared-library"; +-const char GConfProxy::sDefaultLibName1[] = "libgconf-2.so.4"; +-const char GConfProxy::sDefaultLibName2[] = "libgconf-2.so"; +- +-#define GCONF_FUNCS_POINTER_BEGIN \ +- static GConfFuncListType sGConfFuncList[] = { +-#define GCONF_FUNCS_POINTER_ADD(func_name) \ +- {func_name, nsnull}, +-#define GCONF_FUNCS_POINTER_END \ +- {nsnull, nsnull}, }; +- +-GCONF_FUNCS_POINTER_BEGIN +- GCONF_FUNCS_POINTER_ADD("gconf_client_get_default") // 0 +- GCONF_FUNCS_POINTER_ADD("gconf_client_get_bool") // 1 +- GCONF_FUNCS_POINTER_ADD("gconf_client_get_string") //2 +- GCONF_FUNCS_POINTER_ADD("gconf_client_get_int") //3 +- GCONF_FUNCS_POINTER_ADD("gconf_client_notify_add") //4 +- GCONF_FUNCS_POINTER_ADD("gconf_client_notify_remove") //5 +- GCONF_FUNCS_POINTER_ADD("gconf_client_add_dir") //6 +- GCONF_FUNCS_POINTER_ADD("gconf_client_remove_dir") //7 +- GCONF_FUNCS_POINTER_ADD("gconf_entry_get_value") //8 +- GCONF_FUNCS_POINTER_ADD("gconf_entry_get_key") //9 +- GCONF_FUNCS_POINTER_ADD("gconf_value_get_bool") //10 +- GCONF_FUNCS_POINTER_ADD("gconf_value_get_string") //11 +- GCONF_FUNCS_POINTER_ADD("gconf_value_get_int") //12 +- GCONF_FUNCS_POINTER_ADD("gconf_client_get_list") //13 +-GCONF_FUNCS_POINTER_END +- +-///////////////////////////////////////////////////////////////////////////// +-// the list is the mapping table, between mozilla prefs and gconf prefs +-// It is expected to include all the pref pairs that are related in mozilla +-// and gconf. +-// +-// Note: the prefs listed here are not neccessarily be read from gconf, they +-// are the prefs that could be read from gconf. Mozilla has another +-// list (see sSysPrefList in nsSystemPref.cpp) that decide which prefs +-// are really read. +-////////////////////////////////////////////////////////////////////////////// +- +-static const PrefNamePair sPrefNameMapping[] = { +-#include "gconf_pref_list.inc" +- {nsnull, nsnull}, +-}; +- +-PRBool PR_CALLBACK +-gconfDeleteObserver(void *aElement, void *aData) { +- nsMemory::Free(aElement); +- return PR_TRUE; ++ * Also, we set pref.advanced.images.disable_button.view_image iff ++ * /apps/firefox/web/images_load is read-only ++ * And we set permissions.default.honorExceptions iff ++ * /apps/firefox/web/images_load is not read-only ++ */ ++static const char MozKey_ImagePermissions[] = "permissions.default.image"; ++static const char MozKey_ImageExceptions[] = "permissions.honorExceptions.image"; ++static const char MozKey_ImageViewExceptions[] = "pref.advanced.images.disable_button.view_image"; ++static const char GConfKey_LoadImages[] = "/apps/firefox/web/images_load"; ++static nsresult ApplyLoadImages(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_LoadImages, nsnull); ++ // 0 == accept, 1 == no-foreign, 2 == reject ++ gint setting = gconf_client_get_int(aClient, GConfKey_LoadImages, nsnull); ++ PRInt32 pref; ++ switch (setting) { ++ case 0: pref = nsIPermissionManager::ALLOW_ACTION; break; ++ case 2: pref = nsIPermissionManager::DENY_ACTION; break; ++ case 1: pref = 3; break; ++ default: return NS_ERROR_FAILURE; ++ } ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_ImageExceptions, !lock, lock); ++ if (NS_FAILED(rv)) ++ return rv; ++ rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_ImageViewExceptions, lock, lock); ++ if (NS_FAILED(rv)) ++ return rv; ++ return aPrefService->GetPrefs()-> ++ SetOverridingMozillaIntPref(MozKey_ImagePermissions, pref, lock); + } + +-GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService): +- mGConfClient(nsnull), +- mGConfLib(nsnull), +- mInitialized(PR_FALSE), +- mSysPrefService(aSysPrefService), +- mObservers(nsnull) ++static nsresult ReverseApplyLoadImages(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) + { ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRInt32 pref; ++ nsresult rv = prefs->GetIntPref(MozKey_ImagePermissions, &pref); ++ if (NS_FAILED(rv)) ++ return rv; ++ gint setting; ++ switch (pref) { ++ case nsIPermissionManager::ALLOW_ACTION: setting = 0; break; ++ case nsIPermissionManager::DENY_ACTION: setting = 2; break; ++ case 3: setting = 1; break; ++ default: return NS_ERROR_FAILURE; ++ } ++ gconf_client_set_int(aClient, GConfKey_LoadImages, setting, nsnull); ++ return NS_OK; + } + +-GConfProxy::~GConfProxy() ++/** ++ * The relationship R is ++ * "/apps/firefox/web/disable_popups" is true if and only if ++ * "dom.disable_open_during_load" is true ++ * AND if "/apps/firefox/web/disable_popups" is true then ++ * "privacy.popups.showBrowserMessage" is false. ++ */ ++static const char MozKey_DisablePopups[] = "dom.disable_open_during_load"; ++static const char MozKey_DisableBrowserPopupMessage[] = "privacy.popups.showBrowserMessage"; ++static const char GConfKey_DisablePopups[] = "/apps/firefox/web/disable_popups"; ++static nsresult ApplyDisablePopups(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) ++{ ++ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisablePopups, nsnull); ++ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisablePopups, nsnull); ++ nsresult rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_DisablePopups, disable, lock); ++ if (NS_SUCCEEDED(rv)) { ++ if (disable) { ++ rv = aPrefService->GetPrefs()-> ++ SetOverridingMozillaBoolPref(MozKey_DisableBrowserPopupMessage, PR_TRUE, lock); ++ } else { ++ rv = aPrefService->GetPrefs()-> ++ StopOverridingMozillaPref(MozKey_DisableBrowserPopupMessage); ++ } ++ } ++ return rv; ++} ++ ++static nsresult ReverseApplyDisablePopups(nsSystemPrefService* aPrefService, ++ GConfClient* aClient) + { +- if (mGConfClient) +- g_object_unref(G_OBJECT(mGConfClient)); ++ nsCOMPtr prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); ++ PRBool disabled; ++ nsresult rv = prefs->GetBoolPref(MozKey_DisablePopups, &disabled); ++ if (NS_FAILED(rv)) ++ return rv; ++ gconf_client_set_bool(aClient, GConfKey_DisablePopups, disabled, nsnull); ++ return NS_OK; ++} + +- if (mObservers) { +- (void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull); +- delete mObservers; +- } ++static ComplexGConfPrefMapping sComplexGConfPrefMappings[] = { ++ {GConfKey_TrustedURIs, ApplyTrustedURIs}, ++ {GConfKey_DelegationURIs, ApplyDelegationURIs}, ++ {GConfKey_IgnoreHosts, ApplyIgnoreHosts}, ++ {GConfKey_ProxyMode, ApplyProxyMode}, ++ {GConfKey_DownloadFolder, ApplyDownloadFolder}, ++ {GConfKey_DisableCookies, ApplyDisableCookies}, ++ {GConfKey_DisableJSChrome, ApplyWindowOpen}, ++ {GConfKey_DisableUnsafeProtocols, ApplyUnsafeProtocols}, ++ {GConfKey_AdditionalSafeProtocols, ApplyUnsafeProtocols}, ++ {GConfKey_WallpaperSetting, ApplyWallpaper}, ++ {GConfKey_DisableSavePassword, ApplyDisableSavePassword}, ++ {GConfKey_LoadImages, ApplyLoadImages}, ++ {GConfKey_DisablePopups, ApplyDisablePopups} ++}; ++static ComplexMozPrefMapping sComplexMozPrefMappings[] = { ++ {MozKey_TrustedURIs, ReverseApplyTrustedURIs}, ++ {MozKey_DelegationURIs, ReverseApplyDelegationURIs}, ++ {MozKey_IgnoreHosts, ReverseApplyIgnoreHosts}, ++ {MozKey_ProxyMode, ReverseApplyProxyMode}, ++ {MozKey_UseDownloadDir, ReverseApplyDownloadFolder}, ++ {MozKey_DownloadDirType, ReverseApplyDownloadFolder}, ++ {MozKey_DownloadDirExplicit, ReverseApplyDownloadFolder}, ++ {MozKey_CookieBehavior, ReverseApplyDisableCookies}, ++ {MozKey_RememberSignons, ReverseApplyDisableSavePassword}, ++ {MozKey_ImagePermissions, ReverseApplyLoadImages}, ++ {MozKey_DisablePopups, ReverseApplyDisablePopups} ++}; ++// The unsafe protocol preferences are handled specially because ++// they affect an unknown number of Mozilla preferences ++// Window opener permissions are also handled specially so we don't have to ++// repeat the windowOpenFeatures list. ++ ++static PR_CALLBACK void GConfSimpleNotification(GConfClient* client, ++ guint cnxn_id, ++ GConfEntry *entry, ++ gpointer user_data) ++{ ++ nsSystemPrefService* service = static_cast(user_data); ++ SimplePrefMapping* map = static_cast( ++ service->GetSimpleCallbackData(cnxn_id)); ++ NS_ASSERTION(map, "Can't find mapping for callback"); ++ if (!map) ++ return; + +- // bug 379666: can't unload GConf-2 since it registers atexit handlers +- //PR_UnloadLibrary(mGConfLib); ++ ApplySimpleMapping(map, service->GetPrefs(), client); + } + +-PRBool +-GConfProxy::Init() +-{ +- SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n")); +- if (!mSysPrefService) +- return PR_FALSE; +- if (mInitialized) +- return PR_TRUE; ++static PR_CALLBACK void GConfComplexNotification(GConfClient* client, ++ guint cnxn_id, ++ GConfEntry *entry, ++ gpointer user_data) ++{ ++ nsSystemPrefService* service = static_cast(user_data); ++ ComplexGConfPrefMapping* map = static_cast( ++ service->GetComplexCallbackData(cnxn_id)); ++ NS_ASSERTION(map, "Can't find mapping for callback"); ++ if (!map) ++ return; + +- nsCOMPtr pref = do_GetService(NS_PREF_CONTRACTID); +- if (!pref) +- return PR_FALSE; ++ map->callback(service, GetGConf()); ++} + +- nsXPIDLCString gconfLibName; +- nsresult rv; ++static const char GConfKey_Homepage_Url[] = ++ "/apps/firefox/general/homepage_url"; + +- //check if gconf-2 library is given in prefs +- rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName)); +- if (NS_SUCCEEDED(rv)) { +- //use the library name in the preference +- SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get())); +- mGConfLib = PR_LoadLibrary(gconfLibName.get()); +- } +- else { +- SYSPREF_LOG(("GConf library not specified in prefs, try the default: " +- "%s and %s\n", sDefaultLibName1, sDefaultLibName2)); +- mGConfLib = PR_LoadLibrary(sDefaultLibName1); +- if (!mGConfLib) +- mGConfLib = PR_LoadLibrary(sDefaultLibName2); ++nsresult nsSystemPrefService::LoadSystemPreferences(nsISystemPref* aPrefs) ++{ ++ mPref = aPrefs; ++ ++ GConfClient* client = GetGConf(); ++ PRUint32 i; ++ nsCOMPtr userPrefs = aPrefs->GetPrefUserBranch(); ++ ++ // Update gconf settings with any Mozilla settings that have ++ // changed from the default. Do it before we register our ++ // gconf notifications. ++ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { ++ gconf_client_add_dir(client, sSimplePrefMappings[i].gconfPrefName, ++ GCONF_CLIENT_PRELOAD_NONE, nsnull); ++ ++ PRBool hasUserPref = PR_FALSE; ++ nsresult rv = ++ userPrefs->PrefHasUserValue(sSimplePrefMappings[i].mozPrefName, ++ &hasUserPref); ++ if (NS_FAILED(rv)) ++ return rv; ++ if (hasUserPref && sSimplePrefMappings[i].allowWritesFromMozilla && ++ gconf_client_key_is_writable(client, ++ sSimplePrefMappings[i].gconfPrefName, ++ nsnull)) { ++ rv = ReverseApplySimpleMapping(&sSimplePrefMappings[i], ++ aPrefs, client); ++ if (NS_FAILED(rv)) ++ return rv; ++ } + } +- +- if (!mGConfLib) { +- SYSPREF_LOG(("Fail to load GConf library\n")); +- return PR_FALSE; ++ for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) { ++ gconf_client_add_dir(client, sComplexGConfPrefMappings[i].gconfPrefName, ++ GCONF_CLIENT_PRELOAD_NONE, nsnull); ++ } ++ ComplexMozPrefChanged lastMozCallback = nsnull; ++ for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) { ++ PRBool hasUserPref = PR_FALSE; ++ nsresult rv = ++ userPrefs->PrefHasUserValue(sComplexMozPrefMappings[i].mozPrefName, ++ &hasUserPref); ++ if (NS_FAILED(rv)) ++ return rv; ++ if (hasUserPref) { ++ ComplexMozPrefChanged cb = sComplexMozPrefMappings[i].callback; ++ if (cb != lastMozCallback) { ++ cb(this, client); ++ lastMozCallback = cb; ++ } ++ } + } +- +- //check every func we need in the gconf library +- GConfFuncListType *funcList; +- PRFuncPtr func; +- for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) { +- func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName); +- if (!func) { +- SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName)); +- goto init_failed_unload; ++ ++ // Register simple mappings and callbacks ++ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { ++ guint cx = gconf_client_notify_add(client, ++ sSimplePrefMappings[i].gconfPrefName, ++ GConfSimpleNotification, this, ++ nsnull, nsnull); ++ mGConfSimpleCallbacks.Put(cx, &sSimplePrefMappings[i]); ++ nsresult rv = ApplySimpleMapping(&sSimplePrefMappings[i], aPrefs, client); ++ if (NS_FAILED(rv)) ++ return rv; ++ } ++ ++ ComplexGConfPrefChanged lastCallback = nsnull; ++ for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) { ++ guint cx = gconf_client_notify_add(client, ++ sComplexGConfPrefMappings[i].gconfPrefName, ++ GConfComplexNotification, this, ++ nsnull, nsnull); ++ mGConfComplexCallbacks.Put(cx, &sComplexGConfPrefMappings[i]); ++ ComplexGConfPrefChanged cb = sComplexGConfPrefMappings[i].callback; ++ if (cb != lastCallback) { ++ cb(this, client); ++ lastCallback = cb; + } +- funcList->FuncPtr = func; + } + +- InitFuncPtrs(); +- +- mGConfClient = GConfClientGetDefault(); +- +- // Don't unload past this point, since GConf's initialization of ORBit +- // causes atexit handlers to be registered. ++ if (!gconf_client_get(client, GConfKey_DisablePopups, nsnull)) ++ { ++ gconf_client_set_bool(client, GConfKey_DisablePopups, true, nsnull); ++ } + +- if (!mGConfClient) { +- SYSPREF_LOG(("Fail to Get default gconf client\n")); +- goto init_failed; ++ if (!gconf_client_get(client, GConfKey_Homepage_Url, nsnull)) ++ { ++ gconf_client_set_string(client, GConfKey_Homepage_Url, "", nsnull); + } +- mInitialized = PR_TRUE; +- return PR_TRUE; + +- init_failed_unload: +- PR_UnloadLibrary(mGConfLib); +- init_failed: +- mGConfLib = nsnull; +- return PR_FALSE; +-} ++ ApplyUnsafeProtocols(this, client); + +-nsresult +-GConfProxy::GetBoolPref(const char *aMozKey, PRBool *retval) +-{ +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- *retval = GConfClientGetBool(mGConfClient, MozKey2GConfKey(aMozKey), NULL); + return NS_OK; + } + +-nsresult +-GConfProxy::GetCharPref(const char *aMozKey, char **retval) ++nsresult nsSystemPrefService::NotifyMozillaPrefChanged(const char* aPrefName) + { +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- +- const gchar *gconfkey = MozKey2GConfKey(aMozKey); +- +- if (!strcmp (aMozKey, "network.proxy.no_proxies_on")) { +- GSList *s; +- nsCString noproxy; +- GSList *gslist = GConfClientGetList(mGConfClient, gconfkey, +- GCONF_VALUE_STRING, NULL); ++ PRUint32 i; ++ GConfClient* client = GetGConf(); + +- for (s = gslist; s; s = g_slist_next(s)) { +- noproxy += (char *)s->data; +- noproxy += ", "; +- g_free ((char *)s->data); ++ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { ++ if (!strcmp(aPrefName, sSimplePrefMappings[i].mozPrefName)) { ++ ReverseApplySimpleMapping(&sSimplePrefMappings[i], ++ mPref, client); + } +- g_slist_free (gslist); ++ } + +- *retval = PL_strdup(noproxy.get()); +- } else { +- gchar *str = GConfClientGetString(mGConfClient, gconfkey, NULL); +- if (str) { +- *retval = PL_strdup(str); +- g_free (str); ++ for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) { ++ if (!strcmp(aPrefName, sComplexMozPrefMappings[i].mozPrefName)) { ++ sComplexMozPrefMappings[i].callback(this, client); + } + } + +- return NS_OK; +-} +- +-nsresult +-GConfProxy::GetIntPref(const char *aMozKey, PRInt32 *retval) +-{ +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- if (strcmp (aMozKey, "network.proxy.type") == 0) { +- gchar *str; +- +- str = GConfClientGetString(mGConfClient, +- MozKey2GConfKey (aMozKey), NULL); +- +- if (str) { +- if (strcmp (str, "manual") == 0) +- *retval = 1; +- else if (strcmp (str, "auto") == 0) +- *retval = 2; +- else +- *retval = 0; +- +- g_free (str); +- } else +- *retval = 0; +- } else { +- *retval = GConfClientGetInt(mGConfClient, +- MozKey2GConfKey(aMozKey), NULL); ++ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { ++ if (!strcmp(aPrefName, windowOpenFeatures[i])) { ++ ReverseApplyWindowOpen(this, client); ++ } + } + ++ ReverseApplyUnsafeProtocols(this, client); ++ + return NS_OK; + } + +-nsresult +-GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData) ++static PLDHashOperator PR_CALLBACK UnregisterSimple(const PRUint32& aKey, ++ SimplePrefMapping* aData, ++ void* aClosure) + { +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- +- const char *gconfKey = GetGConfKey(aAtom); +- if (!gconfKey) +- return NS_ERROR_FAILURE; +- +- if (!mObservers) { +- mObservers = new nsAutoVoidArray(); +- if (mObservers == nsnull) +- return NS_ERROR_OUT_OF_MEMORY; +- } +- +- GConfCallbackData *pData = (GConfCallbackData *) +- nsMemory::Alloc(sizeof(GConfCallbackData)); +- NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY); +- +- pData->proxy = this; +- pData->userData = aUserData; +- pData->atom = aAtom; +- mObservers->AppendElement(pData); +- +- GConfClientAddDir(mGConfClient, gconfKey, +- 0, // GCONF_CLIENT_PRELOAD_NONE, don't preload anything +- NULL); +- +- pData->notifyId = GConfClientNotifyAdd(mGConfClient, gconfKey, +- gconf_key_listener, pData, +- NULL, NULL); +- return NS_OK; ++ GConfClient* client = GetGConf(); ++ gconf_client_notify_remove(client, aKey); ++ gconf_client_remove_dir(client, aData->gconfPrefName, nsnull); ++ return PL_DHASH_NEXT; + } + +-nsresult +-GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData) ++static PLDHashOperator PR_CALLBACK UnregisterComplex(const PRUint32& aKey, ++ ComplexGConfPrefMapping* aData, ++ void* aClosure) + { +- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); +- +- PRIntn count = mObservers->Count(); +- if (count <= 0) +- return NS_OK; +- +- PRIntn i; +- GConfCallbackData *pData; +- for (i = 0; i < count; ++i) { +- pData = (GConfCallbackData *)mObservers->ElementAt(i); +- if (pData && pData->atom == aAtom && pData->userData == aUserData) { +- GConfClientNotifyRemove(mGConfClient, pData->notifyId); +- GConfClientRemoveDir(mGConfClient, +- GetGConfKey(pData->atom), NULL); +- mObservers->RemoveElementAt(i); +- nsMemory::Free(pData); +- break; +- } +- } +- return NS_OK; ++ GConfClient* client = GetGConf(); ++ gconf_client_notify_remove(client, aKey); ++ gconf_client_remove_dir(client, aData->gconfPrefName, nsnull); ++ return PL_DHASH_NEXT; + } + +-void +-GConfProxy::InitFuncPtrs() +-{ +- //gconf client funcs +- GConfClientGetDefault = +- (GConfClientGetDefaultType) sGConfFuncList[0].FuncPtr; +- GConfClientGetBool = +- (GConfClientGetBoolType) sGConfFuncList[1].FuncPtr; +- GConfClientGetString = +- (GConfClientGetStringType) sGConfFuncList[2].FuncPtr; +- GConfClientGetInt = +- (GConfClientGetIntType) sGConfFuncList[3].FuncPtr; +- GConfClientNotifyAdd = +- (GConfClientNotifyAddType) sGConfFuncList[4].FuncPtr; +- GConfClientNotifyRemove = +- (GConfClientNotifyRemoveType) sGConfFuncList[5].FuncPtr; +- GConfClientAddDir = +- (GConfClientAddDirType) sGConfFuncList[6].FuncPtr; +- GConfClientRemoveDir = +- (GConfClientRemoveDirType) sGConfFuncList[7].FuncPtr; +- +- //gconf entry funcs +- GConfEntryGetValue = (GConfEntryGetValueType) sGConfFuncList[8].FuncPtr; +- GConfEntryGetKey = (GConfEntryGetKeyType) sGConfFuncList[9].FuncPtr; +- +- //gconf value funcs +- GConfValueGetBool = (GConfValueGetBoolType) sGConfFuncList[10].FuncPtr; +- GConfValueGetString = (GConfValueGetStringType) sGConfFuncList[11].FuncPtr; +- GConfValueGetInt = (GConfValueGetIntType) sGConfFuncList[12].FuncPtr; +- +- //gconf client list func +- GConfClientGetList = +- (GConfClientGetListType) sGConfFuncList[13].FuncPtr; +-} +- +-void +-GConfProxy::OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId, +- GConfCallbackData *aData) ++nsresult nsSystemPrefService::NotifyUnloadSystemPreferences() + { +- if (!mInitialized || !aEntry || (mGConfClient != aClient) || !aData) +- return; +- +- if (GConfEntryGetValue(aEntry) == NULL) +- return; ++ // Unregister callbacks ++ mGConfSimpleCallbacks.EnumerateRead(UnregisterSimple, this); ++ mGConfSimpleCallbacks.Clear(); ++ mGConfComplexCallbacks.EnumerateRead(UnregisterComplex, this); ++ mGConfComplexCallbacks.Clear(); + +- PRUint32 prefAtom; +- nsresult rv = GetAtomForGConfKey(GConfEntryGetKey(aEntry), &prefAtom); +- if (NS_FAILED(rv)) +- return; +- +- mSysPrefService->OnPrefChange(prefAtom, aData->userData); ++ return NS_OK; + } + +-nsresult +-GConfProxy::GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom) +-{ +- if (!aKey) +- return NS_ERROR_FAILURE; +- PRUint32 prefSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]); +- for (PRUint32 index = 0; index < prefSize; ++index) { +- if (!strcmp((aNameType == 0) ? sPrefNameMapping[index].mozPrefName : +- sPrefNameMapping[index].gconfPrefName, aKey)) { +- *aAtom = index; +- return NS_OK; +- } +- } +- return NS_ERROR_FAILURE; +-} ++// Factory stuff + +-const char * +-GConfProxy::GetKey(PRUint32 aAtom, PRUint8 aNameType) +-{ +- PRUint32 mapSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]); +- if (aAtom >= 0 && aAtom < mapSize) +- return (aNameType == 0) ? sPrefNameMapping[aAtom].mozPrefName : +- sPrefNameMapping[aAtom].gconfPrefName; +- return NULL; +-} ++NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init) + +-inline const char * +-GConfProxy::MozKey2GConfKey(const char *aMozKey) +-{ +- PRUint32 atom; +- nsresult rv = GetAtomForMozKey(aMozKey, &atom); +- if (NS_SUCCEEDED(rv)) +- return GetGConfKey(atom); +- return NULL; +-} ++static const nsModuleComponentInfo components[] = { ++ { NS_SYSTEMPREF_SERVICE_CLASSNAME, ++ NS_SYSTEMPREF_SERVICE_CID, ++ NS_SYSTEMPREF_SERVICE_CONTRACTID, ++ nsSystemPrefServiceConstructor, ++ }, ++}; + +-/* static */ +-void gconf_key_listener (void* client, guint cnxn_id, +- void *entry, gpointer user_data) +-{ +- SYSPREF_LOG(("...SYSPREF_LOG...key listener get called \n")); +- if (!user_data) +- return; +- GConfCallbackData *pData = reinterpret_cast +- (user_data); +- pData->proxy->OnNotify(client, entry, cnxn_id, pData); +-} ++NS_IMPL_NSGETMODULE(nsSystemPrefServiceModule, components) +diff -Naur mozilla.orig/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h mozilla/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h +--- mozilla.orig/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h 2005-02-23 08:15:37.000000000 -0800 ++++ mozilla/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h 1969-12-31 16:00:00.000000000 -0800 +@@ -1,93 +0,0 @@ +-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +-/* vim:expandtab:shiftwidth=4:tabstop=4: +- */ +-/* ***** BEGIN LICENSE BLOCK ***** +- * Version: NPL 1.1/GPL 2.0/LGPL 2.1 +- * +- * +- * The contents of this file are subject to the Mozilla Public +- * License Version 1.1 (the "License"); you may not use this file +- * except in compliance with the License. You may obtain a copy of +- * the License at http://www.mozilla.org/MPL/ +- * +- * Software distributed under the License is distributed on an "AS +- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +- * implied. See the License for the specific language governing +- * rights and limitations under the License. +- * +- * The Original Code is mozilla.org code. +- * +- * The Initial Developer of the Original Code is Sun Microsystems, Inc. +- * Portions created by Sun Microsystems are Copyright (C) 2003 Sun +- * Microsystems, Inc. All Rights Reserved. +- * +- * Original Author: Bolian Yin (bolian.yin@sun.com) +- * +- * Contributor(s): +- * +- * Alternatively, the contents of this file may be used under the terms of +- * either the GNU General Public License Version 2 or later (the "GPL"), or +- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +- * in which case the provisions of the GPL or the LGPL are applicable instead +- * of those above. If you wish to allow use of your version of this file only +- * under the terms of either the GPL or the LGPL, and not to allow others to +- * use your version of this file under the terms of the NPL, indicate your +- * decision by deleting the provisions above and replace them with the notice +- * and other provisions required by the GPL or the LGPL. If you do not delete +- * the provisions above, a recipient may use your version of this file under +- * the terms of any one of the NPL, the GPL or the LGPL. +- * +- * ***** END LICENSE BLOCK ***** */ +- +-#ifndef __SYSTEM_PREF_SERVICE_H__ +-#define __SYSTEM_PREF_SERVICE_H__ +- +-#include "prlink.h" +-#include "nsVoidArray.h" +-#include "nsWeakPtr.h" +-#include "nsIPrefBranch.h" +-#include "nsIPrefBranch2.h" +- +-class GConfProxy; +- +-//////////////////////////////////////////////////////////////////////////// +-// nsSystemPrefService provide a interface for read system prefs. It is +-// platform related. This directory (system-pref/gconf) impls it for gconf +-// on the gconf platform. +-//////////////////////////////////////////////////////////////////////////// +- +-class nsSystemPrefService : public nsIPrefBranch2 +-{ +-public: +- NS_DECL_ISUPPORTS +- NS_DECL_NSIPREFBRANCH +- NS_DECL_NSIPREFBRANCH2 +- +- nsSystemPrefService(); +- virtual ~nsSystemPrefService(); +- nsresult Init(); +- +- void OnPrefChange(PRUint32 aPrefAtom, void *aData); +- +-private: +- PRBool mInitialized; +- GConfProxy *mGConf; +- +- //listeners +- nsAutoVoidArray *mObservers; +-}; +- +-#define NS_SYSTEMPREF_SERVICE_CID \ +- { /* {94f1de09-d0e5-4ca8-94c2-98b049316b7f} */ \ +- 0x94f1de09, \ +- 0xd0e5, \ +- 0x4ca8, \ +- { 0x94, 0xc2, 0x98, 0xb0, 0x49, 0x31, 0x6b, 0x7f } \ +- } +- +-#define NS_SYSTEMPREF_SERVICE_CONTRACTID "@mozilla.org/system-preference-service;1" +-#define NS_SYSTEMPREF_SERVICE_CLASSNAME "System Preferences Service" +- +-#define NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID "nsSystemPrefService:pref-changed" +- +-#endif /* __SYSTEM_PREF_SERVICE_H__ */ +diff -Naur mozilla.orig/extensions/pref/system-pref/src/Makefile.in mozilla/extensions/pref/system-pref/src/Makefile.in +--- mozilla.orig/extensions/pref/system-pref/src/Makefile.in 2005-12-31 04:14:42.000000000 -0800 ++++ mozilla/extensions/pref/system-pref/src/Makefile.in 2008-04-01 16:50:49.000000000 -0700 +@@ -43,12 +43,14 @@ + include $(DEPTH)/config/autoconf.mk + + MODULE = system-pref +-LIBRARY_NAME = system-pref_s ++MODULE_NAME = nsSystemPrefModule ++LIBRARY_NAME = system-pref + ifneq ($(OS_ARCH),WINNT) + SHORT_LIBNAME = syspref + endif + +-# We want to force the creation of a static lib. ++IS_COMPONENT = 1 ++EXPORT_LIBRARY = 1 + FORCE_STATIC_LIB = 1 + LIBXUL_LIBRARY = 1 + +@@ -58,27 +60,22 @@ + pref \ + $(NULL) + +-ifdef MOZ_ENABLE_GTK2 ++ifdef MOZ_ENABLE_GCONF + DIRS = gconf + endif + +-EXTRA_DSO_LDOPTS = \ +- -L$(DIST)/bin \ +- $(MOZ_COMPONENT_LIBS) \ +- $(NULL) +- + CPPSRCS = \ + nsSystemPref.cpp \ ++ nsSystemPrefFactory.cpp \ + $(NULL) + ++EXTRA_DSO_LDOPTS = \ ++ $(MOZ_COMPONENT_LIBS) \ ++ $(NULL) ++ + EXPORTS = \ +- nsSystemPrefLog.h \ ++ nsISystemPrefService.h \ + $(NULL) + +-include $(topsrcdir)/config/rules.mk + +-ifdef MOZ_ENABLE_GTK2 +-INCLUDES += \ +- -I$(srcdir)/gconf \ +- $(NULL) +-endif ++include $(topsrcdir)/config/rules.mk +diff -Naur mozilla.orig/extensions/pref/system-pref/src/nsISystemPrefService.h mozilla/extensions/pref/system-pref/src/nsISystemPrefService.h +--- mozilla.orig/extensions/pref/system-pref/src/nsISystemPrefService.h 1969-12-31 16:00:00.000000000 -0800 ++++ mozilla/extensions/pref/system-pref/src/nsISystemPrefService.h 2008-04-01 16:50:49.000000000 -0700 +@@ -0,0 +1,109 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* vim:expandtab:shiftwidth=4:tabstop=4: ++ */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * ++ * The contents of this file are subject to the Mozilla Public ++ * License Version 1.1 (the "License"); you may not use this file ++ * except in compliance with the License. You may obtain a copy of ++ * the License at http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * The Original Code is mozilla.org code. ++ * ++ * The Initial Developer of the Original Code is Novell ++ * Portions created by Novell are Copyright (C) 2005 Novell, ++ * All Rights Reserved. ++ * ++ * Original Author: Robert O'Callahan (rocallahan@novell.com) ++ * ++ * Contributor(s): ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the NPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the NPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#ifndef nsISystemPrefService_h__ ++#define nsISystemPrefService_h__ ++ ++#include "nsCOMPtr.h" ++#include "nsIPrefBranchInternal.h" ++ ++#define NS_SYSTEMPREF_SERVICE_CONTRACTID "@mozilla.org/system-preferences-service;1" ++ ++#define NS_ISYSTEMPREFSERVICE_IID \ ++{ 0x006e1cfd, 0xd66a, 0x40b9, \ ++ { 0x84, 0xa1, 0x84, 0xf3, 0xe6, 0xa2, 0xca, 0xbc } } ++ ++class nsISystemPref { ++public: ++ /** ++ * Call one of these three methods to override a Mozilla ++ * preference with a system value. You can call it multiple ++ * times to change the value of a given preference to track ++ * the underlying system value. ++ * ++ * If aLocked is true then we set the default preference and ++ * lock it so the user value is ignored. If aLocked is false ++ * then we unlock the Mozilla preference and set the Mozilla ++ * user value. ++ */ ++ virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName, ++ PRBool aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE) = 0; ++ virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName, ++ PRInt32 aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE) = 0; ++ virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName, ++ const char* aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE) = 0; ++ virtual nsresult StopOverridingMozillaPref(const char* aPrefName) = 0; ++ virtual already_AddRefed GetPrefUserBranch() = 0; ++ virtual already_AddRefed GetPrefDefaultBranch() = 0; ++}; ++ ++class nsISystemPrefService : public nsISupports { ++public: ++ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISYSTEMPREFSERVICE_IID) ++ ++ /** ++ * Load the system prefs from the store into their corresponding ++ * Mozilla prefs, calling SetOverridingMozillaPref on each ++ * such pref. ++ */ ++ virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs) = 0; ++ ++ /** ++ * Notify that a Mozilla user pref that is being overridden by the ++ * store has changed. The new value of the Mozilla pref should be ++ * written back to the store. ++ */ ++ virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName) = 0; ++ ++ /** ++ * Notify that we're about to stop using the system prefs. After ++ * this, nsSystemPref will automatically stop overriding all ++ * Mozilla prefs that are being overridden. ++ */ ++ virtual nsresult NotifyUnloadSystemPreferences() = 0; ++}; ++ ++NS_DEFINE_STATIC_IID_ACCESSOR(nsISystemPrefService, NS_ISYSTEMPREFSERVICE_IID) ++ ++#endif +diff -Naur mozilla.orig/extensions/pref/system-pref/src/nsSystemPref.cpp mozilla/extensions/pref/system-pref/src/nsSystemPref.cpp +--- mozilla.orig/extensions/pref/system-pref/src/nsSystemPref.cpp 2006-04-17 15:03:46.000000000 -0700 ++++ mozilla/extensions/pref/system-pref/src/nsSystemPref.cpp 2008-04-01 16:50:49.000000000 -0700 +@@ -24,6 +24,7 @@ + * Original Author: Bolian Yin (bolian.yin@sun.com) + * + * Contributor(s): ++ * Robert O'Callahan (rocallahan@novell.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -41,66 +42,60 @@ + + #include "nsSystemPref.h" + #include "nsIObserverService.h" ++#include "nsIAppStartupNotifier.h" ++#include "nsIPrefService.h" ++#include "nsIPrefBranch.h" ++#include "nsICategoryManager.h" ++#include "nsIServiceManager.h" + + #include "nsSystemPrefLog.h" +-#include "nsSystemPrefService.h" + #include "nsString.h" + +-const char sSysPrefString[] = "config.use_system_prefs"; +-union MozPrefValue { +- char * stringVal; +- PRInt32 intVal; +- PRBool boolVal; +-}; ++#include + + struct SysPrefItem { +- const char *prefName; // mozilla pref string name +- MozPrefValue defaultValue; // store the mozilla default value +- PRBool isLocked; // store the mozilla lock status ++ // Saved values on both branches ++ PRInt32 savedUserValueScalar; ++ char* savedUserValueString; ++ PRInt32 savedDefaultValueScalar; ++ char* savedDefaultValueString; ++ // When this is true, then the value was locked originally ++ PRPackedBool savedLocked; ++ // When this is true, then there was a user value ++ PRPackedBool savedUserPresent; ++ PRPackedBool ignore; ++ + SysPrefItem() { +- prefName = nsnull; +- defaultValue.intVal = 0; +- defaultValue.stringVal = nsnull; +- defaultValue.boolVal = PR_FALSE; +- isLocked = PR_FALSE; ++ savedUserValueScalar = 0; ++ savedUserValueString = nsnull; ++ savedDefaultValueScalar = 0; ++ savedDefaultValueString = nsnull; ++ savedUserPresent = PR_FALSE; ++ savedLocked = PR_FALSE; ++ ignore = PR_FALSE; + } +- void SetPrefName(const char *aPrefName) { +- prefName = aPrefName; ++ ++ virtual ~SysPrefItem() { ++ nsMemory::Free(savedUserValueString); ++ nsMemory::Free(savedDefaultValueString); + } + }; + +-// all prefs that mozilla need to read from host system if they are available +-static const char *sSysPrefList[] = { +- "network.proxy.http", +- "network.proxy.http_port", +- "network.proxy.ftp", +- "network.proxy.ftp_port", +- "network.proxy.ssl", +- "network.proxy.ssl_port", +- "network.proxy.socks", +- "network.proxy.socks_port", +- "network.proxy.no_proxies_on", +- "network.proxy.autoconfig_url", +- "network.proxy.type", +- "config.use_system_prefs.accessibility", +-}; ++static const char sSysPrefString[] = "config.use_system_prefs"; + + PRLogModuleInfo *gSysPrefLog = NULL; + + NS_IMPL_ISUPPORTS2(nsSystemPref, nsIObserver, nsISupportsWeakReference) + +-nsSystemPref::nsSystemPref(): +- mSysPrefService(nsnull), +- mEnabled(PR_FALSE), +- mSysPrefs(nsnull) ++nsSystemPref::nsSystemPref() : mIgnorePrefSetting(PR_FALSE) + { ++ mSavedPrefs.Init(); ++ mCachedUserPrefBranch = nsnull; ++ mCachedDefaultPrefBranch = nsnull; + } + + nsSystemPref::~nsSystemPref() + { +- mSysPrefService = nsnull; +- mEnabled = PR_FALSE; +- delete [] mSysPrefs; + } + + /////////////////////////////////////////////////////////////////////////////// +@@ -131,6 +126,54 @@ + return(rv); + } + ++already_AddRefed ++nsSystemPref::GetPrefUserBranch() ++{ ++ if (mCachedUserPrefBranch) { ++ NS_ADDREF(mCachedUserPrefBranch); ++ return mCachedUserPrefBranch; ++ } ++ ++ nsresult rv; ++ nsCOMPtr prefService = ++ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ nsCOMPtr prefBranch; ++ rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch)); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ nsCOMPtr pb2(do_QueryInterface(prefBranch)); ++ if (!pb2) ++ return nsnull; ++ ++ nsIPrefBranch2* result = nsnull; ++ pb2.swap(result); ++ return result; ++} ++ ++already_AddRefed ++nsSystemPref::GetPrefDefaultBranch() ++{ ++ if (mCachedDefaultPrefBranch) { ++ NS_ADDREF(mCachedDefaultPrefBranch); ++ return mCachedDefaultPrefBranch; ++ } ++ ++ nsresult rv; ++ nsCOMPtr prefService = ++ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ nsCOMPtr prefBranch; ++ rv = prefService->GetDefaultBranch(nsnull, getter_AddRefs(prefBranch)); ++ if (NS_FAILED(rv)) ++ return nsnull; ++ nsIPrefBranch* pb = nsnull; ++ prefBranch.swap(pb); ++ return pb; ++} ++ + /////////////////////////////////////////////////////////////////////////////// + // nsSystemPref::Observe + // Observe notifications from mozilla pref system and system prefs (if enabled) +@@ -145,330 +188,438 @@ + if (!aTopic) + return NS_OK; + +- // if we are notified by pref service +- // check the system pref settings ++ nsCOMPtr userBranch = GetPrefUserBranch(); ++ PRBool enabled; ++ rv = userBranch->GetBoolPref(sSysPrefString, &enabled); ++ if (NS_FAILED(rv)) { ++ SYSPREF_LOG(("...Failed to Get %s\n", sSysPrefString)); ++ return rv; ++ } ++ + if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) { ++ // The prefs have just loaded. This is the first thing that ++ // happens to us. + SYSPREF_LOG(("Observed: %s\n", aTopic)); + +- nsCOMPtr prefBranch = +- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); +- if (NS_FAILED(rv)) +- return rv; +- +- rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled); ++ // listen on changes to use_system_pref. It's OK to ++ // hold a strong reference because we don't keep a reference ++ // to the pref branch. ++ rv = userBranch->AddObserver(sSysPrefString, this, PR_TRUE); + if (NS_FAILED(rv)) { +- SYSPREF_LOG(("...FAil to Get %s\n", sSysPrefString)); ++ SYSPREF_LOG(("...Failed to add observer for %s\n", sSysPrefString)); + return rv; + } + +- // if there is no system pref service, assume nothing happen to us +- mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv); +- if (NS_FAILED(rv) || !mSysPrefService) { +- SYSPREF_LOG(("...No System Pref Service\n")); ++ NS_ASSERTION(!mSysPrefService, "Should not be already enabled"); ++ if (!enabled) { ++ // Don't load the system pref service if the preference is ++ // not set. + return NS_OK; + } + +- // listen on its changes +- rv = prefBranch->AddObserver(sSysPrefString, this, PR_TRUE); +- if (NS_FAILED(rv)) { +- SYSPREF_LOG(("...FAil to add observer for %s\n", sSysPrefString)); +- return rv; +- } +- +- if (!mEnabled) { +- SYSPREF_LOG(("%s is disabled\n", sSysPrefString)); +- return NS_OK; +- } + SYSPREF_LOG(("%s is enabled\n", sSysPrefString)); +- rv = UseSystemPrefs(); +- +- } +- // sSysPrefString value was changed, update ... +- else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && +- NS_ConvertUTF8toUTF16(sSysPrefString).Equals(aData)) { +- SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n", +- aTopic, NS_ConvertUTF16toUTF8(aData).get())); + +- nsCOMPtr prefBranch = +- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); ++ rv = LoadSystemPrefs(); + if (NS_FAILED(rv)) + return rv; + +- PRBool enabled = mEnabled; +- rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled); +- if (enabled != mEnabled) { +- if (mEnabled) +- //read prefs from system +- rv = UseSystemPrefs(); +- else +- //roll back to mozilla prefs +- rv = UseMozillaPrefs(); ++ // Lock config.use_system_prefs so the user can't undo ++ // it. Really this should already be locked because if it's ++ // not locked at a lower level the user can set it to false in ++ // their in prefs.js. But only do this if the value was not ++ // specially set by the user; if it was set by the user, then ++ // locking it would actually unset the value! And the user ++ // should be allowed to turn off something they set ++ // themselves. ++ PRBool hasUserValue; ++ rv = userBranch->PrefHasUserValue(sSysPrefString, &hasUserValue); ++ if (NS_SUCCEEDED(rv) && !hasUserValue) { ++ userBranch->LockPref(sSysPrefString); + } + } + +- // if the system pref notify us that some pref has been changed by user +- // outside mozilla. We need to read it again. +- else if (!nsCRT::strcmp(aTopic, NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID) && +- aData) { +- NS_ASSERTION(mEnabled == PR_TRUE, "Should not listen when disabled"); +- SYSPREF_LOG(("====== System Pref Notify topic=%s data=%s\n", +- aTopic, (char*)aData)); +- rv = ReadSystemPref(NS_LossyConvertUTF16toASCII(aData).get()); +- return NS_OK; +- } else if (!nsCRT::strcmp(aTopic,"profile-before-change")) { +- //roll back to mozilla prefs +- if (mEnabled) +- UseMozillaPrefs(); +- mEnabled = PR_FALSE; +- mSysPrefService = nsnull; +- delete [] mSysPrefs; +- mSysPrefs = nsnull; +- } else +- SYSPREF_LOG(("Not needed topic Received %s\n", aTopic)); +- return rv; +-} ++ if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && ++ nsDependentString(aData).EqualsASCII(sSysPrefString)) { ++ // sSysPrefString value was changed, update... ++ SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n", ++ aTopic, NS_ConvertUTF16toUTF8(aData).get())); ++ if (mSysPrefService && !enabled) ++ return RestoreMozillaPrefs(); ++ if (!mSysPrefService && enabled) { ++ // Don't lock it. If the user enabled use_system_prefs, ++ // they should be allowed to unlock it. ++ return LoadSystemPrefs(); ++ } + +-/* private */ ++ // didn't change? ++ return NS_OK; ++ } + +-//////////////////////////////////////////////////////////////// +-// nsSystemPref::UseSystemPrefs +-// Read all the prefs in the table from system, listen for their +-// changes in system pref service. +-//////////////////////////////////////////////////////////////// +-nsresult +-nsSystemPref::UseSystemPrefs() +-{ +- SYSPREF_LOG(("\n====Now Use system prefs==\n")); +- nsresult rv = NS_OK; +- if (!mSysPrefService) { +- return NS_ERROR_FAILURE; ++ if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { ++ // some other pref changed, tell the backend if there is one ++ if (mSysPrefService && !mIgnorePrefSetting) { ++ NS_LossyConvertUTF16toASCII tmp(aData); ++#ifdef DEBUG ++ PRBool isLocked; ++ userBranch->PrefIsLocked(tmp.get(), &isLocked); ++ NS_ASSERTION(!isLocked, "Locked pref is changing?"); ++#endif ++ SysPrefItem* item; ++ if (!mSavedPrefs.Get(tmp, &item)) { ++ NS_ERROR("Notified about pref change that we didn't ask about?"); ++ } else { ++ if (!item->ignore) { ++ mSysPrefService->NotifyMozillaPrefChanged(tmp.get()); ++ } ++ } ++ } ++ return NS_OK; + } + +- PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]); ++ if (!nsCRT::strcmp(aTopic,"profile-before-change")) ++ return RestoreMozillaPrefs(); + +- if (!mSysPrefs) { +- mSysPrefs = new SysPrefItem[sysPrefCount]; +- if (!mSysPrefs) +- return NS_ERROR_OUT_OF_MEMORY; +- for (PRIntn index = 0; index < sysPrefCount; ++index) +- mSysPrefs[index].SetPrefName(sSysPrefList[index]); +- } ++ SYSPREF_LOG(("Not needed topic Received %s\n", aTopic)); + +- for (PRIntn index = 0; index < sysPrefCount; ++index) { +- // save mozilla prefs +- SaveMozDefaultPref(mSysPrefs[index].prefName, +- &mSysPrefs[index].defaultValue, +- &mSysPrefs[index].isLocked); +- +- // get the system prefs +- ReadSystemPref(mSysPrefs[index].prefName); +- SYSPREF_LOG(("Add Listener on %s\n", mSysPrefs[index].prefName)); +- mSysPrefService->AddObserver(mSysPrefs[index].prefName, +- this, PR_TRUE); +- } + return rv; + } + +-////////////////////////////////////////////////////////////////////// +-// nsSystemPref::ReadSystemPref +-// Read a pref value from system pref service, and lock it in mozilla. +-////////////////////////////////////////////////////////////////////// + nsresult +-nsSystemPref::ReadSystemPref(const char *aPrefName) ++nsSystemPref::SetOverridingMozillaBoolPref(const char* aPrefName, ++ PRBool aValue, PRBool aLock, PRBool aPresent) + { +- if (!mSysPrefService) +- return NS_ERROR_FAILURE; +- nsresult rv; +- +- nsCOMPtr prefBranch +- (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); +- if (NS_FAILED(rv)) +- return rv; +- +- SYSPREF_LOG(("about to read aPrefName %s\n", aPrefName)); ++ return OverridePref(aPrefName, nsIPrefBranch::PREF_BOOL, ++ (void*)aValue, aLock, aPresent); ++} + +- prefBranch->UnlockPref(aPrefName); ++nsresult ++nsSystemPref::SetOverridingMozillaIntPref(const char* aPrefName, ++ PRInt32 aValue, PRBool aLock, PRBool aPresent) ++{ ++ return OverridePref(aPrefName, nsIPrefBranch::PREF_INT, ++ (void*)aValue, aLock, aPresent); ++} + +- PRInt32 prefType = nsIPrefBranch::PREF_INVALID; +- nsXPIDLCString strValue; +- PRInt32 intValue = 0; +- PRBool boolValue = PR_FALSE; ++nsresult ++nsSystemPref::SetOverridingMozillaStringPref(const char* aPrefName, ++ const char* aValue, PRBool aLock, PRBool aPresent) ++{ ++ return OverridePref(aPrefName, nsIPrefBranch::PREF_STRING, ++ (void*)aValue, aLock, aPresent); ++} + +- rv = prefBranch->GetPrefType(aPrefName, &prefType); +- if (NS_FAILED(rv)) +- return rv; +- switch (prefType) { ++static nsresult RestorePrefValue(PRInt32 aPrefType, ++ const char* aPrefName, ++ SysPrefItem* aItem, ++ nsIPrefBranch* aUser, ++ nsIPrefBranch* aDefault) ++{ ++ switch (aPrefType) { + case nsIPrefBranch::PREF_STRING: +- mSysPrefService->GetCharPref(aPrefName, getter_Copies(strValue)); +- SYSPREF_LOG(("system value is %s\n", strValue.get())); +- +- prefBranch->SetCharPref(aPrefName, strValue.get()); ++ aDefault->SetCharPref(aPrefName, ++ aItem->savedDefaultValueString); ++ if (aItem->savedUserPresent) { ++ aUser->SetCharPref(aPrefName, aItem->savedUserValueString); ++ } + break; + case nsIPrefBranch::PREF_INT: +- mSysPrefService->GetIntPref(aPrefName, &intValue); +- SYSPREF_LOG(("system value is %d\n", intValue)); +- +- prefBranch->SetIntPref(aPrefName, intValue); ++ aDefault->SetIntPref(aPrefName, aItem->savedDefaultValueScalar); ++ if (aItem->savedUserPresent) { ++ aUser->SetIntPref(aPrefName, aItem->savedUserValueScalar); ++ } + break; + case nsIPrefBranch::PREF_BOOL: +- mSysPrefService->GetBoolPref(aPrefName, &boolValue); +- SYSPREF_LOG(("system value is %s\n", boolValue ? "TRUE" : "FALSE")); +- +- prefBranch->SetBoolPref(aPrefName, boolValue); ++ aDefault->SetBoolPref(aPrefName, aItem->savedDefaultValueScalar); ++ if (aItem->savedUserPresent) { ++ aUser->SetBoolPref(aPrefName, aItem->savedUserValueScalar); ++ } + break; + default: +- SYSPREF_LOG(("Fail to system value for it\n")); ++ NS_ERROR("Unknown preference type"); + return NS_ERROR_FAILURE; + } +- prefBranch->LockPref(aPrefName); ++ ++ if (!aItem->savedUserPresent) { ++ aUser->DeleteBranch(aPrefName); ++ } ++ + return NS_OK; + } + +-////////////////////////////////////////////////////////////////////// +-// nsSystemPref::UseMozillaPrefs +-// Restore mozilla default prefs, remove system pref listeners +-///////////////////////////////////////////////////////////////////// +-nsresult +-nsSystemPref::UseMozillaPrefs() ++static PLDHashOperator PR_CALLBACK RestorePref(const nsACString& aKey, ++ SysPrefItem* aItem, ++ void* aClosure) + { +- nsresult rv = NS_OK; +- SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n")); ++ nsSystemPref* prefs = static_cast(aClosure); ++ nsCOMPtr userBranch = prefs->GetPrefUserBranch(); ++ const nsCString& prefName = PromiseFlatCString(aKey); ++ ++ PRInt32 prefType = nsIPrefBranch::PREF_INVALID; ++ nsresult rv = userBranch->GetPrefType(prefName.get(), &prefType); ++ if (NS_FAILED(rv)) ++ return PL_DHASH_NEXT; ++ PRBool isLocked; ++ userBranch->PrefIsLocked(prefName.get(), &isLocked); ++ if (NS_FAILED(rv)) ++ return PL_DHASH_NEXT; + +- // if we did not use system prefs, do nothing +- if (!mSysPrefService) +- return NS_OK; ++ // Remove our observer before we change the value ++ userBranch->RemoveObserver(prefName.get(), prefs); ++ // Remember to ignore this item. Because some prefs start with "config.use_system_prefs", ++ // which we always observe, even after we remove the observer, changes to the pref will ++ // still be observed by us. We must ignore them. ++ aItem->ignore = PR_TRUE; + +- PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]); +- for (PRIntn index = 0; index < sysPrefCount; ++index) { +- // restore mozilla default value and free string memory if needed +- RestoreMozDefaultPref(mSysPrefs[index].prefName, +- &mSysPrefs[index].defaultValue, +- mSysPrefs[index].isLocked); +- SYSPREF_LOG(("stop listening on %s\n", mSysPrefs[index].prefName)); +- mSysPrefService->RemoveObserver(mSysPrefs[index].prefName, +- this); ++ // Unlock the pref so we can set it ++ if (isLocked) { ++ userBranch->UnlockPref(prefName.get()); + } +- return rv; ++ ++ nsCOMPtr defaultBranch = prefs->GetPrefDefaultBranch(); ++ ++ RestorePrefValue(prefType, prefName.get(), aItem, ++ userBranch, defaultBranch); ++ ++ if (aItem->savedLocked) { ++ userBranch->LockPref(prefName.get()); ++ } ++ ++ return PL_DHASH_NEXT; + } + +-//////////////////////////////////////////////////////////////////////////// +-// nsSystemPref::RestoreMozDefaultPref +-// Save the saved mozilla default value. +-// It is also responsible for allocate the string memory when needed, because +-// this method know what type of value is stored. +-///////////////////////////////////////////////////////////////////////////// + nsresult +-nsSystemPref::SaveMozDefaultPref(const char *aPrefName, +- MozPrefValue *aPrefValue, +- PRBool *aLocked) +-{ +- NS_ENSURE_ARG_POINTER(aPrefName); +- NS_ENSURE_ARG_POINTER(aPrefValue); +- NS_ENSURE_ARG_POINTER(aLocked); +- +- nsresult rv; ++nsSystemPref::StopOverridingMozillaPref(const char* aPrefName) ++{ ++ SysPrefItem* item; ++ nsDependentCString prefNameStr(aPrefName); ++ if (!mSavedPrefs.Get(prefNameStr, &item)) ++ return NS_OK; + +- nsCOMPtr prefBranch = +- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); +- if (NS_FAILED(rv)) +- return rv; ++ RestorePref(prefNameStr, item, this); ++ mSavedPrefs.Remove(prefNameStr); ++ //delete item; ++ return NS_OK; ++} + +- SYSPREF_LOG(("Save Mozilla value for %s\n", aPrefName)); ++/* private */ + ++nsresult ++nsSystemPref::OverridePref(const char* aPrefName, PRInt32 aType, ++ void* aValue, PRBool aLock, PRBool aPresent) ++{ ++ nsCOMPtr userBranch = GetPrefUserBranch(); ++ nsCOMPtr defaultBranch = GetPrefDefaultBranch(); + PRInt32 prefType = nsIPrefBranch::PREF_INVALID; +- nsXPIDLCString strValue; +- +- rv = prefBranch->GetPrefType(aPrefName, &prefType); ++ nsresult rv = userBranch->GetPrefType(aPrefName, &prefType); + if (NS_FAILED(rv)) + return rv; +- switch (prefType) { +- case nsIPrefBranch::PREF_STRING: +- prefBranch->GetCharPref(aPrefName, +- getter_Copies(strValue)); +- SYSPREF_LOG(("Mozilla value is %s", strValue.get())); +- +- if (aPrefValue->stringVal) +- PL_strfree(aPrefValue->stringVal); +- aPrefValue->stringVal = PL_strdup(strValue.get()); +- break; +- case nsIPrefBranch::PREF_INT: +- prefBranch->GetIntPref(aPrefName, &aPrefValue->intVal); +- SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal)); + +- break; +- case nsIPrefBranch::PREF_BOOL: +- prefBranch->GetBoolPref(aPrefName, &aPrefValue->boolVal); +- SYSPREF_LOG(("Mozilla value is %s\n", +- aPrefValue->boolVal ? "TRUE" : "FALSE")); ++ PRBool isLocked; ++ rv = userBranch->PrefIsLocked(aPrefName, &isLocked); ++ if (NS_FAILED(rv)) ++ return rv; ++ PRBool hasUserValue; ++ rv = userBranch->PrefHasUserValue(aPrefName, &hasUserValue); ++ if (NS_FAILED(rv)) ++ return rv; + +- break; +- default: +- SYSPREF_LOG(("Fail to Read Mozilla value for it\n")); +- return NS_ERROR_FAILURE; ++ if (prefType == 0) { ++ // Preference does not exist. Allow the system prefs to ++ // set it. ++ } else { ++ NS_ASSERTION(aType == prefType, ++ "System pref engine passed incorrect type for Mozilla pref"); ++ if (aType != prefType) ++ return NS_ERROR_FAILURE; ++ } ++ ++ if (prefType != 0) { ++ nsDependentCString prefNameStr(aPrefName); ++ SysPrefItem* item = nsnull; ++ if (!mSavedPrefs.Get(prefNameStr, &item)) { ++ // Need to save the existing value away ++ item = new SysPrefItem(); ++ if (!item) ++ return NS_ERROR_OUT_OF_MEMORY; ++ ++ item->savedLocked = isLocked; ++ item->savedUserPresent = hasUserValue; ++ ++ switch (prefType) { ++ case nsIPrefBranch::PREF_STRING: ++ if (hasUserValue) { ++ userBranch->GetCharPref(aPrefName, &item->savedUserValueString); ++ } ++ defaultBranch->GetCharPref(aPrefName, &item->savedDefaultValueString); ++ break; ++ case nsIPrefBranch::PREF_INT: ++ if (hasUserValue) { ++ userBranch->GetIntPref(aPrefName, &item->savedUserValueScalar); ++ } ++ defaultBranch->GetIntPref(aPrefName, &item->savedDefaultValueScalar); ++ break; ++ case nsIPrefBranch::PREF_BOOL: ++ if (hasUserValue) { ++ userBranch->GetBoolPref(aPrefName, &item->savedUserValueScalar); ++ } ++ defaultBranch->GetBoolPref(aPrefName, &item->savedDefaultValueScalar); ++ break; ++ default: ++ NS_ERROR("Unknown preference type"); ++ delete item; ++ return NS_ERROR_FAILURE; ++ } ++ ++ mSavedPrefs.Put(prefNameStr, item); ++ ++ // Watch the user value in case it changes on the Mozilla side ++ // If 'aLock' is true then it shouldn't change and we don't ++ // need the observer, but don't bother optimizing for that. ++ userBranch->AddObserver(aPrefName, this, PR_TRUE); ++ } else { ++ if (isLocked != aLock) { ++ // restore pref value on user and default branches ++ RestorePrefValue(prefType, aPrefName, item, ++ userBranch, defaultBranch); ++ } ++ } + } +- rv = prefBranch->PrefIsLocked(aPrefName, aLocked); +- SYSPREF_LOG((" (%s).\n", aLocked ? "Locked" : "NOT Locked")); +- return rv; +-} + +-//////////////////////////////////////////////////////////////////////////// +-// nsSystemPref::RestoreMozDefaultPref +-// Restore the saved mozilla default value to pref service. +-// It is also responsible for free the string memory when needed, because +-// this method know what type of value is stored. +-///////////////////////////////////////////////////////////////////////////// +-nsresult +-nsSystemPref::RestoreMozDefaultPref(const char *aPrefName, +- MozPrefValue *aPrefValue, +- PRBool aLocked) +-{ +- NS_ENSURE_ARG_POINTER(aPrefName); ++ // We need to ignore pref changes due to our own calls here ++ mIgnorePrefSetting = PR_TRUE; + +- nsresult rv; ++ // Unlock it if it's locked, so we can set it ++ if (isLocked) { ++ rv = userBranch->UnlockPref(aPrefName); ++ if (NS_FAILED(rv)) ++ return rv; ++ } + +- nsCOMPtr prefBranch = +- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); ++ // Set the pref on the default branch if we're locking it, because ++ // only the default branch gets used when the pref is locked. ++ // Set the pref on the user branch if we're not locking it, because ++ // that's where the user change will go. ++ nsIPrefBranch* settingBranch = ++ aLock ? defaultBranch.get() : static_cast(userBranch.get()); ++ ++ if (!aPresent) { ++ rv = settingBranch->DeleteBranch(aPrefName); ++ } else { ++ switch (aType) { ++ case nsIPrefBranch::PREF_STRING: ++ rv = settingBranch->SetCharPref(aPrefName, (const char*)aValue); ++ break; ++ case nsIPrefBranch::PREF_INT: ++ rv = settingBranch->SetIntPref(aPrefName, (PRInt32)(NS_PTR_TO_INT32(aValue))); ++ break; ++ case nsIPrefBranch::PREF_BOOL: ++ rv = settingBranch->SetBoolPref(aPrefName, (PRBool)(NS_PTR_TO_INT32(aValue))); ++ break; ++ default: ++ NS_ERROR("Unknown preference type"); ++ mIgnorePrefSetting = PR_FALSE; ++ return NS_ERROR_FAILURE; ++ } ++ } + if (NS_FAILED(rv)) + return rv; ++ if (aLock) { ++ rv = userBranch->LockPref(aPrefName); ++ } + +- SYSPREF_LOG(("Restore Mozilla value for %s\n", aPrefName)); ++ mIgnorePrefSetting = PR_FALSE; ++ return rv; ++} + +- PRInt32 prefType = nsIPrefBranch::PREF_INVALID; +- rv = prefBranch->GetPrefType(aPrefName, &prefType); ++nsresult ++nsSystemPref::FixupLockdownPrefs() ++{ ++ nsCOMPtr userPrefs = GetPrefUserBranch(); ++ nsCOMPtr defaultPrefs = GetPrefUserBranch(); ++ PRUint32 childCount; ++ char **childArray = nsnull; ++ nsresult rv = userPrefs->GetChildList("config.lockdown.", ++ &childCount, &childArray); + if (NS_FAILED(rv)) + return rv; ++ for (PRUint32 i = 0; i < childCount; ++i) { ++ PRInt32 type; ++ rv = defaultPrefs->GetPrefType(childArray[i], &type); ++ if (NS_FAILED(rv)) ++ return rv; ++ NS_ASSERTION(type == nsIPrefBranch2::PREF_BOOL, ++ "All config.lockdown.* prefs should be boolean"); ++ if (type == nsIPrefBranch2::PREF_BOOL) { ++ rv = defaultPrefs->SetBoolPref(childArray[i], PR_FALSE); ++ if (NS_FAILED(rv)) ++ return rv; ++ } ++ } ++ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); ++ return NS_OK; ++} + +- // unlock, if it is locked +- prefBranch->UnlockPref(aPrefName); ++nsresult ++nsSystemPref::LoadSystemPrefs() ++{ ++ SYSPREF_LOG(("\n====Now Use system prefs==\n")); ++ NS_ASSERTION(!mSysPrefService, ++ "Shouldn't have the pref service here"); ++ nsresult rv; ++ mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv); ++ if (NS_FAILED(rv) || !mSysPrefService) { ++ FixupLockdownPrefs(); ++ SYSPREF_LOG(("...No System Pref Service\n")); ++ return NS_OK; ++ } + +- switch (prefType) { +- case nsIPrefBranch::PREF_STRING: +- prefBranch->SetCharPref(aPrefName, +- aPrefValue->stringVal); +- SYSPREF_LOG(("Mozilla value is %s\n", aPrefValue->stringVal)); ++ // Cache the pref-branch while we load up the system prefs. ++ NS_ASSERTION(!mCachedUserPrefBranch, ++ "Shouldn't have a cache here"); ++ nsCOMPtr userBranch = GetPrefUserBranch(); ++ nsCOMPtr defaultBranch = GetPrefDefaultBranch(); ++ mCachedDefaultPrefBranch = defaultBranch; ++ mCachedUserPrefBranch = userBranch; ++ rv = mSysPrefService->LoadSystemPreferences(this); ++ mCachedDefaultPrefBranch = nsnull; ++ mCachedUserPrefBranch = nsnull; ++ ++ if (NS_FAILED(rv)) { ++ // Restore all modified preferences to their original values ++ mSavedPrefs.EnumerateRead(RestorePref, this); ++ mSavedPrefs.Clear(); ++ mSysPrefService = nsnull; ++ } ++ ++ return rv; ++} + +- PL_strfree(aPrefValue->stringVal); +- aPrefValue->stringVal = nsnull; ++nsresult ++nsSystemPref::RestoreMozillaPrefs() ++{ ++ SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n")); + +- break; +- case nsIPrefBranch::PREF_INT: +- prefBranch->SetIntPref(aPrefName, aPrefValue->intVal); +- SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal)); ++ NS_ASSERTION(mSysPrefService, ++ "Should have the pref service here"); ++ if (!mSysPrefService) ++ return NS_ERROR_FAILURE; + +- break; +- case nsIPrefBranch::PREF_BOOL: +- prefBranch->SetBoolPref(aPrefName, aPrefValue->boolVal); +- SYSPREF_LOG(("Mozilla value is %s\n", +- aPrefValue->boolVal ? "TRUE" : "FALSE")); ++ nsCOMPtr userBranch = GetPrefUserBranch(); ++ nsCOMPtr defaultBranch = GetPrefDefaultBranch(); ++ mCachedDefaultPrefBranch = defaultBranch; ++ mCachedUserPrefBranch = userBranch; ++ ++ mSysPrefService->NotifyUnloadSystemPreferences(); ++ // Restore all modified preferences to their original values ++ mSavedPrefs.EnumerateRead(RestorePref, this); ++ mSavedPrefs.Clear(); ++ ++ mCachedDefaultPrefBranch = nsnull; ++ mCachedUserPrefBranch = nsnull; ++ ++ mSysPrefService = nsnull; + +- break; +- default: +- SYSPREF_LOG(("Fail to Restore Mozilla value for it\n")); +- return NS_ERROR_FAILURE; +- } ++ FixupLockdownPrefs(); + +- // restore its old lock status +- if (aLocked) +- prefBranch->LockPref(aPrefName); + return NS_OK; + } +diff -Naur mozilla.orig/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp mozilla/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp +--- mozilla.orig/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp 2003-04-14 19:28:25.000000000 -0700 ++++ mozilla/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp 2008-04-01 16:50:49.000000000 -0700 +@@ -42,10 +42,10 @@ + #include "nsICategoryManager.h" + #include "nsIGenericFactory.h" + #include "nsSystemPref.h" +-#include "nsSystemPrefService.h" ++#include "nsIServiceManager.h" ++#include "nsIAppStartupNotifier.h" + + NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPref, Init) +-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init) + + // Registering nsSystemPref module as part of the app-startup category to get + // it instantiated. +@@ -96,11 +96,6 @@ + RegisterSystemPref, + UnRegisterSystemPref, + }, +- { NS_SYSTEMPREF_SERVICE_CLASSNAME, +- NS_SYSTEMPREF_SERVICE_CID, +- NS_SYSTEMPREF_SERVICE_CONTRACTID, +- nsSystemPrefServiceConstructor, +- }, + }; + + NS_IMPL_NSGETMODULE(nsSystemPrefModule, components) +diff -Naur mozilla.orig/extensions/pref/system-pref/src/nsSystemPref.h mozilla/extensions/pref/system-pref/src/nsSystemPref.h +--- mozilla.orig/extensions/pref/system-pref/src/nsSystemPref.h 2005-02-23 08:15:37.000000000 -0800 ++++ mozilla/extensions/pref/system-pref/src/nsSystemPref.h 2008-04-01 16:50:49.000000000 -0700 +@@ -23,7 +23,7 @@ + * + * Original Author: Bolian Yin (bolian.yin@sun.com) + * +- * Contributor(s): ++ * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -45,16 +45,14 @@ + #include "nsCOMPtr.h" + #include "nsXPCOM.h" + #include "nsCRT.h" +-#include "nsIAppStartupNotifier.h" +-#include "nsICategoryManager.h" +-#include "nsIServiceManager.h" + #include "nsWeakReference.h" +-#include "nsIPrefService.h" +-#include "nsIPrefBranch2.h" ++#include "nsClassHashtable.h" ++#include "nsHashKeys.h" ++#include "nsMemory.h" + +-#include ++#include "nsISystemPrefService.h" ++#include "nsIObserver.h" + +-union MozPrefValue; + struct SysPrefItem; + + ////////////////////////////////////////////////////////////////////////// +@@ -62,18 +60,34 @@ + // nsSystemPref, as an extension of mozilla pref service, reads some mozilla + // prefs from host system when the feature is enabled ("config.system-pref"). + // +-// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When notified, +-// nsSystemPref will start the nsSystemPrefService (platform specific) to +-// read all the interested prefs (listed in sSysPrefList table) from system +-// and lock these prefs from user's modification. +-// +-// This feature will make mozilla integrated better into host platforms. If +-// users want to change the prefs read from system, the system provided pref +-// editor (i.e. gconf-editor in gnome) should be used. ++// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When ++// notified, nsSystemPref will start the nsSystemPrefService (platform ++// specific) and tell it to override Mozilla prefs with its own ++// settings. ++// ++// When overriding a Mozilla preference the prefservice can request the ++// pref be locked or unlocked. If the pref is locked then we set the default ++// value and lock it in Mozilla so the user value is ignored and the user cannot ++// change the value. If the pref is unlocked then we set the user value ++// and unlock it in Mozilla so the user can change it. If the user changes it, ++// then the prefservice is notified so it can copy the value back to its ++// underlying store. ++// ++// We detect changes to Mozilla prefs by observing pref changes in the ++// user branch. ++// ++// For testing purposes, if the user toggles on ++// config.use_system_prefs then we save the current preferences before ++// overriding them from gconf, and if the user toggles off ++// config.use_system_prefs *in the same session* then we restore the ++// preferences. If the user exits without turning off use_system_prefs ++// then the saved values are lost and the new values are permanent. ++// + ////////////////////////////////////////////////////////////////////////// + + class nsSystemPref : public nsIObserver, +- public nsSupportsWeakReference ++ public nsSupportsWeakReference, ++ public nsISystemPref + { + public: + NS_DECL_ISUPPORTS +@@ -83,23 +97,39 @@ + virtual ~nsSystemPref(); + nsresult Init(void); + ++ // nsISystemPref ++ virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName, ++ PRBool aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE); ++ virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName, ++ PRInt32 aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE); ++ virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName, ++ const char* aValue, PRBool aLocked, ++ PRBool aPresent = PR_TRUE); ++ virtual nsresult StopOverridingMozillaPref(const char* aPrefName); ++ virtual already_AddRefed GetPrefUserBranch(); ++ virtual already_AddRefed GetPrefDefaultBranch(); ++ + private: +- // funcs used to load system prefs and save mozilla default prefs +- nsresult UseSystemPrefs(); +- nsresult ReadSystemPref(const char *aPrefName); +- nsresult SaveMozDefaultPref(const char *aPrefName, +- MozPrefValue *aPrefVal, +- PRBool *aLocked); +- +- // funcs used to load mozilla default prefs +- nsresult UseMozillaPrefs(); +- nsresult RestoreMozDefaultPref(const char *aPrefName, +- MozPrefValue *aPrefVal, +- PRBool aLocked); +- +- nsCOMPtr mSysPrefService; +- PRBool mEnabled; // system pref is enabled or not +- SysPrefItem *mSysPrefs; ++ // If we don't load the system prefs for any reason, then ++ // set all config.lockdown.* preferences to PR_FALSE so that ++ // residual lockdown settings are removed. ++ nsresult FixupLockdownPrefs(); ++ ++ nsresult LoadSystemPrefs(); ++ ++ nsresult RestoreMozillaPrefs(); ++ ++ nsresult OverridePref(const char* aPrefName, PRInt32 aType, ++ void* aValue, PRBool aLock, PRBool aPresent); ++ ++ nsCOMPtr mSysPrefService; ++ nsClassHashtable mSavedPrefs; ++ // weak pointers to cached prefbranches ++ nsIPrefBranch2* mCachedUserPrefBranch; ++ nsIPrefBranch* mCachedDefaultPrefBranch; ++ PRPackedBool mIgnorePrefSetting; + }; + + #define NS_SYSTEMPREF_CID \ +diff -Naur mozilla.orig/toolkit/library/libxul-config.mk mozilla/toolkit/library/libxul-config.mk +--- mozilla.orig/toolkit/library/libxul-config.mk 2008-02-25 17:28:51.000000000 -0800 ++++ mozilla/toolkit/library/libxul-config.mk 2008-04-10 11:38:00.000000000 -0700 +@@ -266,6 +266,7 @@ + ifdef MOZ_ENABLE_GTK2 + COMPONENT_LIBS += widget_gtk2 + ifdef MOZ_PREF_EXTENSIONS ++COMPONENT_LIBS += syspref-gconf + COMPONENT_LIBS += system-pref + endif + endif +diff -Naur mozilla.orig/toolkit/library/libxul-rules.mk mozilla/toolkit/library/libxul-rules.mk +--- mozilla.orig/toolkit/library/libxul-rules.mk 2008-03-08 01:43:03.000000000 -0800 ++++ mozilla/toolkit/library/libxul-rules.mk 2008-04-10 11:38:07.000000000 -0700 +@@ -89,6 +89,12 @@ + EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) + endif + ++ifdef MOZ_ENABLE_GTK2 ++ifdef MOZ_PREF_EXTENSIONS ++EXTRA_DSO_LDOPTS += $(MOZ_GCONF_LIBS) ++endif ++endif ++ + EXTRA_DSO_LDOPTS += $(MOZ_CAIRO_LIBS) + + export:: dlldeps.cpp +diff -Naur mozilla.orig/toolkit/library/nsStaticXULComponents.cpp mozilla/toolkit/library/nsStaticXULComponents.cpp +--- mozilla.orig/toolkit/library/nsStaticXULComponents.cpp 2008-02-25 17:28:51.000000000 -0800 ++++ mozilla/toolkit/library/nsStaticXULComponents.cpp 2008-04-10 11:38:14.000000000 -0700 +@@ -136,7 +136,8 @@ + #ifdef MOZ_ENABLE_GTK2 + #ifdef MOZ_PREF_EXTENSIONS + #define SYSTEMPREF_MODULES MODULE(nsSystemPrefModule) \ +- MODULE(nsAutoConfigModule) ++ MODULE(nsAutoConfigModule) \ ++ MODULE(nsSystemPrefServiceModule) + #else + #define SYSTEMPREF_MODULES + #endif --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_gre_extension_plugin_support.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_gre_extension_plugin_support.patch @@ -0,0 +1,417 @@ +--- + toolkit/mozapps/extensions/src/nsExtensionManager.js.in | 27 ++++++--- + toolkit/xre/nsXREDirProvider.cpp | 5 + + xpcom/io/nsAppDirectoryServiceDefs.h | 1 + xpcom/io/nsAppFileLocationProvider.cpp | 47 ++++++++++++++-- + xpcom/io/nsAppFileLocationProvider.h | 2 + 5 files changed, 71 insertions(+), 11 deletions(-) + +Index: mozilla/toolkit/mozapps/extensions/src/nsExtensionManager.js.in +=================================================================== +--- mozilla.orig/toolkit/mozapps/extensions/src/nsExtensionManager.js.in ++++ mozilla/toolkit/mozapps/extensions/src/nsExtensionManager.js.in +@@ -92,16 +92,17 @@ + const UNKNOWN_XPCOM_ABI = "unknownABI"; + + const FILE_DEFAULT_THEME_JAR = "classic.jar"; + const TOOLKIT_ID = "toolkit@mozilla.org" + + const KEY_PROFILEDIR = "ProfD"; + const KEY_PROFILEDS = "ProfDS"; + const KEY_APPDIR = "XCurProcD"; ++const KEY_GREDIR = "GreD"; + const KEY_TEMPDIR = "TmpD"; + + const EM_ACTION_REQUESTED_TOPIC = "em-action-requested"; + const EM_ITEM_INSTALLED = "item-installed"; + const EM_ITEM_UPGRADED = "item-upgraded"; + const EM_ITEM_UNINSTALLED = "item-uninstalled"; + const EM_ITEM_ENABLED = "item-enabled"; + const EM_ITEM_DISABLED = "item-disabled"; +@@ -111,16 +112,17 @@ + const OP_NEEDS_INSTALL = "needs-install"; + const OP_NEEDS_UPGRADE = "needs-upgrade"; + const OP_NEEDS_UNINSTALL = "needs-uninstall"; + const OP_NEEDS_ENABLE = "needs-enable"; + const OP_NEEDS_DISABLE = "needs-disable"; + + const KEY_APP_PROFILE = "app-profile"; + const KEY_APP_GLOBAL = "app-global"; ++const KEY_GRE_GLOBAL = "gre-global"; + const KEY_APP_SYSTEM_LOCAL = "app-system-local"; + const KEY_APP_SYSTEM_SHARE = "app-system-share"; + const KEY_APP_SYSTEM_USER = "app-system-user"; + + const CATEGORY_INSTALL_LOCATIONS = "extension-install-locations"; + const CATEGORY_UPDATE_PARAMS = "extension-update-params"; + + const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; +@@ -2011,16 +2013,17 @@ + " ... rolling back file moves and aborting installation."); + rollbackMove(); + cleanUpTrash(itemLocationTrash); + throw e; + } + } + } + else if (installLocation.name == KEY_APP_PROFILE || ++ installLocation.name == KEY_GRE_GLOBAL || + installLocation.name == KEY_APP_GLOBAL || + installLocation.name == KEY_APP_SYSTEM_USER) { + // Check for a pointer file and move it aside if it exists + var pointerFile = installLocation.location.clone(); + pointerFile.append(itemID); + if (pointerFile.exists() && !pointerFile.isDirectory()) { + var trashFileName = itemID + "-trash"; + var itemLocationTrash = installLocation.location.clone(); +@@ -2417,17 +2420,25 @@ + + gConsole = Cc["@mozilla.org/consoleservice;1"]. + getService(Ci.nsIConsoleService); + + gRDF = Cc["@mozilla.org/rdf/rdf-service;1"]. + getService(Ci.nsIRDFService); + gInstallManifestRoot = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT); + +- // Register Global Install Location ++ // Register Global GRE Install Location ++ var greGlobalExtensions = getDirNoCreate(KEY_GREDIR, [DIR_EXTENSIONS]); ++ var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL; ++ var greGlobalLocation = new DirectoryInstallLocation(KEY_GRE_GLOBAL, ++ greGlobalExtensions, true, ++ priority); ++ InstallLocations.put(greGlobalLocation); ++ ++ // Register Global Application Install Location + var appGlobalExtensions = getDirNoCreate(KEY_APPDIR, [DIR_EXTENSIONS]); + var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL; + var globalLocation = new DirectoryInstallLocation(KEY_APP_GLOBAL, + appGlobalExtensions, true, + priority, false); + InstallLocations.put(globalLocation); + + // Register App-Profile Install Location +@@ -3613,17 +3624,17 @@ + badItems.push(id); + continue; + } + + if (ds.getItemProperty(id, "appManaged") == "true") { + // Force an update of the metadata for appManaged extensions since the + // last modified time is not updated for directories on FAT / FAT32 + // filesystems when software update applies a new version of the app. +- if (location.name == KEY_APP_GLOBAL) { ++ if (location.name == KEY_APP_GLOBAL || location.name == KEY_GRE_GLOBAL) { + var installRDF = location.getItemFile(id, FILE_INSTALL_MANIFEST); + if (installRDF.exists()) { + var metadataDS = getInstallManifest(installRDF); + ds.addItemMetadata(id, metadataDS, location); + ds.updateProperty(id, "compatible"); + } + } + } +@@ -3771,17 +3782,17 @@ + + // return early to avoid migrating data twice if we already have a + // toolkit 1.8 extension datasource. + if (dsExists) + return; + + // Prepare themes for installation + // Only enumerate directories in the app-profile and app-global locations. +- var locations = [KEY_APP_PROFILE, KEY_APP_GLOBAL]; ++ var locations = [KEY_APP_PROFILE, KEY_APP_GLOBAL, KEY_GRE_GLOBAL]; + for (var i = 0; i < locations.length; ++i) { + var location = InstallLocations.get(locations[i]); + if (!location.canAccess) + continue; + + var entries = location.itemLocations; + var entry; + while ((entry = entries.nextFile)) { +@@ -3837,17 +3848,18 @@ + // items since the datasource hasn't been created yet. + var itemsToCheck = []; + if (this._checkForFileChanges()) { + // Create a list of all items that are to be installed so we can migrate + // these items's settings to the new datasource. + var items = PendingOperations.getOperations(OP_NEEDS_INSTALL); + for (i = items.length - 1; i >= 0; --i) { + if (items[i].locationKey == KEY_APP_PROFILE || +- items[i].locationKey == KEY_APP_GLOBAL) ++ items[i].locationKey == KEY_APP_GLOBAL || ++ items[i].locationKey == KEY_GRE_GLOBAL) + itemsToCheck.push(items[i].id); + } + this._finishOperations(); + } + + // If there are no items to migrate settings for return early. + if (itemsToCheck.length == 0) + return; +@@ -4933,16 +4945,17 @@ + StartupCache.put(installLocation, id, OP_NONE, true); + var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type")) + this._updateManifests(restartRequired); + return; + } + } + } + else if (installLocation.name == KEY_APP_PROFILE || ++ installLocation.name == KEY_GRE_GLOBAL || + installLocation.name == KEY_APP_GLOBAL || + installLocation.name == KEY_APP_SYSTEM_USER) { + // Check for a pointer file and remove it if it exists + var pointerFile = installLocation.location.clone(); + pointerFile.append(id); + if (pointerFile.exists() && !pointerFile.isDirectory()) + pointerFile.remove(false); + } +@@ -7094,17 +7107,17 @@ + // with and maintained by this application AND it is installed in the + // global install location (i.e. the place installed by the app installer) + // it is and can be managed by the update file - it's not an item that has + // been manually installed by the user into their profile dir, and as such + // it is always compatible with the next release of the application since + // we will continue to support it. + var locationKey = this.getItemProperty(id, "installLocation"); + var appManaged = this.getItemProperty(id, "appManaged") == "true"; +- if (appManaged && locationKey == KEY_APP_GLOBAL) ++ if (appManaged && (locationKey == KEY_APP_GLOBAL || locationKey == KEY_GRE_GLOBAL)) + continue; + + if (type != -1 && (type & desiredType) && + !this.isCompatible(this, item, appVersion, platformVersion)) + items.push(this.getItemForID(id)); + } + return items; + }, +@@ -7660,17 +7673,17 @@ + // Assert properties with single values + var singleProps = ["version", "updateURL", "updateService", "optionsURL", + "aboutURL", "iconURL", "internalName", "updateKey"]; + + // Items installed into restricted Install Locations can also be locked + // (can't be removed or disabled), and hidden (not shown in the UI) + if (installLocation.restricted) + singleProps = singleProps.concat(["locked", "hidden"]); +- if (installLocation.name == KEY_APP_GLOBAL) ++ if (installLocation.name == KEY_APP_GLOBAL || installLocation.name == KEY_GRE_GLOBAL) + singleProps = singleProps.concat(["appManaged"]); + for (var i = 0; i < singleProps.length; ++i) { + var property = EM_R(singleProps[i]); + var literal = installManifest.GetTarget(gInstallManifestRoot, property, true); + // If literal is null, _setProperty will remove any existing. + this._setProperty(this._inner, targetRes, property, literal); + } + +@@ -8326,17 +8339,17 @@ + + /** + * Get the em:appManaged property. This prevents extensions from hiding + * extensions installed into locations other than the app-global location. + */ + _rdfGet_appManaged: function(item, property) { + var id = stripPrefix(item.Value, PREFIX_ITEM_URI); + var locationKey = this.getItemProperty(id, "installLocation"); +- if (locationKey != KEY_APP_GLOBAL) ++ if (locationKey != KEY_APP_GLOBAL && locationKey != KEY_GRE_GLOBAL) + return EM_L("false"); + return null; + }, + + /** + * Get the em:hidden property. This prevents extensions from hiding + * extensions installed into locations other than restricted locations. + */ +Index: mozilla/xpcom/io/nsAppDirectoryServiceDefs.h +=================================================================== +--- mozilla.orig/xpcom/io/nsAppDirectoryServiceDefs.h ++++ mozilla/xpcom/io/nsAppDirectoryServiceDefs.h +@@ -71,16 +71,17 @@ + + #define NS_APP_USER_PROFILES_ROOT_DIR "DefProfRt" // The dir where user profile dirs live. + #define NS_APP_USER_PROFILES_LOCAL_ROOT_DIR "DefProfLRt" // The dir where user profile temp dirs live. + + #define NS_APP_RES_DIR "ARes" + #define NS_APP_CHROME_DIR "AChrom" + #define NS_APP_PLUGINS_DIR "APlugns" // Deprecated - use NS_APP_PLUGINS_DIR_LIST + #define NS_APP_SEARCH_DIR "SrchPlugns" ++#define NS_GRE_PLUGINS_DIR "GrePlugns" // Usually you want NS_APP_PLUGINS_DIR_LIST + + #define NS_APP_CHROME_DIR_LIST "AChromDL" + #define NS_APP_PLUGINS_DIR_LIST "APluginsDL" + #define NS_APP_SEARCH_DIR_LIST "SrchPluginsDL" + + // -------------------------------------------------------------------------------------- + // Files and directories which exist on a per-profile basis + // These locations are typically provided by the profile mgr +Index: mozilla/xpcom/io/nsAppFileLocationProvider.cpp +=================================================================== +--- mozilla.orig/xpcom/io/nsAppFileLocationProvider.cpp ++++ mozilla/xpcom/io/nsAppFileLocationProvider.cpp +@@ -194,16 +194,22 @@ + rv = localFile->AppendRelativeNativePath(RES_DIR_NAME); + } + else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0) + { + rv = CloneMozBinDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME); + } ++ else if (nsCRT::strcmp(prop, NS_GRE_PLUGINS_DIR) == 0) ++ { ++ rv = CloneMozGreDirectory(getter_AddRefs(localFile)); ++ if (NS_SUCCEEDED(rv)) ++ rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); ++ } + else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0) + { + rv = CloneMozBinDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); + } + #ifdef XP_MACOSX + else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0) +@@ -276,16 +282,51 @@ + + if (localFile && NS_SUCCEEDED(rv)) + return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval); + + return rv; + } + + ++NS_METHOD nsAppFileLocationProvider::CloneMozGreDirectory(nsILocalFile **aLocalFile) ++{ ++ NS_ENSURE_ARG_POINTER(aLocalFile); ++ nsresult rv; ++ ++ if (!mMozGreDirectory) ++ { ++ // Get the mozilla bin directory ++ // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR ++ // This will be set if a directory was passed to NS_InitXPCOM ++ // 2. If that doesn't work, set it to be the current process directory ++ nsCOMPtr ++ directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); ++ if (NS_FAILED(rv)) ++ return rv; ++ ++ rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozGreDirectory)); ++ if (NS_FAILED(rv)) ++ return rv; ++ } ++ ++ nsCOMPtr aFile; ++ rv = mMozGreDirectory->Clone(getter_AddRefs(aFile)); ++ if (NS_FAILED(rv)) ++ return rv; ++ ++ nsCOMPtr lfile = do_QueryInterface (aFile); ++ if (!lfile) ++ return NS_ERROR_FAILURE; ++ ++ NS_IF_ADDREF(*aLocalFile = lfile); ++ return NS_OK; ++} ++ ++ + NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile) + { + NS_ENSURE_ARG_POINTER(aLocalFile); + nsresult rv; + + if (!mMozBinDirectory) + { + // Get the mozilla bin directory +@@ -578,30 +619,30 @@ + { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nsnull; + nsresult rv = NS_ERROR_FAILURE; + + if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST)) + { + #ifdef XP_MACOSX +- static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull }; +- static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull }; ++ static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull }; ++ static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull }; + static const char** keys; + + if (!keys) { + OSErr err; + long response; + err = ::Gestalt(gestaltSystemVersion, &response); + keys = (!err && response >= 0x00001000) ? osXKeys : os9Keys; + } + + *_retval = new nsAppDirectoryEnumerator(this, keys); + #else +- static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nsnull }; ++ static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_GRE_PLUGINS_DIR, nsnull }; + if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) { + static const char nullstr = 0; + keys[0] = &nullstr; + } + *_retval = new nsPathsDirectoryEnumerator(this, keys); + #endif + NS_IF_ADDREF(*_retval); + rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +Index: mozilla/xpcom/io/nsAppFileLocationProvider.h +=================================================================== +--- mozilla.orig/xpcom/io/nsAppFileLocationProvider.h ++++ mozilla/xpcom/io/nsAppFileLocationProvider.h +@@ -55,22 +55,24 @@ + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + NS_DECL_NSIDIRECTORYSERVICEPROVIDER2 + + private: + ~nsAppFileLocationProvider() {} + + protected: + NS_METHOD CloneMozBinDirectory(nsILocalFile **aLocalFile); ++ NS_METHOD CloneMozGreDirectory(nsILocalFile **aLocalFile); + /** + * Get the product directory. This is a user-specific directory for storing + * application settings (e.g. the Application Data directory on windows + * systems). + * @param aLocal If true, should try to get a directory that is only stored + * locally (ie not transferred with roaming profiles) + */ + NS_METHOD GetProductDirectory(nsILocalFile **aLocalFile, + PRBool aLocal = PR_FALSE); + NS_METHOD GetDefaultUserProfileRoot(nsILocalFile **aLocalFile, + PRBool aLocal = PR_FALSE); + + nsCOMPtr mMozBinDirectory; ++ nsCOMPtr mMozGreDirectory; + }; +Index: mozilla/toolkit/xre/nsXREDirProvider.cpp +=================================================================== +--- mozilla.orig/toolkit/xre/nsXREDirProvider.cpp ++++ mozilla/toolkit/xre/nsXREDirProvider.cpp +@@ -747,18 +747,21 @@ + + rv = NS_NewArrayEnumerator(aResult, directories); + } + else if (!strcmp(aProperty, NS_APP_PLUGINS_DIR_LIST)) { + static const char *const kAppendPlugins[] = { "plugins", nsnull }; + nsCOMArray directories; + + // The root dirserviceprovider does quite a bit for us: we're mainly +- // interested in xulapp and extension-provided plugins. ++ // interested in gre, xulapp, and extension-provided plugins. + LoadBundleDirectories(); ++ LoadAppDirIntoArray(mGREDir, ++ kAppendPlugins, ++ directories); + LoadDirsIntoArray(mAppBundleDirectories, + kAppendPlugins, + directories); + LoadDirsIntoArray(mExtensionDirectories, + kAppendPlugins, + directories); + + rv = NS_NewArrayEnumerator(aResult, directories); --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/protect_tests_by_ifdefs.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/protect_tests_by_ifdefs.patch @@ -0,0 +1,94 @@ +--- + content/xul/content/Makefile.in | 6 +++++- + dom/Makefile.in | 6 +++++- + toolkit/components/commandlines/Makefile.in | 5 ++++- + toolkit/components/downloads/Makefile.in | 6 +++++- + 4 files changed, 19 insertions(+), 4 deletions(-) + +Index: mozilla/content/xul/content/Makefile.in +=================================================================== +--- mozilla.orig/content/xul/content/Makefile.in ++++ mozilla/content/xul/content/Makefile.in +@@ -38,12 +38,16 @@ + DEPTH = ../../.. + topsrcdir = @top_srcdir@ + srcdir = @srcdir@ + VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + + MODULE = xul +-DIRS = src test ++DIRS = src ++ ++ifdef ENABLE_TESTS ++DIRS += test ++endif + + include $(topsrcdir)/config/rules.mk + +Index: mozilla/toolkit/components/downloads/Makefile.in +=================================================================== +--- mozilla.orig/toolkit/components/downloads/Makefile.in ++++ mozilla/toolkit/components/downloads/Makefile.in +@@ -37,12 +37,16 @@ + + DEPTH = ../../.. + topsrcdir = @top_srcdir@ + srcdir = @srcdir@ + VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + +-DIRS = public src test ++DIRS = public src ++ ++ifdef ENABLE_TESTS ++DIRS += test ++endif + + include $(topsrcdir)/config/rules.mk + +Index: mozilla/toolkit/components/commandlines/Makefile.in +=================================================================== +--- mozilla.orig/toolkit/components/commandlines/Makefile.in ++++ mozilla/toolkit/components/commandlines/Makefile.in +@@ -40,12 +40,15 @@ + srcdir = @srcdir@ + VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + + DIRS = \ + public \ + src \ +- test \ + $(NULL) + ++ifdef ENABLE_TESTS ++DIRS += test ++endif ++ + include $(topsrcdir)/config/rules.mk +Index: mozilla/dom/Makefile.in +=================================================================== +--- mozilla.orig/dom/Makefile.in ++++ mozilla/dom/Makefile.in +@@ -38,12 +38,16 @@ + DEPTH = .. + topsrcdir = @top_srcdir@ + srcdir = @srcdir@ + VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + + MODULE = dom +-DIRS = public src locales tests ++DIRS = public src locales ++ ++ifdef ENABLE_TESTS ++DIRS += tests ++endif + + include $(topsrcdir)/config/rules.mk + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_autoconfig_in_gre.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_autoconfig_in_gre.patch @@ -0,0 +1,35 @@ +--- + extensions/pref/autoconfig/src/nsReadConfig.cpp | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +Index: mozilla/extensions/pref/autoconfig/src/nsReadConfig.cpp +=================================================================== +--- mozilla.orig/extensions/pref/autoconfig/src/nsReadConfig.cpp ++++ mozilla/extensions/pref/autoconfig/src/nsReadConfig.cpp +@@ -279,20 +279,25 @@ + getter_AddRefs(jsFile)); + if (NS_FAILED(rv)) + return rv; + + #ifdef XP_MAC + jsFile->AppendNative(NS_LITERAL_CSTRING("Essential Files")); + #endif + } else { +- rv = NS_GetSpecialDirectory(NS_APP_DEFAULTS_50_DIR, ++ rv = NS_GetSpecialDirectory(NS_GRE_DIR, + getter_AddRefs(jsFile)); + if (NS_FAILED(rv)) + return rv; ++ ++ rv = jsFile->AppendNative(NS_LITERAL_CSTRING("defaults")); ++ if (NS_FAILED(rv)) ++ return rv; ++ + rv = jsFile->AppendNative(NS_LITERAL_CSTRING("autoconfig")); + if (NS_FAILED(rv)) + return rv; + } + rv = jsFile->AppendNative(nsDependentCString(aFileName)); + if (NS_FAILED(rv)) + return rv; + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/jemalloc_static.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/jemalloc_static.patch @@ -0,0 +1,31 @@ +--- + memory/jemalloc/Makefile.in | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: mozilla/memory/jemalloc/Makefile.in +=================================================================== +--- mozilla.orig/memory/jemalloc/Makefile.in ++++ mozilla/memory/jemalloc/Makefile.in +@@ -88,17 +88,22 @@ + MODULE_OPTIMIZE_FLAGS = -xO5 + endif + endif + + LIBRARY_NAME = jemalloc + + # Build jemalloc as a shared lib. This is mandatory for Darwin, since a library + # init function is used on that platform. ++ifeq ($(OS_ARCH),Darwin) + FORCE_SHARED_LIB= 1 ++else ++DIST_INSTALL = 1 ++FORCE_STATIC_LIB= 1 ++endif + + CSRCS = \ + jemalloc.c \ + $(NULL) + + #XXX: PGO on Linux causes problems here + # See bug 419470 + NO_PROFILE_GUIDED_OPTIMIZE = 1 --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/rename_venkman_addon.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/rename_venkman_addon.patch @@ -0,0 +1,120 @@ +--- + extensions/venkman/Makefile.in | 2 +- + extensions/venkman/locales/Makefile.in | 2 +- + extensions/venkman/locales/generic/install.rdf | 2 +- + extensions/venkman/resources/Makefile.in | 2 +- + extensions/venkman/xpi/resources/install.rdf | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +Index: mozilla/extensions/venkman/Makefile.in +=================================================================== +--- mozilla.orig/extensions/venkman/Makefile.in ++++ mozilla/extensions/venkman/Makefile.in +@@ -48,17 +48,17 @@ + + EXTRA_COMPONENTS = js/venkman-service.js + DIST_FILES = xpi/resources/install.rdf + + VENKMAN_VERSION=$(shell cat $(srcdir)/version.txt) + + XPI_NAME = venkman + NO_JAR_AUTO_REG = 1 +-INSTALL_EXTENSION_ID = {f13b157f-b174-47e7-a34d-4815ddfdfeb8} ++INSTALL_EXTENSION_ID = venkman@mozilla.org + XPI_PKGNAME = venkman-$(VENKMAN_VERSION) + + # include config.mk before using the AB_CD var it sets in an if statement + include $(topsrcdir)/config/config.mk + + # always build en-US locale, add build locale if supported + BUILD_LOCALES = en-US + ifneq (,$(filter $(AB_CD),$(shell cat $(srcdir)/locales/all-locales))) +Index: mozilla/extensions/venkman/locales/Makefile.in +=================================================================== +--- mozilla.orig/extensions/venkman/locales/Makefile.in ++++ mozilla/extensions/venkman/locales/Makefile.in +@@ -43,17 +43,17 @@ + relativesrcdir = extensions/venkman/locales + + VENKMAN_VERSION=$(shell cat $(srcdir)/../version.txt) + VENKMAN_BASE_VERSION=$(shell echo "$(VENKMAN_VERSION)" | sed "s|\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\).*|\1|") + + XPI_NAME = venkman + USE_EXTENSION_MANIFEST = 1 + NO_JAR_AUTO_REG = 1 +-INSTALL_EXTENSION_ID = {f13b157f-b174-47e7-a34d-4815ddfdfeb8} ++INSTALL_EXTENSION_ID = venkman@mozilla.org + XPI_PKGNAME = venkman-$(VENKMAN_VERSION) + + # include config.mk before we override the AB_CD var it sets + include $(topsrcdir)/config/config.mk + + # if the wanted language is not in all-locales, fall back to en-US + ifeq (,$(filter $(AB_CD),$(shell cat $(srcdir)/all-locales))) + override AB_CD = en-US +Index: mozilla/extensions/venkman/locales/generic/install.rdf +=================================================================== +--- mozilla.orig/extensions/venkman/locales/generic/install.rdf ++++ mozilla/extensions/venkman/locales/generic/install.rdf +@@ -10,17 +10,17 @@ + em:homepageURL="@MOZ_LANGPACK_HOMEPAGE@"> + #ifdef MOZ_LANGPACK_CONTRIBUTORS + @MOZ_LANGPACK_CONTRIBUTORS@ + #endif + + + + +- {f13b157f-b174-47e7-a34d-4815ddfdfeb8} ++ venkman@mozilla.org + @VENKMAN_BASE_VERSION@ + @VENKMAN_BASE_VERSION@.* + + + + + + +Index: mozilla/extensions/venkman/resources/Makefile.in +=================================================================== +--- mozilla.orig/extensions/venkman/resources/Makefile.in ++++ mozilla/extensions/venkman/resources/Makefile.in +@@ -43,15 +43,15 @@ + + include $(DEPTH)/config/autoconf.mk + + VENKMAN_VERSION=$(shell cat $(srcdir)/../version.txt) + + XPI_NAME = venkman + USE_EXTENSION_MANIFEST = 1 + NO_JAR_AUTO_REG = 1 +-INSTALL_EXTENSION_ID = {f13b157f-b174-47e7-a34d-4815ddfdfeb8} ++INSTALL_EXTENSION_ID = venkman@mozilla.org + XPI_PKGNAME = venkman-$(VENKMAN_VERSION) + + DEFINES += -DVENKMAN_VERSION=$(VENKMAN_VERSION) + + include $(topsrcdir)/config/rules.mk + +Index: mozilla/extensions/venkman/xpi/resources/install.rdf +=================================================================== +--- mozilla.orig/extensions/venkman/xpi/resources/install.rdf ++++ mozilla/extensions/venkman/xpi/resources/install.rdf +@@ -1,16 +1,16 @@ + + + #filter substitution + + + + +- {f13b157f-b174-47e7-a34d-4815ddfdfeb8} ++ venkman@mozilla.org + @VENKMAN_VERSION@ + + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 0.9 + 3.0 --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/patches/bzXXX_no_zlib_export_if_native.patch +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/patches/bzXXX_no_zlib_export_if_native.patch @@ -0,0 +1,27 @@ +Index: modules/zlib/standalone/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/modules/zlib/standalone/Makefile.in,v +retrieving revision 1.20 +diff -u -p -8 -r1.20 Makefile.in +--- mozilla/modules/zlib/standalone/Makefile.in 31 Dec 2005 16:02:07 -0000 1.20 ++++ mozilla/modules/zlib/standalone/Makefile.in 1 Jan 2008 23:27:42 -0000 +@@ -43,17 +43,19 @@ VPATH = @srcdir@ + + include $(DEPTH)/config/autoconf.mk + include $(srcdir)/../src/objs.mk + + MODULE = zlib + LIBRARY_NAME = mozz_s + + CSRCS = $(MODULES_ZLIB_SRC_LCSRCS) ++ifndef MOZ_NATIVE_ZLIB + EXPORTS = $(MODULES_ZLIB_SRC_EXPORTS) ++endif + + FORCE_STATIC_LIB = 1 + SRCS_IN_OBJDIR = 1 + + ifeq ($(OS_ARCH),WINNT) + USE_STATIC_LIBS=1 + endif + --- xulrunner-1.9-1.9.0.9+nobinonly.orig/debian/translation-support/install.rdf.in +++ xulrunner-1.9-1.9.0.9+nobinonly/debian/translation-support/install.rdf.in @@ -0,0 +1,24 @@ + + + + + + + + + + toolkit@mozilla.org + @EM_TOOLKIT_MIN_VERSION@ + @EM_TOOLKIT_MAX_VERSION@ + + + +
target