[Unison-hackers] [unison-svn] r326 - in trunk/src: . ubase
vouillon@seas.upenn.edu
vouillon at seas.upenn.edu
Mon May 4 14:48:29 EDT 2009
Author: vouillon
Date: 2009-05-04 14:48:23 -0400 (Mon, 04 May 2009)
New Revision: 326
Added:
trunk/src/unicode.ml
trunk/src/unicode.mli
trunk/src/unicode_tables.ml
Modified:
trunk/src/.depend
trunk/src/Makefile.OCaml
trunk/src/RECENTNEWS
trunk/src/case.ml
trunk/src/case.mli
trunk/src/mkProjectInfo.ml
trunk/src/name.ml
trunk/src/name.mli
trunk/src/path.ml
trunk/src/pred.ml
trunk/src/ubase/depend
trunk/src/update.ml
Log:
* Updated list of bad Windows file names following the MSDN
documentation (in particular, files with trailing dots are now
rejected when synchronizing with a Windows machine)
* Experimental Unicode-aware case insensitive mode. It is activated
when the preference "unicode" is set to true and Unison is in
case-insensitive mode.
* Bumped version number to reflect the newly added preference
Modified: trunk/src/.depend
===================================================================
--- trunk/src/.depend 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/.depend 2009-05-04 18:48:23 UTC (rev 326)
@@ -1,37 +1,52 @@
abort.cmi: uutil.cmi
+case.cmi:
+checksum.cmi:
+clroot.cmi:
common.cmi: uutil.cmi props.cmi path.cmi osx.cmi os.cmi name.cmi fspath.cmi \
fileinfo.cmi
copy.cmi: uutil.cmi props.cmi path.cmi osx.cmi os.cmi lwt/lwt.cmi fspath.cmi \
common.cmi
+external.cmi:
fileinfo.cmi: props.cmi path.cmi osx.cmi fspath.cmi
files.cmi: uutil.cmi props.cmi path.cmi lwt/lwt_util.cmi lwt/lwt.cmi \
common.cmi
+fileutil.cmi:
fingerprint.cmi: uutil.cmi path.cmi fspath.cmi
fspath.cmi: path.cmi name.cmi
globals.cmi: ubase/prefs.cmi path.cmi lwt/lwt.cmi common.cmi
+lock.cmi:
+name.cmi:
os.cmi: props.cmi path.cmi name.cmi fspath.cmi fileinfo.cmi
osx.cmi: uutil.cmi ubase/prefs.cmi path.cmi fspath.cmi fingerprint.cmi
path.cmi: name.cmi
+pred.cmi:
props.cmi: uutil.cmi ubase/prefs.cmi path.cmi osx.cmi fspath.cmi
recon.cmi: path.cmi common.cmi
remote.cmi: ubase/prefs.cmi lwt/lwt.cmi fspath.cmi common.cmi clroot.cmi
sortri.cmi: common.cmi
stasher.cmi: ubase/prefs.cmi path.cmi os.cmi fspath.cmi
+strings.cmi:
+terminal.cmi:
+test.cmi:
transfer.cmi: uutil.cmi lwt/lwt.cmi
transport.cmi: uutil.cmi lwt/lwt.cmi common.cmi
+tree.cmi:
uicommon.cmi: uutil.cmi ubase/prefs.cmi path.cmi lwt/lwt.cmi common.cmi
+uigtk2.cmi: uicommon.cmi
uigtk.cmi: uicommon.cmi
-uigtk2.cmi: uicommon.cmi
+ui.cmi:
uitext.cmi: uicommon.cmi
+unicode.cmi:
update.cmi: tree.cmi props.cmi path.cmi osx.cmi os.cmi name.cmi lwt/lwt.cmi \
fspath.cmi fileinfo.cmi common.cmi
+uutil.cmi:
xferhint.cmi: ubase/prefs.cmi path.cmi os.cmi fspath.cmi
abort.cmo: uutil.cmi ubase/util.cmi ubase/trace.cmi ubase/safelist.cmi \
abort.cmi
abort.cmx: uutil.cmx ubase/util.cmx ubase/trace.cmx ubase/safelist.cmx \
abort.cmi
-case.cmo: ubase/prefs.cmi case.cmi
-case.cmx: ubase/prefs.cmx case.cmi
+case.cmo: ubase/util.cmi unicode.cmi ubase/rx.cmi ubase/prefs.cmi case.cmi
+case.cmx: ubase/util.cmx unicode.cmx ubase/rx.cmx ubase/prefs.cmx case.cmi
checksum.cmo: checksum.cmi
checksum.cmx: checksum.cmi
clroot.cmo: ubase/util.cmi ubase/rx.cmi ubase/prefs.cmi clroot.cmi
@@ -80,10 +95,10 @@
globals.cmx: ubase/util.cmx ubase/trace.cmx ubase/safelist.cmx remote.cmx \
ubase/prefs.cmx pred.cmx path.cmx os.cmx name.cmx lwt/lwt_util.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx common.cmx clroot.cmx globals.cmi
+linkgtk2.cmo: uigtk2.cmi main.cmo
+linkgtk2.cmx: uigtk2.cmx main.cmx
linkgtk.cmo: uigtk.cmi main.cmo
linkgtk.cmx: uigtk.cmx main.cmx
-linkgtk2.cmo: uigtk2.cmi main.cmo
-linkgtk2.cmx: uigtk2.cmx main.cmx
linktext.cmo: uitext.cmi main.cmo
linktext.cmx: uitext.cmx main.cmx
linktk.cmo: main.cmo
@@ -94,6 +109,8 @@
ubase/safelist.cmi remote.cmi ubase/prefs.cmi os.cmi fspath.cmi
main.cmx: uutil.cmx ubase/util.cmx uitext.cmx uicommon.cmx strings.cmx \
ubase/safelist.cmx remote.cmx ubase/prefs.cmx os.cmx fspath.cmx
+mkProjectInfo.cmo:
+mkProjectInfo.cmx:
name.cmo: ubase/util.cmi case.cmi name.cmi
name.cmx: ubase/util.cmx case.cmx name.cmi
os.cmo: uutil.cmi ubase/util.cmi ubase/safelist.cmi props.cmi ubase/prefs.cmi \
@@ -108,6 +125,8 @@
fileutil.cmi case.cmi path.cmi
path.cmx: ubase/util.cmx ubase/safelist.cmx ubase/rx.cmx pred.cmx name.cmx \
fileutil.cmx case.cmx path.cmi
+pixmaps.cmo:
+pixmaps.cmx:
pred.cmo: ubase/util.cmi ubase/safelist.cmi ubase/rx.cmi ubase/prefs.cmi \
case.cmi pred.cmi
pred.cmx: ubase/util.cmx ubase/safelist.cmx ubase/rx.cmx ubase/prefs.cmx \
@@ -178,26 +197,26 @@
props.cmx ubase/prefs.cmx path.cmx osx.cmx os.cmx name.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx files.cmx \
fileinfo.cmx common.cmx clroot.cmx case.cmx uicommon.cmi
-uigtk.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
+uigtk2.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
transport.cmi ubase/trace.cmi strings.cmi sortri.cmi ubase/safelist.cmi \
remote.cmi recon.cmi ubase/prefs.cmi pixmaps.cmo path.cmi os.cmi \
lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi \
- files.cmi common.cmi clroot.cmi uigtk.cmi
-uigtk.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
+ files.cmi common.cmi clroot.cmi uigtk2.cmi
+uigtk2.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
transport.cmx ubase/trace.cmx strings.cmx sortri.cmx ubase/safelist.cmx \
remote.cmx recon.cmx ubase/prefs.cmx pixmaps.cmx path.cmx os.cmx \
lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx \
- files.cmx common.cmx clroot.cmx uigtk.cmi
-uigtk2.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
+ files.cmx common.cmx clroot.cmx uigtk2.cmi
+uigtk.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
transport.cmi ubase/trace.cmi strings.cmi sortri.cmi ubase/safelist.cmi \
remote.cmi recon.cmi ubase/prefs.cmi pixmaps.cmo path.cmi os.cmi \
lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi fspath.cmi \
- files.cmi common.cmi clroot.cmi uigtk2.cmi
-uigtk2.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
+ files.cmi common.cmi clroot.cmi uigtk.cmi
+uigtk.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
transport.cmx ubase/trace.cmx strings.cmx sortri.cmx ubase/safelist.cmx \
remote.cmx recon.cmx ubase/prefs.cmx pixmaps.cmx path.cmx os.cmx \
lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx \
- files.cmx common.cmx clroot.cmx uigtk2.cmi
+ files.cmx common.cmx clroot.cmx uigtk.cmi
uimacbridge.cmo: xferhint.cmi uutil.cmi ubase/util.cmi update.cmi \
uicommon.cmi transport.cmi ubase/trace.cmi terminal.cmi stasher.cmi \
ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi path.cmi os.cmi \
@@ -226,18 +245,22 @@
ubase/trace.cmx ubase/safelist.cmx remote.cmx recon.cmx ubase/prefs.cmx \
path.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx \
common.cmx uitext.cmi
+unicode.cmo: unicode_tables.cmo unicode.cmi
+unicode.cmx: unicode_tables.cmx unicode.cmi
+unicode_tables.cmo:
+unicode_tables.cmx:
update.cmo: xferhint.cmi uutil.cmi ubase/util.cmi tree.cmi ubase/trace.cmi \
- stasher.cmi ubase/safelist.cmi ubase/rx.cmi remote.cmi props.cmi \
- ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi name.cmi ubase/myMap.cmi \
+ stasher.cmi ubase/safelist.cmi remote.cmi props.cmi ubase/prefs.cmi \
+ pred.cmi path.cmi osx.cmi os.cmi name.cmi ubase/myMap.cmi \
lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi globals.cmi fspath.cmi \
fingerprint.cmi fileinfo.cmi external.cmi common.cmi update.cmi
update.cmx: xferhint.cmx uutil.cmx ubase/util.cmx tree.cmx ubase/trace.cmx \
- stasher.cmx ubase/safelist.cmx ubase/rx.cmx remote.cmx props.cmx \
- ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx name.cmx ubase/myMap.cmx \
+ stasher.cmx ubase/safelist.cmx remote.cmx props.cmx ubase/prefs.cmx \
+ pred.cmx path.cmx osx.cmx os.cmx name.cmx ubase/myMap.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx globals.cmx fspath.cmx \
fingerprint.cmx fileinfo.cmx external.cmx common.cmx update.cmi
-uutil.cmo: ubase/util.cmi uutil.cmi
-uutil.cmx: ubase/util.cmx uutil.cmi
+uutil.cmo: ubase/util.cmi ubase/projectInfo.cmo uutil.cmi
+uutil.cmx: ubase/util.cmx ubase/projectInfo.cmx uutil.cmi
xferhint.cmo: ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi path.cmi os.cmi \
fspath.cmi xferhint.cmi
xferhint.cmx: ubase/util.cmx ubase/trace.cmx ubase/prefs.cmx path.cmx os.cmx \
@@ -256,6 +279,8 @@
ubase/prefs.cmi
ubase/prefs.cmx: ubase/util.cmx ubase/uarg.cmx ubase/safelist.cmx \
ubase/prefs.cmi
+ubase/projectInfo.cmo:
+ubase/projectInfo.cmx:
ubase/rx.cmo: ubase/rx.cmi
ubase/rx.cmx: ubase/rx.cmi
ubase/safelist.cmo: ubase/safelist.cmi
@@ -270,7 +295,15 @@
ubase/uprintf.cmx: ubase/uprintf.cmi
ubase/util.cmo: ubase/uprintf.cmi ubase/safelist.cmi ubase/util.cmi
ubase/util.cmx: ubase/uprintf.cmx ubase/safelist.cmx ubase/util.cmi
+lwt/lwt.cmi:
lwt/lwt_unix.cmi: lwt/lwt.cmi
lwt/lwt_util.cmi: lwt/lwt.cmi
+lwt/pqueue.cmi:
+ubase/myMap.cmi:
ubase/prefs.cmi: ubase/util.cmi
+ubase/rx.cmi:
+ubase/safelist.cmi:
ubase/trace.cmi: ubase/prefs.cmi
+ubase/uarg.cmi:
+ubase/uprintf.cmi:
+ubase/util.cmi:
Modified: trunk/src/Makefile.OCaml
===================================================================
--- trunk/src/Makefile.OCaml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/Makefile.OCaml 2009-05-04 18:48:23 UTC (rev 326)
@@ -179,7 +179,7 @@
\
lwt/pqueue.cmo lwt/lwt.cmo lwt/lwt_util.cmo lwt/lwt_unix.cmo \
\
- case.cmo pred.cmo uutil.cmo \
+ unicode_tables.cmo unicode.cmo case.cmo pred.cmo uutil.cmo \
fileutil.cmo name.cmo path.cmo fspath.cmo fingerprint.cmo \
abort.cmo osx.cmo external.cmo \
props.cmo fileinfo.cmo os.cmo lock.cmo clroot.cmo common.cmo \
Modified: trunk/src/RECENTNEWS
===================================================================
--- trunk/src/RECENTNEWS 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/RECENTNEWS 2009-05-04 18:48:23 UTC (rev 326)
@@ -1,3 +1,14 @@
+CHANGES FROM VERSION 2.33.-4
+
+* Updated list of bad Windows file names following the MSDN
+ documentation (in particular, files with trailing dots are now
+ rejected when synchronizing with a Windows machine)
+* Experimental Unicode-aware case insensitive mode. It is activated
+ when the preference "unicode" is set to true and Unison is in
+ case-insensitive mode.
+* Bumped version number to reflect the newly added preference
+
+-------------------------------
CHANGES FROM VERSION 2.32.7
* Move descriptions of recent changes to documentation.
Modified: trunk/src/case.ml
===================================================================
--- trunk/src/case.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/case.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -34,16 +34,37 @@
^ "useful to set the flag manually (e.g. when running Unison on a "
^ "Unix system with a FAT [Windows] volume mounted).")
+let unicodeEncoding =
+ Prefs.createBool "unicode" false
+ "!assume Unicode encoding in case insensitive mode"
+ "When set to {\\tt true}, this flag causes Unison to perform \
+ case insensitive file comparisons assuming Unicode encoding"
+
(* Defining this variable as a preference ensures that it will be propagated
to the other host during initialization *)
let someHostIsInsensitive =
Prefs.createBool "someHostIsInsensitive" false
"*Pseudo-preference for internal use only" ""
-(* Note: this function must be fast *)
-let insensitive () = Prefs.read someHostIsInsensitive
+(* During startup the client determines the case sensitivity of each root. *)
+(* If any root is case insensitive, all roots must know it; we ensure this *)
+(* by storing the information in a pref so that it is propagated to the *)
+(* server with the rest of the prefs. *)
+let init b =
+ Prefs.set someHostIsInsensitive
+ (Prefs.read caseInsensitiveMode = "yes" ||
+ Prefs.read caseInsensitiveMode = "true" ||
+ (Prefs.read caseInsensitiveMode = "default" && b))
-let needNormalization s =
+(****)
+
+(* Dots are ignored at the end of filenames under Windows. *)
+
+(* FIX: for the moment, simply disallow files ending with a dot.
+ This is more efficient, and this may well be good enough.
+ We should reconsider this is people start complaining...
+
+let hasTrailingDots s =
let rec iter s pos len wasDot =
if pos = len then wasDot else
let c = s.[pos] in
@@ -67,31 +88,87 @@
done;
String.sub s' (!pos' + 1) (len - !pos' - 1)
-(* Dots are ignored at the end of filenames under Windows. *)
-let normalize s =
+let rmTrailDots s =
s
(*FIX: disabled for know -- requires an archive version change
if
- insensitive () &&
-(*FIX: should only be done when one host is running under Windows...
-(should be OK for now as it seems unlikely to have a file ending with
- a dot and the same file with the same name but no dot at the end)
Prefs.read someHostIsRunningWindows &&
not (Prefs.read allHostsAreRunningWindows) &&
-*)
- needNormalization s
+ hasTrailingDots s
then
removeTrailingDots s
else
s
*)
+*)
-(* During startup the client determines the case sensitivity of each root. *)
-(* If any root is case insensitive, all roots must know it; we ensure this *)
-(* by storing the information in a pref so that it is propagated to the *)
-(* server with the rest of the prefs. *)
-let init b =
- Prefs.set someHostIsInsensitive
- (Prefs.read caseInsensitiveMode = "yes" ||
- Prefs.read caseInsensitiveMode = "true" ||
- (Prefs.read caseInsensitiveMode = "default" && b))
+(****)
+
+(* Windows file naming conventions are descripted here:
+ <http://msdn.microsoft.com/en-us/library/aa365247(printer).aspx> *)
+let badWindowsFilenameRx =
+ Rx.case_insensitive
+ (Rx.rx
+ "(.*[\000-\031<>:\"/\\|?*].*)|\
+ ((con|prn|aux|nul|com[1-9]|lpt[1-9])(\\.[^.]*)?)|\
+ (.*[. ])")
+
+let isBadWindowsFilename s =
+ (* FIX: should also check for a max filename length, not sure how much *)
+ Rx.match_string badWindowsFilenameRx s
+let badFilename someHostIsRunningWindows s =
+ (* Don't check unless we are syncing with Windows *)
+ someHostIsRunningWindows && isBadWindowsFilename s
+
+(****)
+
+type mode = Sensitive | Insensitive | UnicodeInsensitive
+
+(*
+Important invariant:
+ if [compare s s' = 0],
+ then [hash s = hash s'] and
+ and [Rx.match_string rx (normalizeMatchedString s) =
+ Rx.match_string rx (normalizeMatchedString s')]
+ (when [rx] has been compiled using the [caseInsensitiveMatch] mode)
+*)
+
+let sensitiveOps = object
+ method mode = Sensitive
+ method compare s s' = compare s s'
+ method hash s = Hashtbl.hash s
+ method normalizePattern s = s
+ method caseInsensitiveMatch = false
+ method normalizeMatchedString s = s
+ method badFilename w s = badFilename w s
+end
+
+let insensitiveOps = object
+ method mode = Insensitive
+ method compare s s' = Util.nocase_cmp s s'
+ method hash s = Hashtbl.hash (String.lowercase s)
+ method normalizePattern s = s
+ method caseInsensitiveMatch = true
+ method normalizeMatchedString s = s
+ method badFilename w s = badFilename w s
+end
+
+let unicodeInsensitiveOps = object
+ method mode = UnicodeInsensitive
+ method compare s s' = Unicode.compare s s'
+ method hash s = Hashtbl.hash (Unicode.normalize s)
+ method normalizePattern p = Unicode.normalize p
+ method caseInsensitiveMatch = false
+ method normalizeMatchedString s = Unicode.normalize s
+ method badFilename w s = not (Unicode.check_utf_8 s) || badFilename w s
+end
+
+(* Note: the dispatch must be fast *)
+let ops () =
+ if Prefs.read someHostIsInsensitive then begin
+ if Prefs.read unicodeEncoding then
+ unicodeInsensitiveOps
+ else
+ insensitiveOps
+ end else
+ sensitiveOps
Modified: trunk/src/case.mli
===================================================================
--- trunk/src/case.mli 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/case.mli 2009-05-04 18:48:23 UTC (rev 326)
@@ -1,8 +1,15 @@
(* Unison file synchronizer: src/case.mli *)
(* Copyright 1999-2009, Benjamin C. Pierce (see COPYING for details) *)
-val insensitive : unit -> bool
+type mode
-val normalize : string -> string
+val ops : unit ->
+ < mode : mode;
+ compare : string -> string -> int;
+ hash : string -> int;
+ normalizePattern : string -> string;
+ caseInsensitiveMatch : bool;
+ normalizeMatchedString : string -> string;
+ badFilename : bool -> string -> bool >
val init : bool -> unit
Modified: trunk/src/mkProjectInfo.ml
===================================================================
--- trunk/src/mkProjectInfo.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/mkProjectInfo.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -5,8 +5,8 @@
let projectName = "unison"
let majorVersion = 2
-let minorVersion = 32
-let pointVersionOrigin = 313 (* Revision that corresponds to point version 0 *)
+let minorVersion = 33
+let pointVersionOrigin = 325 (* Revision that corresponds to point version 0 *)
(* Documentation:
This is a program to construct a version of the form Major.Minor.Point,
@@ -105,3 +105,4 @@
+
Modified: trunk/src/name.ml
===================================================================
--- trunk/src/name.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/name.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -20,11 +20,7 @@
INCREMENT "UPDATE.ARCHIVEFORMAT" *)
type t = string
-let compare n1 n2 =
- if Case.insensitive () then
- Util.nocase_cmp (Case.normalize n1) (Case.normalize n2)
- else
- compare n1 n2
+let compare n1 n2 = (Case.ops())#compare n1 n2
let eq a b = (0 = (compare a b))
@@ -41,5 +37,7 @@
(* We ought to consider further checks, e.g., in Windows, no colons *)
s
-let hash n =
- Hashtbl.hash (if Case.insensitive () then String.lowercase (Case.normalize n) else n)
+let hash n = (Case.ops())#hash n
+
+let bad someHostIsRunningWindows n =
+ (Case.ops())#badFilename someHostIsRunningWindows n
Modified: trunk/src/name.mli
===================================================================
--- trunk/src/name.mli 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/name.mli 2009-05-04 18:48:23 UTC (rev 326)
@@ -9,3 +9,5 @@
val compare : t -> t -> int
val eq : t -> t -> bool
val hash : t -> int
+
+val bad : bool -> t -> bool
Modified: trunk/src/path.ml
===================================================================
--- trunk/src/path.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/path.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -170,8 +170,7 @@
let toString path = path
-let compare p1 p2 =
- if Case.insensitive () then Util.nocase_cmp p1 p2 else compare p1 p2
+let compare p1 p2 = (Case.ops())#compare p1 p2
let toDebugString path = String.concat " / " (toStringList path)
@@ -191,6 +190,7 @@
assert (not (isEmpty path));
prefix ^ path
+(* No need to perform case normalization on local paths *)
let hash p = Hashtbl.hash p
(* Pref controlling whether symlinks are followed. *)
Modified: trunk/src/pred.ml
===================================================================
--- trunk/src/pred.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/pred.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -28,7 +28,7 @@
mutable default: string list;
mutable last_pref : string list;
mutable last_def : string list;
- mutable last_mode : bool;
+ mutable last_mode : Case.mode;
mutable compiled: Rx.t;
mutable associated_strings : (Rx.t * string) list;
}
@@ -61,7 +61,7 @@
let (p,v) =
match Util.splitIntoWordsByString clause mapSeparator with
[p] -> (p,None)
- | [p;v] -> (p, Some (Util.trimWhitespace v))
+ | [p;v] -> (p, Some ((Case.ops())#normalizePattern (Util.trimWhitespace v)))
| [] -> raise (Prefs.IllegalValue "Empty pattern")
| _ -> raise (Prefs.IllegalValue ("Malformed pattern: "
^ "\"" ^ clause ^ "\"\n"
@@ -97,7 +97,7 @@
string :: oldList)
(fun l -> l) in
{pref = pref; name = name;
- last_pref = []; default = []; last_def = []; last_mode = false;
+ last_pref = []; default = []; last_def = []; last_mode = (Case.ops())#mode;
compiled = Rx.empty; associated_strings = []}
let addDefaultPatterns p pats =
@@ -115,14 +115,16 @@
None -> None
| Some v -> Some (rx,v))
compiledList in
- p.compiled <- if mode then Rx.case_insensitive compiled else compiled;
+ p.compiled <-
+ if (Case.ops())#caseInsensitiveMatch then Rx.case_insensitive compiled
+ else compiled;
p.associated_strings <- strings;
p.last_pref <- pref;
p.last_def <- p.default;
p.last_mode <- mode
let recompile_if_needed p =
- let mode = Case.insensitive () in
+ let mode = (Case.ops())#mode in
if
p.last_mode <> mode ||
p.last_pref != Prefs.read p.pref ||
@@ -148,10 +150,11 @@
let test p s =
recompile_if_needed p;
- let res = Rx.match_string p.compiled (Case.normalize s) in
+ let res = Rx.match_string p.compiled ((Case.ops())#normalizeMatchedString s) in
debug (fun() -> Util.msg "%s '%s' = %b\n" p.name s res);
res
let assoc p s =
recompile_if_needed p;
+ let s = (Case.ops())#normalizeMatchedString s in
snd (Safelist.find (fun (rx,v) -> Rx.match_string rx s) p.associated_strings)
Modified: trunk/src/ubase/depend
===================================================================
--- trunk/src/ubase/depend 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/ubase/depend 2009-05-04 18:48:23 UTC (rev 326)
@@ -2,6 +2,8 @@
myMap.cmx: myMap.cmi
prefs.cmo: util.cmi uarg.cmi safelist.cmi prefs.cmi
prefs.cmx: util.cmx uarg.cmx safelist.cmx prefs.cmi
+projectInfo.cmo:
+projectInfo.cmx:
rx.cmo: rx.cmi
rx.cmx: rx.cmi
safelist.cmo: safelist.cmi
@@ -14,5 +16,11 @@
uprintf.cmx: uprintf.cmi
util.cmo: uprintf.cmi safelist.cmi util.cmi
util.cmx: uprintf.cmx safelist.cmx util.cmi
+myMap.cmi:
prefs.cmi: util.cmi
+rx.cmi:
+safelist.cmi:
trace.cmi: prefs.cmi
+uarg.cmi:
+uprintf.cmi:
+util.cmi:
Added: trunk/src/unicode.ml
===================================================================
--- trunk/src/unicode.ml (rev 0)
+++ trunk/src/unicode.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -0,0 +1,859 @@
+(* Unison file synchronizer: src/unicode.ml *)
+(* Copyright 1999-2009, Benjamin C. Pierce
+
+ 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+*)
+
+open Unicode_tables
+
+exception Invalid
+
+let fail () = raise Invalid
+
+let get s i = Char.code (String.unsafe_get s i)
+let set s i v = String.unsafe_set s i (Char.unsafe_chr v)
+
+(****)
+
+let hangul_sbase = 0xAC00
+let hangul_lbase = 0x1100
+let hangul_vbase = 0x1161
+let hangul_tbase = 0x11A7
+
+let hangul_scount = 11172
+let hangul_lcount = 19
+let hangul_vcount = 21
+let hangul_tcount = 28
+let hangul_ncount = hangul_vcount * hangul_tcount
+
+let set_char_3 s i c =
+ set s i (c lsr 12 + 0xE0);
+ set s (i + 1) ((c lsr 6) land 0x3f + 0x80);
+ set s (i + 2) (c land 0x3f + 0x80)
+
+let rec norm s i l s' j =
+ if i < l then begin
+ let c = get s i in
+ if c < 0x80 then begin
+ set s' j (get ascii_lower c);
+ norm s (i + 1) l s' (j + 1)
+ end else if c < 0xE0 then begin
+ (* 80 - 7FF *)
+ if c < 0xc2 || i + 1 >= l then raise Invalid;
+ let c1 = get s (i + 1) in
+ if c1 land 0xc0 <> 0x80 then raise Invalid;
+ let idx = get norm_prim (c - 0xc0) in
+ let idx = idx lsl 6 + c1 - 0x80 in
+ let k = get norm_second_high idx in
+ if k = 0 then begin
+ set s' j c;
+ set s' (j + 1) c1;
+ norm s (i + 2) l s' (j + 2)
+ end else begin
+ let k = (k - 2) lsl 8 + get norm_second_low idx in
+ let n = get norm_repl k in
+ String.blit norm_repl (k + 1) s' j n;
+ norm s (i + 2) l s' (j + n)
+ end
+ end else if c < 0xF0 then begin
+ (* 800 - FFFF *)
+ if i + 2 >= l then raise Invalid;
+ let c1 = get s (i + 1) in
+ if c1 land 0xc0 <> 0x80 then raise Invalid;
+ let idx = c lsl 6 + c1 - 0x3880 in
+ if idx < 0x20 then raise Invalid;
+ let c2 = get s (i + 2) in
+ if c2 land 0xc0 <> 0x80 then raise Invalid;
+ let idx = get norm_prim idx in
+ let idx = idx lsl 6 + c2 - 0x80 in
+ let k = get norm_second_high idx in
+ if k = 0 then begin
+ set s' j c;
+ set s' (j + 1) c1;
+ set s' (j + 2) c2;
+ norm s (i + 3) l s' (j + 3)
+ end else if k = 1 then begin
+ let v = c lsl 12 + c1 lsl 6 + c2 - (0x000E2080 + hangul_sbase) in
+ if v >= hangul_scount then begin
+ set s' j c;
+ set s' (j + 1) c1;
+ set s' (j + 2) c2;
+ norm s (i + 3) l s' (j + 3)
+ end else begin
+ set_char_3 s' j (v / hangul_ncount + hangul_lbase);
+ set_char_3 s' (j + 3)
+ ((v mod hangul_ncount) / hangul_tcount + hangul_vbase);
+ if v mod hangul_tcount = 0 then
+ norm s (i + 3) l s' (j + 6)
+ else begin
+ set_char_3 s' (j + 6) ((v mod hangul_tcount) + hangul_tbase);
+ norm s (i + 3) l s' (j + 9)
+ end
+ end
+ end else begin
+ let k = (k - 2) lsl 8 + get norm_second_low idx in
+ let n = get norm_repl k in
+ String.blit norm_repl (k + 1) s' j n;
+ norm s (i + 3) l s' (j + n)
+ end
+ end else begin
+ (* 10000 - 10FFFF *)
+ if i + 3 >= l then raise Invalid;
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ let c3 = get s (i + 3) in
+ if (c1 lor c2 lor c3) land 0xc0 <> 0x80 then raise Invalid;
+ let v = c lsl 18 + c1 lsl 12 + c2 lsl 6 + c3 - 0x03c82080 in
+ if v < 0x10000 || v > 0x10ffff then raise Invalid;
+ set s' j c;
+ set s' (j + 1) c1;
+ set s' (j + 2) c2;
+ set s' (j + 3) c3;
+ norm s (i + 4) l s' (j + 4)
+ end
+ end else
+ String.sub s' 0 j
+
+let normalize s =
+ let l = String.length s in
+ let s' = String.create (3 * l) in
+ try norm s 0 l s' 0 with Invalid -> s
+
+(****)
+
+let rec compare_rec s s' i l =
+ if i = l then begin
+ if l < String.length s then 1 else
+ if l < String.length s' then -1 else
+ 0
+ end else begin
+ let c = get s i in
+ let c' = get s' i in
+ if c < 0x80 && c' < 0x80 then begin
+ let v = compare (get ascii_lower c) (get ascii_lower c') in
+ if v <> 0 then v else compare_rec s s' (i + 1) l
+ end else
+ compare (normalize s) (normalize s')
+ end
+
+let compare s s' =
+ compare_rec s s' 0 (min (String.length s) (String.length s'))
+
+(****)
+
+let rec decode_char s i l =
+ if i = l then fail () else
+ let c = get s i in
+ if c < 0x80 then
+ cont s (i + 1) l c
+ else if c < 0xE0 then begin
+ (* 80 - 7FF *)
+ if c < 0xc2 || i + 1 >= l then fail () else
+ let c1 = get s (i + 1) in
+ if c1 land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 6 + c1 - 0x3080 in
+ cont s (i + 2) l v
+ end else if c < 0xF0 then begin
+ (* 800 - FFFF *)
+ if i + 2 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ if (c1 lor c2) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 12 + c1 lsl 6 + c2 - 0xe2080 in
+ if v < 0x800 then fail () else
+ cont s (i + 3) l v
+ end else begin
+ (* 10000 - 10FFFF *)
+ if i + 3 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ let c3 = get s (i + 3) in
+ if (c1 lor c2 lor c3) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 18 + c1 lsl 12 + c2 lsl 6 + c3 - 0x03c82080 in
+ if v < 0x10000 || v > 0x10ffff then fail () else
+ cont s (i + 4) l v
+ end
+
+and cont s i l v = (v, i)
+
+let encode_char s i l c =
+ if c < 0x80 then begin
+ if i >= l then fail () else begin
+ set s i c;
+ i + 1
+ end
+ end else if c < 0x800 then begin
+ if i + 1 >= l then fail () else begin
+ set s i (c lsr 6 + 0xC0);
+ set s (i + 1) (c land 0x3f + 0x80);
+ i + 2
+ end
+ end else if c < 0x10000 then begin
+ if i + 1 >= l then fail () else begin
+ set s i (c lsr 12 + 0xE0);
+ set s (i + 1) ((c lsr 6) land 0x3f + 0x80);
+ set s (i + 2) (c land 0x3f + 0x80);
+ i + 3
+ end
+ end else begin
+ if i + 1 >= l then fail () else begin
+ set s i (c lsr 18 + 0xF0);
+ set s (i + 1) ((c lsr 12) land 0x3f + 0x80);
+ set s (i + 2) ((c lsr 6) land 0x3f + 0x80);
+ set s (i + 3) (c land 0x3f + 0x80);
+ i + 4
+ end
+ end
+
+let rec prev_char s i =
+ let i = i - 1 in
+ if i < 0 then fail () else
+ if (get s i) land 0xc0 <> 0x80 then i else prev_char s i
+
+(****)
+
+let uniCharPrecompSourceTable = [|
+ 0x00000300; 0x00540000; 0x00000301; 0x00750054;
+ 0x00000302; 0x002000C9; 0x00000303; 0x001C00E9;
+ 0x00000304; 0x002C0105; 0x00000306; 0x00200131;
+ 0x00000307; 0x002E0151; 0x00000308; 0x0036017F;
+ 0x00000309; 0x001801B5; 0x0000030A; 0x000601CD;
+ 0x0000030B; 0x000601D3; 0x0000030C; 0x002501D9;
+ 0x0000030F; 0x000E01FE; 0x00000311; 0x000C020C;
+ 0x00000313; 0x000E0218; 0x00000314; 0x00100226;
+ 0x0000031B; 0x00040236; 0x00000323; 0x002A023A;
+ 0x00000324; 0x00020264; 0x00000325; 0x00020266;
+ 0x00000326; 0x00040268; 0x00000327; 0x0016026C;
+ 0x00000328; 0x000A0282; 0x0000032D; 0x000C028C;
+ 0x0000032E; 0x00020298; 0x00000330; 0x0006029A;
+ 0x00000331; 0x001102A0; 0x00000338; 0x002C02B1;
+ 0x00000342; 0x001D02DD; 0x00000345; 0x003F02FA;
+ 0x00000653; 0x00010339; 0x00000654; 0x0006033A;
+ 0x00000655; 0x00010340; 0x0000093C; 0x00030341;
+ 0x000009BE; 0x00010344; 0x000009D7; 0x00010345;
+ 0x00000B3E; 0x00010346; 0x00000B56; 0x00010347;
+ 0x00000B57; 0x00010348; 0x00000BBE; 0x00020349;
+ 0x00000BD7; 0x0002034B; 0x00000C56; 0x0001034D;
+ 0x00000CC2; 0x0001034E; 0x00000CD5; 0x0003034F;
+ 0x00000CD6; 0x00010352; 0x00000D3E; 0x00020353;
+ 0x00000D57; 0x00010355; 0x00000DCA; 0x00020356;
+ 0x00000DCF; 0x00010358; 0x00000DDF; 0x00010359;
+ 0x0000102E; 0x0001035A; 0x00003099; 0x0030035B;
+ 0x0000309A; 0x000A038B
+|]
+
+let uniCharBMPPrecompDestinationTable = [|
+ 0x0041; 0x00C0; 0x0045; 0x00C8; 0x0049; 0x00CC; 0x004E; 0x01F8;
+ 0x004F; 0x00D2; 0x0055; 0x00D9; 0x0057; 0x1E80; 0x0059; 0x1EF2;
+ 0x0061; 0x00E0; 0x0065; 0x00E8; 0x0069; 0x00EC; 0x006E; 0x01F9;
+ 0x006F; 0x00F2; 0x0075; 0x00F9; 0x0077; 0x1E81; 0x0079; 0x1EF3;
+ 0x00A8; 0x1FED; 0x00C2; 0x1EA6; 0x00CA; 0x1EC0; 0x00D4; 0x1ED2;
+ 0x00DC; 0x01DB; 0x00E2; 0x1EA7; 0x00EA; 0x1EC1; 0x00F4; 0x1ED3;
+ 0x00FC; 0x01DC; 0x0102; 0x1EB0; 0x0103; 0x1EB1; 0x0112; 0x1E14;
+ 0x0113; 0x1E15; 0x014C; 0x1E50; 0x014D; 0x1E51; 0x01A0; 0x1EDC;
+ 0x01A1; 0x1EDD; 0x01AF; 0x1EEA; 0x01B0; 0x1EEB; 0x0391; 0x1FBA;
+ 0x0395; 0x1FC8; 0x0397; 0x1FCA; 0x0399; 0x1FDA; 0x039F; 0x1FF8;
+ 0x03A5; 0x1FEA; 0x03A9; 0x1FFA; 0x03B1; 0x1F70; 0x03B5; 0x1F72;
+ 0x03B7; 0x1F74; 0x03B9; 0x1F76; 0x03BF; 0x1F78; 0x03C5; 0x1F7A;
+ 0x03C9; 0x1F7C; 0x03CA; 0x1FD2; 0x03CB; 0x1FE2; 0x0415; 0x0400;
+ 0x0418; 0x040D; 0x0435; 0x0450; 0x0438; 0x045D; 0x1F00; 0x1F02;
+ 0x1F01; 0x1F03; 0x1F08; 0x1F0A; 0x1F09; 0x1F0B; 0x1F10; 0x1F12;
+ 0x1F11; 0x1F13; 0x1F18; 0x1F1A; 0x1F19; 0x1F1B; 0x1F20; 0x1F22;
+ 0x1F21; 0x1F23; 0x1F28; 0x1F2A; 0x1F29; 0x1F2B; 0x1F30; 0x1F32;
+ 0x1F31; 0x1F33; 0x1F38; 0x1F3A; 0x1F39; 0x1F3B; 0x1F40; 0x1F42;
+ 0x1F41; 0x1F43; 0x1F48; 0x1F4A; 0x1F49; 0x1F4B; 0x1F50; 0x1F52;
+ 0x1F51; 0x1F53; 0x1F59; 0x1F5B; 0x1F60; 0x1F62; 0x1F61; 0x1F63;
+ 0x1F68; 0x1F6A; 0x1F69; 0x1F6B; 0x1FBF; 0x1FCD; 0x1FFE; 0x1FDD;
+ 0x0041; 0x00C1; 0x0043; 0x0106; 0x0045; 0x00C9; 0x0047; 0x01F4;
+ 0x0049; 0x00CD; 0x004B; 0x1E30; 0x004C; 0x0139; 0x004D; 0x1E3E;
+ 0x004E; 0x0143; 0x004F; 0x00D3; 0x0050; 0x1E54; 0x0052; 0x0154;
+ 0x0053; 0x015A; 0x0055; 0x00DA; 0x0057; 0x1E82; 0x0059; 0x00DD;
+ 0x005A; 0x0179; 0x0061; 0x00E1; 0x0063; 0x0107; 0x0065; 0x00E9;
+ 0x0067; 0x01F5; 0x0069; 0x00ED; 0x006B; 0x1E31; 0x006C; 0x013A;
+ 0x006D; 0x1E3F; 0x006E; 0x0144; 0x006F; 0x00F3; 0x0070; 0x1E55;
+ 0x0072; 0x0155; 0x0073; 0x015B; 0x0075; 0x00FA; 0x0077; 0x1E83;
+ 0x0079; 0x00FD; 0x007A; 0x017A; 0x00A8; 0x0385; 0x00C2; 0x1EA4;
+ 0x00C5; 0x01FA; 0x00C6; 0x01FC; 0x00C7; 0x1E08; 0x00CA; 0x1EBE;
+ 0x00CF; 0x1E2E; 0x00D4; 0x1ED0; 0x00D5; 0x1E4C; 0x00D8; 0x01FE;
+ 0x00DC; 0x01D7; 0x00E2; 0x1EA5; 0x00E5; 0x01FB; 0x00E6; 0x01FD;
+ 0x00E7; 0x1E09; 0x00EA; 0x1EBF; 0x00EF; 0x1E2F; 0x00F4; 0x1ED1;
+ 0x00F5; 0x1E4D; 0x00F8; 0x01FF; 0x00FC; 0x01D8; 0x0102; 0x1EAE;
+ 0x0103; 0x1EAF; 0x0112; 0x1E16; 0x0113; 0x1E17; 0x014C; 0x1E52;
+ 0x014D; 0x1E53; 0x0168; 0x1E78; 0x0169; 0x1E79; 0x01A0; 0x1EDA;
+ 0x01A1; 0x1EDB; 0x01AF; 0x1EE8; 0x01B0; 0x1EE9; 0x0391; 0x0386;
+ 0x0395; 0x0388; 0x0397; 0x0389; 0x0399; 0x038A; 0x039F; 0x038C;
+ 0x03A5; 0x038E; 0x03A9; 0x038F; 0x03B1; 0x03AC; 0x03B5; 0x03AD;
+ 0x03B7; 0x03AE; 0x03B9; 0x03AF; 0x03BF; 0x03CC; 0x03C5; 0x03CD;
+ 0x03C9; 0x03CE; 0x03CA; 0x0390; 0x03CB; 0x03B0; 0x03D2; 0x03D3;
+ 0x0413; 0x0403; 0x041A; 0x040C; 0x0433; 0x0453; 0x043A; 0x045C;
+ 0x1F00; 0x1F04; 0x1F01; 0x1F05; 0x1F08; 0x1F0C; 0x1F09; 0x1F0D;
+ 0x1F10; 0x1F14; 0x1F11; 0x1F15; 0x1F18; 0x1F1C; 0x1F19; 0x1F1D;
+ 0x1F20; 0x1F24; 0x1F21; 0x1F25; 0x1F28; 0x1F2C; 0x1F29; 0x1F2D;
+ 0x1F30; 0x1F34; 0x1F31; 0x1F35; 0x1F38; 0x1F3C; 0x1F39; 0x1F3D;
+ 0x1F40; 0x1F44; 0x1F41; 0x1F45; 0x1F48; 0x1F4C; 0x1F49; 0x1F4D;
+ 0x1F50; 0x1F54; 0x1F51; 0x1F55; 0x1F59; 0x1F5D; 0x1F60; 0x1F64;
+ 0x1F61; 0x1F65; 0x1F68; 0x1F6C; 0x1F69; 0x1F6D; 0x1FBF; 0x1FCE;
+ 0x1FFE; 0x1FDE; 0x0041; 0x00C2; 0x0043; 0x0108; 0x0045; 0x00CA;
+ 0x0047; 0x011C; 0x0048; 0x0124; 0x0049; 0x00CE; 0x004A; 0x0134;
+ 0x004F; 0x00D4; 0x0053; 0x015C; 0x0055; 0x00DB; 0x0057; 0x0174;
+ 0x0059; 0x0176; 0x005A; 0x1E90; 0x0061; 0x00E2; 0x0063; 0x0109;
+ 0x0065; 0x00EA; 0x0067; 0x011D; 0x0068; 0x0125; 0x0069; 0x00EE;
+ 0x006A; 0x0135; 0x006F; 0x00F4; 0x0073; 0x015D; 0x0075; 0x00FB;
+ 0x0077; 0x0175; 0x0079; 0x0177; 0x007A; 0x1E91; 0x1EA0; 0x1EAC;
+ 0x1EA1; 0x1EAD; 0x1EB8; 0x1EC6; 0x1EB9; 0x1EC7; 0x1ECC; 0x1ED8;
+ 0x1ECD; 0x1ED9; 0x0041; 0x00C3; 0x0045; 0x1EBC; 0x0049; 0x0128;
+ 0x004E; 0x00D1; 0x004F; 0x00D5; 0x0055; 0x0168; 0x0056; 0x1E7C;
+ 0x0059; 0x1EF8; 0x0061; 0x00E3; 0x0065; 0x1EBD; 0x0069; 0x0129;
+ 0x006E; 0x00F1; 0x006F; 0x00F5; 0x0075; 0x0169; 0x0076; 0x1E7D;
+ 0x0079; 0x1EF9; 0x00C2; 0x1EAA; 0x00CA; 0x1EC4; 0x00D4; 0x1ED6;
+ 0x00E2; 0x1EAB; 0x00EA; 0x1EC5; 0x00F4; 0x1ED7; 0x0102; 0x1EB4;
+ 0x0103; 0x1EB5; 0x01A0; 0x1EE0; 0x01A1; 0x1EE1; 0x01AF; 0x1EEE;
+ 0x01B0; 0x1EEF; 0x0041; 0x0100; 0x0045; 0x0112; 0x0047; 0x1E20;
+ 0x0049; 0x012A; 0x004F; 0x014C; 0x0055; 0x016A; 0x0059; 0x0232;
+ 0x0061; 0x0101; 0x0065; 0x0113; 0x0067; 0x1E21; 0x0069; 0x012B;
+ 0x006F; 0x014D; 0x0075; 0x016B; 0x0079; 0x0233; 0x00C4; 0x01DE;
+ 0x00C6; 0x01E2; 0x00D5; 0x022C; 0x00D6; 0x022A; 0x00DC; 0x01D5;
+ 0x00E4; 0x01DF; 0x00E6; 0x01E3; 0x00F5; 0x022D; 0x00F6; 0x022B;
+ 0x00FC; 0x01D6; 0x01EA; 0x01EC; 0x01EB; 0x01ED; 0x0226; 0x01E0;
+ 0x0227; 0x01E1; 0x022E; 0x0230; 0x022F; 0x0231; 0x0391; 0x1FB9;
+ 0x0399; 0x1FD9; 0x03A5; 0x1FE9; 0x03B1; 0x1FB1; 0x03B9; 0x1FD1;
+ 0x03C5; 0x1FE1; 0x0418; 0x04E2; 0x0423; 0x04EE; 0x0438; 0x04E3;
+ 0x0443; 0x04EF; 0x1E36; 0x1E38; 0x1E37; 0x1E39; 0x1E5A; 0x1E5C;
+ 0x1E5B; 0x1E5D; 0x0041; 0x0102; 0x0045; 0x0114; 0x0047; 0x011E;
+ 0x0049; 0x012C; 0x004F; 0x014E; 0x0055; 0x016C; 0x0061; 0x0103;
+ 0x0065; 0x0115; 0x0067; 0x011F; 0x0069; 0x012D; 0x006F; 0x014F;
+ 0x0075; 0x016D; 0x0228; 0x1E1C; 0x0229; 0x1E1D; 0x0391; 0x1FB8;
+ 0x0399; 0x1FD8; 0x03A5; 0x1FE8; 0x03B1; 0x1FB0; 0x03B9; 0x1FD0;
+ 0x03C5; 0x1FE0; 0x0410; 0x04D0; 0x0415; 0x04D6; 0x0416; 0x04C1;
+ 0x0418; 0x0419; 0x0423; 0x040E; 0x0430; 0x04D1; 0x0435; 0x04D7;
+ 0x0436; 0x04C2; 0x0438; 0x0439; 0x0443; 0x045E; 0x1EA0; 0x1EB6;
+ 0x1EA1; 0x1EB7; 0x0041; 0x0226; 0x0042; 0x1E02; 0x0043; 0x010A;
+ 0x0044; 0x1E0A; 0x0045; 0x0116; 0x0046; 0x1E1E; 0x0047; 0x0120;
+ 0x0048; 0x1E22; 0x0049; 0x0130; 0x004D; 0x1E40; 0x004E; 0x1E44;
+ 0x004F; 0x022E; 0x0050; 0x1E56; 0x0052; 0x1E58; 0x0053; 0x1E60;
+ 0x0054; 0x1E6A; 0x0057; 0x1E86; 0x0058; 0x1E8A; 0x0059; 0x1E8E;
+ 0x005A; 0x017B; 0x0061; 0x0227; 0x0062; 0x1E03; 0x0063; 0x010B;
+ 0x0064; 0x1E0B; 0x0065; 0x0117; 0x0066; 0x1E1F; 0x0067; 0x0121;
+ 0x0068; 0x1E23; 0x006D; 0x1E41; 0x006E; 0x1E45; 0x006F; 0x022F;
+ 0x0070; 0x1E57; 0x0072; 0x1E59; 0x0073; 0x1E61; 0x0074; 0x1E6B;
+ 0x0077; 0x1E87; 0x0078; 0x1E8B; 0x0079; 0x1E8F; 0x007A; 0x017C;
+ 0x015A; 0x1E64; 0x015B; 0x1E65; 0x0160; 0x1E66; 0x0161; 0x1E67;
+ 0x017F; 0x1E9B; 0x1E62; 0x1E68; 0x1E63; 0x1E69; 0x0041; 0x00C4;
+ 0x0045; 0x00CB; 0x0048; 0x1E26; 0x0049; 0x00CF; 0x004F; 0x00D6;
+ 0x0055; 0x00DC; 0x0057; 0x1E84; 0x0058; 0x1E8C; 0x0059; 0x0178;
+ 0x0061; 0x00E4; 0x0065; 0x00EB; 0x0068; 0x1E27; 0x0069; 0x00EF;
+ 0x006F; 0x00F6; 0x0074; 0x1E97; 0x0075; 0x00FC; 0x0077; 0x1E85;
+ 0x0078; 0x1E8D; 0x0079; 0x00FF; 0x00D5; 0x1E4E; 0x00F5; 0x1E4F;
+ 0x016A; 0x1E7A; 0x016B; 0x1E7B; 0x0399; 0x03AA; 0x03A5; 0x03AB;
+ 0x03B9; 0x03CA; 0x03C5; 0x03CB; 0x03D2; 0x03D4; 0x0406; 0x0407;
+ 0x0410; 0x04D2; 0x0415; 0x0401; 0x0416; 0x04DC; 0x0417; 0x04DE;
+ 0x0418; 0x04E4; 0x041E; 0x04E6; 0x0423; 0x04F0; 0x0427; 0x04F4;
+ 0x042B; 0x04F8; 0x042D; 0x04EC; 0x0430; 0x04D3; 0x0435; 0x0451;
+ 0x0436; 0x04DD; 0x0437; 0x04DF; 0x0438; 0x04E5; 0x043E; 0x04E7;
+ 0x0443; 0x04F1; 0x0447; 0x04F5; 0x044B; 0x04F9; 0x044D; 0x04ED;
+ 0x0456; 0x0457; 0x04D8; 0x04DA; 0x04D9; 0x04DB; 0x04E8; 0x04EA;
+ 0x04E9; 0x04EB; 0x0041; 0x1EA2; 0x0045; 0x1EBA; 0x0049; 0x1EC8;
+ 0x004F; 0x1ECE; 0x0055; 0x1EE6; 0x0059; 0x1EF6; 0x0061; 0x1EA3;
+ 0x0065; 0x1EBB; 0x0069; 0x1EC9; 0x006F; 0x1ECF; 0x0075; 0x1EE7;
+ 0x0079; 0x1EF7; 0x00C2; 0x1EA8; 0x00CA; 0x1EC2; 0x00D4; 0x1ED4;
+ 0x00E2; 0x1EA9; 0x00EA; 0x1EC3; 0x00F4; 0x1ED5; 0x0102; 0x1EB2;
+ 0x0103; 0x1EB3; 0x01A0; 0x1EDE; 0x01A1; 0x1EDF; 0x01AF; 0x1EEC;
+ 0x01B0; 0x1EED; 0x0041; 0x00C5; 0x0055; 0x016E; 0x0061; 0x00E5;
+ 0x0075; 0x016F; 0x0077; 0x1E98; 0x0079; 0x1E99; 0x004F; 0x0150;
+ 0x0055; 0x0170; 0x006F; 0x0151; 0x0075; 0x0171; 0x0423; 0x04F2;
+ 0x0443; 0x04F3; 0x0041; 0x01CD; 0x0043; 0x010C; 0x0044; 0x010E;
+ 0x0045; 0x011A; 0x0047; 0x01E6; 0x0048; 0x021E; 0x0049; 0x01CF;
+ 0x004B; 0x01E8; 0x004C; 0x013D; 0x004E; 0x0147; 0x004F; 0x01D1;
+ 0x0052; 0x0158; 0x0053; 0x0160; 0x0054; 0x0164; 0x0055; 0x01D3;
+ 0x005A; 0x017D; 0x0061; 0x01CE; 0x0063; 0x010D; 0x0064; 0x010F;
+ 0x0065; 0x011B; 0x0067; 0x01E7; 0x0068; 0x021F; 0x0069; 0x01D0;
+ 0x006A; 0x01F0; 0x006B; 0x01E9; 0x006C; 0x013E; 0x006E; 0x0148;
+ 0x006F; 0x01D2; 0x0072; 0x0159; 0x0073; 0x0161; 0x0074; 0x0165;
+ 0x0075; 0x01D4; 0x007A; 0x017E; 0x00DC; 0x01D9; 0x00FC; 0x01DA;
+ 0x01B7; 0x01EE; 0x0292; 0x01EF; 0x0041; 0x0200; 0x0045; 0x0204;
+ 0x0049; 0x0208; 0x004F; 0x020C; 0x0052; 0x0210; 0x0055; 0x0214;
+ 0x0061; 0x0201; 0x0065; 0x0205; 0x0069; 0x0209; 0x006F; 0x020D;
+ 0x0072; 0x0211; 0x0075; 0x0215; 0x0474; 0x0476; 0x0475; 0x0477;
+ 0x0041; 0x0202; 0x0045; 0x0206; 0x0049; 0x020A; 0x004F; 0x020E;
+ 0x0052; 0x0212; 0x0055; 0x0216; 0x0061; 0x0203; 0x0065; 0x0207;
+ 0x0069; 0x020B; 0x006F; 0x020F; 0x0072; 0x0213; 0x0075; 0x0217;
+ 0x0391; 0x1F08; 0x0395; 0x1F18; 0x0397; 0x1F28; 0x0399; 0x1F38;
+ 0x039F; 0x1F48; 0x03A9; 0x1F68; 0x03B1; 0x1F00; 0x03B5; 0x1F10;
+ 0x03B7; 0x1F20; 0x03B9; 0x1F30; 0x03BF; 0x1F40; 0x03C1; 0x1FE4;
+ 0x03C5; 0x1F50; 0x03C9; 0x1F60; 0x0391; 0x1F09; 0x0395; 0x1F19;
+ 0x0397; 0x1F29; 0x0399; 0x1F39; 0x039F; 0x1F49; 0x03A1; 0x1FEC;
+ 0x03A5; 0x1F59; 0x03A9; 0x1F69; 0x03B1; 0x1F01; 0x03B5; 0x1F11;
+ 0x03B7; 0x1F21; 0x03B9; 0x1F31; 0x03BF; 0x1F41; 0x03C1; 0x1FE5;
+ 0x03C5; 0x1F51; 0x03C9; 0x1F61; 0x004F; 0x01A0; 0x0055; 0x01AF;
+ 0x006F; 0x01A1; 0x0075; 0x01B0; 0x0041; 0x1EA0; 0x0042; 0x1E04;
+ 0x0044; 0x1E0C; 0x0045; 0x1EB8; 0x0048; 0x1E24; 0x0049; 0x1ECA;
+ 0x004B; 0x1E32; 0x004C; 0x1E36; 0x004D; 0x1E42; 0x004E; 0x1E46;
+ 0x004F; 0x1ECC; 0x0052; 0x1E5A; 0x0053; 0x1E62; 0x0054; 0x1E6C;
+ 0x0055; 0x1EE4; 0x0056; 0x1E7E; 0x0057; 0x1E88; 0x0059; 0x1EF4;
+ 0x005A; 0x1E92; 0x0061; 0x1EA1; 0x0062; 0x1E05; 0x0064; 0x1E0D;
+ 0x0065; 0x1EB9; 0x0068; 0x1E25; 0x0069; 0x1ECB; 0x006B; 0x1E33;
+ 0x006C; 0x1E37; 0x006D; 0x1E43; 0x006E; 0x1E47; 0x006F; 0x1ECD;
+ 0x0072; 0x1E5B; 0x0073; 0x1E63; 0x0074; 0x1E6D; 0x0075; 0x1EE5;
+ 0x0076; 0x1E7F; 0x0077; 0x1E89; 0x0079; 0x1EF5; 0x007A; 0x1E93;
+ 0x01A0; 0x1EE2; 0x01A1; 0x1EE3; 0x01AF; 0x1EF0; 0x01B0; 0x1EF1;
+ 0x0055; 0x1E72; 0x0075; 0x1E73; 0x0041; 0x1E00; 0x0061; 0x1E01;
+ 0x0053; 0x0218; 0x0054; 0x021A; 0x0073; 0x0219; 0x0074; 0x021B;
+ 0x0043; 0x00C7; 0x0044; 0x1E10; 0x0045; 0x0228; 0x0047; 0x0122;
+ 0x0048; 0x1E28; 0x004B; 0x0136; 0x004C; 0x013B; 0x004E; 0x0145;
+ 0x0052; 0x0156; 0x0053; 0x015E; 0x0054; 0x0162; 0x0063; 0x00E7;
+ 0x0064; 0x1E11; 0x0065; 0x0229; 0x0067; 0x0123; 0x0068; 0x1E29;
+ 0x006B; 0x0137; 0x006C; 0x013C; 0x006E; 0x0146; 0x0072; 0x0157;
+ 0x0073; 0x015F; 0x0074; 0x0163; 0x0041; 0x0104; 0x0045; 0x0118;
+ 0x0049; 0x012E; 0x004F; 0x01EA; 0x0055; 0x0172; 0x0061; 0x0105;
+ 0x0065; 0x0119; 0x0069; 0x012F; 0x006F; 0x01EB; 0x0075; 0x0173;
+ 0x0044; 0x1E12; 0x0045; 0x1E18; 0x004C; 0x1E3C; 0x004E; 0x1E4A;
+ 0x0054; 0x1E70; 0x0055; 0x1E76; 0x0064; 0x1E13; 0x0065; 0x1E19;
+ 0x006C; 0x1E3D; 0x006E; 0x1E4B; 0x0074; 0x1E71; 0x0075; 0x1E77;
+ 0x0048; 0x1E2A; 0x0068; 0x1E2B; 0x0045; 0x1E1A; 0x0049; 0x1E2C;
+ 0x0055; 0x1E74; 0x0065; 0x1E1B; 0x0069; 0x1E2D; 0x0075; 0x1E75;
+ 0x0042; 0x1E06; 0x0044; 0x1E0E; 0x004B; 0x1E34; 0x004C; 0x1E3A;
+ 0x004E; 0x1E48; 0x0052; 0x1E5E; 0x0054; 0x1E6E; 0x005A; 0x1E94;
+ 0x0062; 0x1E07; 0x0064; 0x1E0F; 0x0068; 0x1E96; 0x006B; 0x1E35;
+ 0x006C; 0x1E3B; 0x006E; 0x1E49; 0x0072; 0x1E5F; 0x0074; 0x1E6F;
+ 0x007A; 0x1E95; 0x003C; 0x226E; 0x003D; 0x2260; 0x003E; 0x226F;
+ 0x2190; 0x219A; 0x2192; 0x219B; 0x2194; 0x21AE; 0x21D0; 0x21CD;
+ 0x21D2; 0x21CF; 0x21D4; 0x21CE; 0x2203; 0x2204; 0x2208; 0x2209;
+ 0x220B; 0x220C; 0x2223; 0x2224; 0x2225; 0x2226; 0x223C; 0x2241;
+ 0x2243; 0x2244; 0x2245; 0x2247; 0x2248; 0x2249; 0x224D; 0x226D;
+ 0x2261; 0x2262; 0x2264; 0x2270; 0x2265; 0x2271; 0x2272; 0x2274;
+ 0x2273; 0x2275; 0x2276; 0x2278; 0x2277; 0x2279; 0x227A; 0x2280;
+ 0x227B; 0x2281; 0x227C; 0x22E0; 0x227D; 0x22E1; 0x2282; 0x2284;
+ 0x2283; 0x2285; 0x2286; 0x2288; 0x2287; 0x2289; 0x2291; 0x22E2;
+ 0x2292; 0x22E3; 0x22A2; 0x22AC; 0x22A8; 0x22AD; 0x22A9; 0x22AE;
+ 0x22AB; 0x22AF; 0x22B2; 0x22EA; 0x22B3; 0x22EB; 0x22B4; 0x22EC;
+ 0x22B5; 0x22ED; 0x00A8; 0x1FC1; 0x03B1; 0x1FB6; 0x03B7; 0x1FC6;
+ 0x03B9; 0x1FD6; 0x03C5; 0x1FE6; 0x03C9; 0x1FF6; 0x03CA; 0x1FD7;
+ 0x03CB; 0x1FE7; 0x1F00; 0x1F06; 0x1F01; 0x1F07; 0x1F08; 0x1F0E;
+ 0x1F09; 0x1F0F; 0x1F20; 0x1F26; 0x1F21; 0x1F27; 0x1F28; 0x1F2E;
+ 0x1F29; 0x1F2F; 0x1F30; 0x1F36; 0x1F31; 0x1F37; 0x1F38; 0x1F3E;
+ 0x1F39; 0x1F3F; 0x1F50; 0x1F56; 0x1F51; 0x1F57; 0x1F59; 0x1F5F;
+ 0x1F60; 0x1F66; 0x1F61; 0x1F67; 0x1F68; 0x1F6E; 0x1F69; 0x1F6F;
+ 0x1FBF; 0x1FCF; 0x1FFE; 0x1FDF; 0x0391; 0x1FBC; 0x0397; 0x1FCC;
+ 0x03A9; 0x1FFC; 0x03AC; 0x1FB4; 0x03AE; 0x1FC4; 0x03B1; 0x1FB3;
+ 0x03B7; 0x1FC3; 0x03C9; 0x1FF3; 0x03CE; 0x1FF4; 0x1F00; 0x1F80;
+ 0x1F01; 0x1F81; 0x1F02; 0x1F82; 0x1F03; 0x1F83; 0x1F04; 0x1F84;
+ 0x1F05; 0x1F85; 0x1F06; 0x1F86; 0x1F07; 0x1F87; 0x1F08; 0x1F88;
+ 0x1F09; 0x1F89; 0x1F0A; 0x1F8A; 0x1F0B; 0x1F8B; 0x1F0C; 0x1F8C;
+ 0x1F0D; 0x1F8D; 0x1F0E; 0x1F8E; 0x1F0F; 0x1F8F; 0x1F20; 0x1F90;
+ 0x1F21; 0x1F91; 0x1F22; 0x1F92; 0x1F23; 0x1F93; 0x1F24; 0x1F94;
+ 0x1F25; 0x1F95; 0x1F26; 0x1F96; 0x1F27; 0x1F97; 0x1F28; 0x1F98;
+ 0x1F29; 0x1F99; 0x1F2A; 0x1F9A; 0x1F2B; 0x1F9B; 0x1F2C; 0x1F9C;
+ 0x1F2D; 0x1F9D; 0x1F2E; 0x1F9E; 0x1F2F; 0x1F9F; 0x1F60; 0x1FA0;
+ 0x1F61; 0x1FA1; 0x1F62; 0x1FA2; 0x1F63; 0x1FA3; 0x1F64; 0x1FA4;
+ 0x1F65; 0x1FA5; 0x1F66; 0x1FA6; 0x1F67; 0x1FA7; 0x1F68; 0x1FA8;
+ 0x1F69; 0x1FA9; 0x1F6A; 0x1FAA; 0x1F6B; 0x1FAB; 0x1F6C; 0x1FAC;
+ 0x1F6D; 0x1FAD; 0x1F6E; 0x1FAE; 0x1F6F; 0x1FAF; 0x1F70; 0x1FB2;
+ 0x1F74; 0x1FC2; 0x1F7C; 0x1FF2; 0x1FB6; 0x1FB7; 0x1FC6; 0x1FC7;
+ 0x1FF6; 0x1FF7; 0x0627; 0x0622; 0x0627; 0x0623; 0x0648; 0x0624;
+ 0x064A; 0x0626; 0x06C1; 0x06C2; 0x06D2; 0x06D3; 0x06D5; 0x06C0;
+ 0x0627; 0x0625; 0x0928; 0x0929; 0x0930; 0x0931; 0x0933; 0x0934;
+ 0x09C7; 0x09CB; 0x09C7; 0x09CC; 0x0B47; 0x0B4B; 0x0B47; 0x0B48;
+ 0x0B47; 0x0B4C; 0x0BC6; 0x0BCA; 0x0BC7; 0x0BCB; 0x0B92; 0x0B94;
+ 0x0BC6; 0x0BCC; 0x0C46; 0x0C48; 0x0CC6; 0x0CCA; 0x0CBF; 0x0CC0;
+ 0x0CC6; 0x0CC7; 0x0CCA; 0x0CCB; 0x0CC6; 0x0CC8; 0x0D46; 0x0D4A;
+ 0x0D47; 0x0D4B; 0x0D46; 0x0D4C; 0x0DD9; 0x0DDA; 0x0DDC; 0x0DDD;
+ 0x0DD9; 0x0DDC; 0x0DD9; 0x0DDE; 0x1025; 0x1026; 0x3046; 0x3094;
+ 0x304B; 0x304C; 0x304D; 0x304E; 0x304F; 0x3050; 0x3051; 0x3052;
+ 0x3053; 0x3054; 0x3055; 0x3056; 0x3057; 0x3058; 0x3059; 0x305A;
+ 0x305B; 0x305C; 0x305D; 0x305E; 0x305F; 0x3060; 0x3061; 0x3062;
+ 0x3064; 0x3065; 0x3066; 0x3067; 0x3068; 0x3069; 0x306F; 0x3070;
+ 0x3072; 0x3073; 0x3075; 0x3076; 0x3078; 0x3079; 0x307B; 0x307C;
+ 0x309D; 0x309E; 0x30A6; 0x30F4; 0x30AB; 0x30AC; 0x30AD; 0x30AE;
+ 0x30AF; 0x30B0; 0x30B1; 0x30B2; 0x30B3; 0x30B4; 0x30B5; 0x30B6;
+ 0x30B7; 0x30B8; 0x30B9; 0x30BA; 0x30BB; 0x30BC; 0x30BD; 0x30BE;
+ 0x30BF; 0x30C0; 0x30C1; 0x30C2; 0x30C4; 0x30C5; 0x30C6; 0x30C7;
+ 0x30C8; 0x30C9; 0x30CF; 0x30D0; 0x30D2; 0x30D3; 0x30D5; 0x30D6;
+ 0x30D8; 0x30D9; 0x30DB; 0x30DC; 0x30EF; 0x30F7; 0x30F0; 0x30F8;
+ 0x30F1; 0x30F9; 0x30F2; 0x30FA; 0x30FD; 0x30FE; 0x306F; 0x3071;
+ 0x3072; 0x3074; 0x3075; 0x3077; 0x3078; 0x307A; 0x307B; 0x307D;
+ 0x30CF; 0x30D1; 0x30D2; 0x30D4; 0x30D5; 0x30D7; 0x30D8; 0x30DA;
+ 0x30DB; 0x30DD
+|]
+
+let uniCharCombiningBitmap = "\
+\x00\x00\x00\x01\x02\x03\x04\x05\
+\x00\x06\x07\x08\x09\x0A\x0B\x0C\
+\x0D\x14\x00\x00\x00\x00\x00\x0E\
+\x0F\x00\x00\x00\x00\x00\x00\x00\
+\x10\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x11\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x12\x00\x00\x13\x00\
+\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
+\xFF\xFF\x00\x00\xFF\xFF\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x78\x03\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\xFE\xFF\xFB\xFF\xFF\xBB\
+\x16\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\xF8\x3F\x00\x00\x00\x01\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\xC0\xFF\x9F\x3D\x00\x00\
+\x00\x00\x02\x00\x00\x00\xFF\xFF\
+\xFF\x07\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\xC0\xFF\x01\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x0E\x00\x00\x00\x00\x00\x00\xD0\
+\xFF\x3F\x1E\x00\x0C\x00\x00\x00\
+\x0E\x00\x00\x00\x00\x00\x00\xD0\
+\x9F\x39\x80\x00\x0C\x00\x00\x00\
+\x04\x00\x00\x00\x00\x00\x00\xD0\
+\x87\x39\x00\x00\x00\x00\x03\x00\
+\x0E\x00\x00\x00\x00\x00\x00\xD0\
+\xBF\x3B\x00\x00\x00\x00\x00\x00\
+\x0E\x00\x00\x00\x00\x00\x00\xD0\
+\x8F\x39\xC0\x00\x00\x00\x00\x00\
+\x04\x00\x00\x00\x00\x00\x00\xC0\
+\xC7\x3D\x80\x00\x00\x00\x00\x00\
+\x0E\x00\x00\x00\x00\x00\x00\xC0\
+\xDF\x3D\x60\x00\x00\x00\x00\x00\
+\x0C\x00\x00\x00\x00\x00\x00\xC0\
+\xDF\x3D\x60\x00\x00\x00\x00\x00\
+\x0C\x00\x00\x00\x00\x00\x00\xC0\
+\xCF\x3D\x80\x00\x00\x00\x00\x00\
+\x0C\x00\x00\x00\x00\x00\x00\x00\
+\x00\x84\x5F\xFF\x00\x00\x0C\x00\
+\x00\x00\x00\x00\x00\x00\xF2\x07\
+\x80\x7F\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\xF2\x1B\
+\x00\x3F\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x03\x00\x00\xA0\xC2\
+\x00\x00\x00\x00\x00\x00\xFE\xFF\
+\xDF\x00\xFF\xFE\xFF\xFF\xFF\x1F\
+\x40\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\xF0\xC7\x03\
+\x00\x00\xC0\x03\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x1C\x00\x00\x00\x1C\x00\
+\x00\x00\x0C\x00\x00\x00\x0C\x00\
+\x00\x00\x00\x00\x00\x00\xF0\xFF\
+\xFF\xFF\x0F\x00\x00\x00\x00\x00\
+\x00\x38\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\xFF\xFF\xFF\x07\x00\x00\
+\x00\x00\x00\x00\x00\xFC\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x06\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x40\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\xFF\xFF\x00\x00\x0F\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\xFE\xFF\x3F\x00\
+\x00\x00\x00\x00\x00\xFF\xFF\xFF\
+\x07\x00\x00\x00\x00\x00\x00\x00"
+
+(****)
+
+let bitmap_test base bitmap character =
+ character >= base && character < 0x10000
+ &&
+ (let value = get bitmap ((character lsr 8) land 0xFF) in
+ value = 0xFF
+ ||
+ (value <> 0
+ &&
+ get bitmap ((value - 1) * 32 + 256 + (character land 0xFF) / 8)
+ land (1 lsl (character land 7)) <> 0))
+
+let unicode_combinable character =
+ bitmap_test 0x0300 uniCharCombiningBitmap character
+
+let rec find_rec t i j v =
+ if i + 1 = j then begin
+ if t.(i * 2) = v then t.(i * 2 + 1) else 0
+ end else begin
+ let k = (i + j) / 2 in
+ if v < t.(k * 2) then
+ find_rec t i k v
+ else
+ find_rec t k j v
+ end
+
+let find t i n v =
+ let j = i + n in
+ if v < t.(2 * i) || v > t.(2 * (j - 1)) then 0 else
+ find_rec t i j v
+
+let uniCharPrecompSourceTableLen = Array.length uniCharPrecompSourceTable / 2
+
+let combine v v' =
+ if v' >= hangul_vbase && v' < hangul_tbase + hangul_tcount then begin
+ if
+ v' < hangul_vbase + hangul_vcount &&
+ v >= hangul_lbase && v < hangul_lbase + hangul_lcount
+ then
+ hangul_sbase + ((v - hangul_lbase) * (hangul_vcount * hangul_tcount)) +
+ ((v' - hangul_vbase) * hangul_tcount)
+ else if
+ v' > hangul_tbase &&
+ v >= hangul_sbase && v < hangul_sbase + hangul_scount
+ then
+ if (v - hangul_sbase) mod hangul_tcount <> 0 then 0 else
+ v + v' - hangul_tbase
+ else
+ 0
+ end else begin
+ let k =
+ find uniCharPrecompSourceTable 0
+ uniCharPrecompSourceTableLen v'
+ in
+ if k = 0 then 0 else
+ find uniCharBMPPrecompDestinationTable (k land 0xFFFF) (k lsr 16) v
+ end
+
+(****)
+
+let rec scan d s i l =
+ if i < l then begin
+ let c = get s i in
+ if c < 0x80 then
+ cont d s i l (i + 1) c
+ else if c < 0xE0 then begin
+ (* 80 - 7FF *)
+ if c < 0xc2 || i + 1 >= l then fail () else
+ let c1 = get s (i + 1) in
+ if c1 land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 6 + c1 - 0x3080 in
+ cont d s i l (i + 2) v
+ end else if c < 0xF0 then begin
+ (* 800 - FFFF *)
+ if i + 2 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ if (c1 lor c2) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 12 + c1 lsl 6 + c2 - 0xe2080 in
+ if v < 0x800 then fail () else
+ cont d s i l (i + 3) v
+ end else begin
+ (* 10000 - 10FFFF *)
+ if i + 3 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ let c3 = get s (i + 3) in
+ if (c1 lor c2 lor c3) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 18 + c1 lsl 12 + c2 lsl 6 + c3 - 0x03c82080 in
+ if v < 0x10000 || v > 0x10ffff then fail () else
+ cont d s i l (i + 4) v
+ end
+ end else begin
+ let (i1, i2) = d in
+ String.blit s i2 s i1 (l - i2);
+ String.sub s 0 (i1 + l - i2)
+ end
+
+and cont d s i l j v' =
+ if unicode_combinable v' then begin
+ let i = prev_char s i in
+ let (v, _) = decode_char s i l in
+ let v'' = combine v v' in
+ if v'' = 0 then
+ scan d s j l
+ else begin
+ let (i1, i2) = d in
+ String.blit s i2 s i1 (i - i2);
+ let i1 = i1 + i - i2 in
+ let (v'', i) = compose_rec s j l v'' in
+ let i1 = encode_char s i1 l v'' in
+ scan (i1, i) s i l
+ end
+ end else
+ scan d s j l
+
+and compose_rec s i l v =
+ try
+ let (v', j) = decode_char s i l in
+ if unicode_combinable v' then begin
+ let v'' = combine v v' in
+ if v'' = 0 then
+ (v, i)
+ else
+ compose_rec s j l v''
+ end else
+ (v, i)
+ with Invalid ->
+ (v, i)
+
+let compose s =
+ try scan (0, 0) (String.copy s) 0 (String.length s) with Invalid -> s
+
+(***)
+
+let set_2 s i v =
+ set s i (v land 0xff);
+ set s (i + 1) (v lsr 8)
+
+let get_2 s i = (get s (i + 1)) lsl 8 + get s i
+
+let rec scan s' j s i l =
+ if i < l then begin
+ let c = get s i in
+ if c < 0x80 then
+ cont s' j s (i + 1) l c
+ else if c < 0xE0 then begin
+ (* 80 - 7FF *)
+ if c < 0xc2 || i + 1 >= l then fail () else
+ let c1 = get s (i + 1) in
+ if c1 land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 6 + c1 - 0x3080 in
+ cont s' j s (i + 2) l v
+ end else if c < 0xF0 then begin
+ (* 800 - FFFF *)
+ if i + 2 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ if (c1 lor c2) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 12 + c1 lsl 6 + c2 - 0xe2080 in
+ if v < 0x800 then fail () else
+ cont s' j s (i + 3) l v
+ end else begin
+ (* 10000 - 10FFFF *)
+ if i + 3 >= l then fail () else
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ let c3 = get s (i + 3) in
+ if (c1 lor c2 lor c3) land 0xc0 <> 0x80 then fail () else
+ let v = c lsl 18 + c1 lsl 12 + c2 lsl 6 + c3 - 0x03c82080 in
+ if v < 0x10000 || v > 0x10ffff then fail () else
+ cont s' j s (i + 4) l v
+ end
+ end else
+ String.sub s' 0 j
+
+and cont s' j s i l v =
+ if v < 0x10000 then begin
+ set_2 s' j v;
+ scan s' (j + 2) s i l
+ end else begin
+ let v = v - 0x10000 in
+ set_2 s' j (v lsr 10 + 0xD800);
+ set_2 s' (j + 2) (v land 0x3FF + 0xDC00);
+ scan s' (j + 4) s i l
+ end
+
+let to_utf_16 s =
+ let l = String.length s in
+ let s' = String.create (2 * l) in
+ scan s' 0 s 0 l
+
+(****)
+
+let rec scan s' i' l' s i l =
+ if i + 2 <= l then begin
+ let v = get_2 s i in
+ if v < 0xD800 || v > 0xDFFF then
+ let i' = encode_char s' i' l' v in
+ scan s' i' l' s (i + 2) l
+ else if v >= 0xdc00 || i + 4 > l then
+ fail ()
+ else begin
+ let v' = get_2 s (i + 2) in
+ if v' < 0xDC00 || v' > 0XDFFF then fail () else
+ let i' =
+ encode_char s' i' l' ((v - 0xD800) lsl 10 + (v' - 0xDC00) + 0x10000)
+ in
+ scan s' i' l' s (i + 4) l
+ end
+ end else if i < l then
+ fail ()
+ else
+ String.sub s' 0 i'
+
+let from_utf_16 s =
+ let l = String.length s in
+ let l' = 3 * l / 2 in
+ let s' = String.create l' in
+ scan s' 0 l' s 0 l
+
+(****)
+
+let rec scan s i l =
+ i = l ||
+ let c = get s i in
+ if c < 0x80 then
+ scan s (i + 1) l
+ else if c < 0xE0 then begin
+ (* 80 - 7FF *)
+ c >= 0xc2 && i + 1 < l &&
+ let c1 = get s (i + 1) in
+ c1 land 0xc0 = 0x80 &&
+ scan s (i + 2) l
+ end else if c < 0xF0 then begin
+ (* 800 - FFFF *)
+ i + 2 < l &&
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ (c1 lor c2) land 0xc0 = 0x80 &&
+ let v = c lsl 12 + c1 lsl 6 + c2 - 0xe2080 in
+ v >= 0x800 &&
+ scan s (i + 3) l
+ end else begin
+ (* 10000 - 10FFFF *)
+ i + 3 < l &&
+ let c1 = get s (i + 1) in
+ let c2 = get s (i + 2) in
+ let c3 = get s (i + 3) in
+ (c1 lor c2 lor c3) land 0xc0 = 0x80 &&
+ let v = c lsl 18 + c1 lsl 12 + c2 lsl 6 + c3 - 0x03c82080 in
+ v >= 0x10000 && v < 0x10ffff &&
+ scan s (i + 4) l
+ end
+
+let check_utf_8 s = scan s 0 (String.length s)
Added: trunk/src/unicode.mli
===================================================================
--- trunk/src/unicode.mli (rev 0)
+++ trunk/src/unicode.mli 2009-05-04 18:48:23 UTC (rev 326)
@@ -0,0 +1,23 @@
+(* Unison file synchronizer: src/unicode.mli *)
+(* Copyright 1999-2009, Benjamin C. Pierce (see COPYING for details) *)
+
+
+(* Case-insensitive comparison. If two strings are equal according to
+ Mac OS X (Darwin, actually, but the algorithm has hopefully
+ remained unchanged) or Windows (Samba), then this function returns 0 *)
+val compare : string -> string -> int
+
+(* Corresponding normalization *)
+val normalize : string -> string
+
+(* Compose Unicode strings. This reverts the decomposition performed
+ by Mac OS X. *)
+val compose : string -> string
+
+(* Convert to and from little-endian UTF-16 encoding *)
+(*XXX What about null-termination? *)
+val to_utf_16 : string -> string
+val from_utf_16 : string -> string
+
+(* Check wether the string contains only well-formed UTF-8 characters *)
+val check_utf_8 : string -> bool
Added: trunk/src/unicode_tables.ml
===================================================================
--- trunk/src/unicode_tables.ml (rev 0)
+++ trunk/src/unicode_tables.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -0,0 +1,11 @@
+(*-*-coding: utf-8;-*-*)
+let ascii_lower =
+ "\000\001\002\003\004\005\006\007\008\t\n\011\012\013\014\015\016\017\018\019\020\021\022\023\024\025\026\027\028\029\030\031 !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127"
+let norm_repl =
+ "\003aÌ\003aÌ\003aÌ\003aÌ\003aÌ\003aÌ\002æ\003ç\003eÌ\003eÌ\003eÌ\003eÌ\003iÌ\003iÌ\003iÌ\003iÌ\002ð\003nÌ\003oÌ\003oÌ\003oÌ\003oÌ\003oÌ\002ø\003uÌ\003uÌ\003uÌ\003uÌ\003yÌ\002þ\003yÌ\003aÌ\003aÌ\003ą\003cÌ\003cÌ\003cÌ\003cÌ\003dÌ\002Ä\003eÌ\003eÌ\003eÌ\003ę\003eÌ\003gÌ\003gÌ\003gÌ\003ģ\003hÌ\002ħ\003iÌ\003iÌ\003iÌ\003į\003iÌ\002ij\003jÌ\003ķ\003lÌ\003ļ\003lÌ\002Å\002Å\003nÌ\003ņ\003nÌ\002Å\003oÌ\003oÌ\003oÌ\002Å\003rÌ\003ŗ\003rÌ\003sÌ\003sÌ\003ş\003sÌ\003ţ\003tÌ\002ŧ\003uÌ\003uÌ\003uÌ\003uÌ\003uÌ\003ų\003wÌ\003yÌ\003zÌ\003zÌ\003zÌ\002É\002Æ\002Æ
\002É\002Æ\002É\002É\002Æ\002Ç\002É\002É\002Æ\002É \002É£\002É©\002ɨ\002Æ\002ɯ\002ɲ\002ɵ\003oÌ\002Æ£\002Æ¥\002ƨ\002Ê\002Æ\002Ê\003uÌ\002Ê\002Ê\002Æ´\002ƶ\002Ê\002ƹ\002ƽ\002Ç\002Ç\002Ç\003aÌ\003iÌ\003oÌ\003uÌ\005uÌÌ\005uÌÌ\005uÌÌ\005uÌÌ\005aÌÌ\005aÌÌ\004æÌ\002Ç¥\003gÌ\003kÌ\003oÌ!
¨\005ǫÌ\004ÊÌ\003jÌ\002dz\003gÌ\003nÌ\005aÌÌ\004æÌ\004øÌ\003aÌ\003aÌ\003eÌ\003eÌ\003iÌ\003iÌ\003oÌ\003oÌ\003rÌ\003rÌ\003uÌ\003uÌ\003ș\003ț\003hÌ\003aÌ\003ȩ\005oÌÌ\005oÌÌ\003oÌ\005oÌÌ\003yÌ\002Ì\002Ì\002Ì\004ÌÌ\002ʹ\001;\004¨Ì\004αÌ\002·\004εÌ\004ηÌ\004ιÌ\004οÌ\004Ï
Ì\004ÏÌ\006ιÌÌ\002α\002β\002γ\002δ\002ε\002ζ\002η\002θ\002ι\002κ\002λ\002μ\002ν\002ξ\002ο\002Ï\002Ï\002Ï\002Ï\002Ï
\002Ï\002Ï\002Ï\002Ï\004ιÌ\004Ï
Ì\006Ï
ÌÌ\004ÏÌ\004ÏÌ\002Ï£\002Ï¥\002ϧ\002Ï©\002Ï«\002Ï\002ϯ\004еÌ\004еÌ\002Ñ\004гÌ\002Ñ\002Ñ\002Ñ\004ÑÌ\002Ñ\002Ñ\002Ñ\002Ñ\004кÌ\004иÌ\004ÑÌ\002Ñ\002а\002б\002в\002г\002д\002е\002ж\002з\002и\004иÌ\002к\002л\002м\002н\002о\002п\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ
\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ\002Ñ¡\002Ñ£\002Ñ¥\002ѧ\002Ñ©\002Ñ«\002Ñ\002ѯ\002ѱ\002ѳ\002ѵ\004ѵÌ\002ѹ\002Ñ»\002ѽ\002Ñ¿\002Ò\002Ò!
\002Ò\002Ò\002Ò\002Ò\002Ò\002Ò\002Ò\002Ò¡\002Ò£\002Ò¥\!
002Ò§\00
2Ò©\002Ò«\002Ò\002Ò¯\002Ò±\002Ò³\002Òµ\002Ò·\002Ò¹\002Ò»\002Ò½\002Ò¿\004жÌ\002Ó\002Ó\002Ó\004аÌ\004аÌ\002Ó\004еÌ\002Ó\004ÓÌ\004жÌ\004зÌ\002Ó¡\004иÌ\004иÌ\004оÌ\002Ó©\004Ó©Ì\004ÑÌ\004ÑÌ\004ÑÌ\004ÑÌ\004ÑÌ\004ÑÌ\002Õ¡\002Õ¢\002Õ£\002Õ¤\002Õ¥\002Õ¦\002Õ§\002Õ¨\002Õ©\002Õª\002Õ«\002Õ¬\002Õ\002Õ®\002Õ¯\002Õ°\002Õ±\002Õ²\002Õ³\002Õ´\002Õµ\002Õ¶\002Õ·\002Õ¸\002Õ¹\002Õº\002Õ»\002Õ¼\002Õ½\002Õ¾\002Õ¿\002Ö\002Ö\002Ö\002Ö\002Ö\002Ö
\002Ö\004اÙ\004اÙ\004ÙÙ\004اÙ\004ÙÙ\004ÛÙ\004ÛÙ\004ÛÙ\006ऩ\006ऱ\006ऴ\006à¤à¤¼\006à¤à¤¼\006à¤à¤¼\006à¤à¤¼\006ड़\006ढ़\006फ़\006य़\006à§à¦¾\006à§à§\006ড়\006ঢ়\006য়\006ਲ਼\006ਸ਼\006à¨à¨¼\006à¨à¨¼\006à¨à¨¼\006ਫ਼\006àà\006àା\006àà\006ଡ଼\006ଢ଼\006à®à¯\006à¯à®¾\006à¯à®¾\006à¯à¯\006à±à±\006ಿà³\006à³à³\006à³à³\006à³à³\009à³à³à³\006àµà´¾\006àµà´¾\006àµàµ\006à·à·\006à·à·\009à·à·à·\006à·à·\006!
à½à¾·\006à½à¾·\006à½à¾·\006à½à¾·\006à½à¾·\006à½à¾µ\006ཱི\006ཱུ\006ྲà¾\006ླà¾\006ཱà¾\006à¾à¾·\006à¾à¾·\006ྡྷ\006ྦྷ\006ྫྷ\006à¾à¾µ\006á¥á®\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á\003á \003á¡\003á¢\003á£\003á¤\003á¥\003á¦\003á§\003á¨\003á©\003áª\003á«\003á¬\003á\003á®\003á¯\003á°\003á±\003á²\003á³\003á´\003áµ\003aÌ¥\003bÌ\003bÌ£\003ḇ\005çÌ\003dÌ\003dÌ£\003ḏ\003ḑ\003dÌ\005eÌÌ\005eÌÌ\003eÌ\003eÌ°\005ȩÌ\003fÌ\003gÌ\003hÌ\003hÌ£\003hÌ\003ḩ\003hÌ®\003iÌ°\005iÌÌ\003kÌ\003kÌ£\003ḵ\003lÌ£\005lÌ£Ì\003ḻ\003lÌ\003mÌ\003mÌ\003mÌ£\003nÌ\003nÌ£\003ṉ\003nÌ\005oÌÌ\005oÌÌ\005oÌÌ\005oÌÌ\003pÌ\003pÌ\003rÌ\003rÌ£\005rÌ£Ì\003ṟ\003sÌ\003sÌ£\005sÌÌ\005sÌÌ\005sÌ£Ì\003tÌ\003tÌ£\003ṯ\003tÌ\003ṳ\003uÌ°\003uÌ\005uÌÌ\005uÌÌ\003vÌ\003vÌ£\003wÌ\003wÌ\003wÌ\003wÌ\003wÌ£\003xÌ\003xÌ\003yÌ\003zÌ\00!
3zÌ£\003ẕ\003ẖ\003tÌ\003wÌ\003yÌ\004Å¿Ì\003aÌ£\003aÌ\!
005aÌÌ
\005aÌÌ\005aÌÌ\005aÌÌ\005aÌ£Ì\005aÌÌ\005aÌÌ\005aÌÌ\005aÌÌ\005aÌ£Ì\003eÌ£\003eÌ\003eÌ\005eÌÌ\005eÌÌ\005eÌÌ\005eÌÌ\005eÌ£Ì\003iÌ\003iÌ£\003oÌ£\003oÌ\005oÌÌ\005oÌÌ\005oÌÌ\005oÌÌ\005oÌ£Ì\005oÌÌ\005oÌÌ\005oÌÌ\005oÌÌ\005oÌÌ£\003uÌ£\003uÌ\005uÌÌ\005uÌÌ\005uÌÌ\005uÌÌ\005uÌÌ£\003yÌ\003yÌ£\003yÌ\003yÌ\004αÌ\004αÌ\006αÌÌ\006αÌÌ\006αÌÌ\006αÌÌ\006αÌÍ\006αÌÍ\004εÌ\004εÌ\006εÌÌ\006εÌÌ\006εÌÌ\006εÌÌ\004ηÌ\004ηÌ\006ηÌÌ\006ηÌÌ\006ηÌÌ\006ηÌÌ\006ηÌÍ\006ηÌÍ\004ιÌ\004ιÌ\006ιÌÌ\006ιÌÌ\006ιÌÌ\006ιÌÌ\006ιÌÍ\006ιÌÍ\004οÌ\004οÌ\006οÌÌ\006οÌÌ\006οÌÌ\006οÌÌ\004Ï
Ì\004Ï
Ì\006Ï
ÌÌ\006Ï
ÌÌ\006Ï
ÌÌ\006Ï
ÌÌ\006Ï
ÌÍ\006Ï
ÌÍ\004ÏÌ\004ÏÌ\006ÏÌÌ\006ÏÌÌ\006ÏÌÌ\006ÏÌÌ\006ÏÌÍ\006ÏÌÍ\004αÌ\004εÌ\004ηÌ\004ιÌ\004οÌ\004Ï
Ì\004ÏÌ\006αÌÍ
\006αÌÍ
\008αÌÌÍ
\008αÌÌÍ
\008αÌÌÍ
\008αÌÌÍ
\008αÌÍÍ
\008αÌÍ!
Í
\006ηÌÍ
\006ηÌÍ
\008ηÌÌÍ
\008ηÌÌÍ
\008ηÌÌÍ
\008ηÌÌÍ
\008ηÌÍÍ
\008ηÌÍÍ
\006ÏÌÍ
\006ÏÌÍ
\008ÏÌÌÍ
\008ÏÌÌÍ
\008ÏÌÌÍ
\008ÏÌÌÍ
\008ÏÌÍÍ
\008ÏÌÍÍ
\004αÌ\004αÌ\006αÌÍ
\004αÍ
\006αÌÍ
\004αÍ\006αÍÍ
\004¨Í\006ηÌÍ
\004ηÍ
\006ηÌÍ
\004ηÍ\006ηÍÍ
\005᾿Ì\005᾿Ì\005᾿Í\004ιÌ\004ιÌ\006ιÌÌ\004ιÍ\006ιÌÍ\005῾Ì\005῾Ì\005῾Í\004Ï
Ì\004Ï
Ì\006Ï
ÌÌ\004ÏÌ\004ÏÌ\004Ï
Í\006Ï
ÌÍ\004¨Ì\001`\006ÏÌÍ
\004ÏÍ
\006ÏÌÍ
\004ÏÍ\006ÏÍÍ
\002´\000\003â
°\003â
±\003â
²\003â
³\003â
´\003â
µ\003â
¶\003â
·\003â
¸\003â
¹\003â
º\003â
»\003â
¼\003â
½\003â
¾\003â
¿\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â\003â \003â¡\003â¢\003â£\003â¤\003â¥\003â¦\003â§\003â¨\003â©\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ã¡ã\006ã¤ã\006ã¦ã\006ã¨ã\006ã¯ã\006!
ã¯ã\006ã²ã\006ã²ã\006ãµã\006ãµã\006ã¸ã\006ã!
¸ã\006
ã»ã\006ã»ã\006ãã\006ãã\006ã«ã\006ãã\006ã¯ã\006ã±ã\006ã³ã\006ãµã\006ã·ã\006ã¹ã\006ã»ã\006ã½ã\006ã¿ã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ãã\006ã¦ã\006ã¯ã\006ã°ã\006ã±ã\006ã²ã\006ã½ã\004×Ö´\004ײַ\004ש×\004ש×\006שּ×\006שּ×\004×Ö·\004×Ö¸\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004×Ö¼\004× Ö¼\004סּ\004×£Ö¼\004פּ\004צּ\004קּ\004רּ\004שּ\004תּ\004×Ö¹\004×Ö¿\004×Ö¿\004פֿ\003ï½\003ï½\003ï½\003ï½\003ï½
\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½\003ï½"
+let norm_prim =
+ "\000\000\000\002\003\004\005\006\007\000\000\000\000\008\009\010\011\012\013\014\015\016\000\000\017\000\000\018\000\000\000\000\000\000\000\000\019\020\000\021\022\023\000\000\000\024\025\026\000\027\000\028\000\029\000\030\000\000\000\000\000\031\032\000\033\000\034\035\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\036\037\038\039\040\041\042\043\044\045\000\000\000\046\000\000\000\000\000\000\000\000\000\000\000\000\047\048\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\049\050\051\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00!
0\000\00
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001!
\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\052!
\053\000\000\000\000\000\000\000\000\000\000\000\000\000\054\0!
55\000\0
00\000"
+let norm_second_high =
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\000\002\002\002\002\002\002\002\000\002\002\002\002\002\002\000\002\002\002\002\002\002\002\002\002\000\002\002\002\002\002\002\000\000\002\002\002\002\002\000\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\000\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\000\002\002\002\002\002\002\002\002\002\000\002\000\002\002\!
002\002\000\002\002\002\002\002\002\002\000\002\000\002\002\002\002\002\002\000\003\000\003\003\003\003\003\003\003\000\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\000\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\002\003\003\003\003\003\003\000\000\003\003\000\003\000\003\003\000\003\003\003\000\000\003\003\003\003\000\003\003\000\003\003\003\000\000\000\003\003\000\003\003\003\003\000\003\000\000\003\000\003\000\000\003\000\003\003\003\003\003\003\000\003\000\003\003\000\000\000\003\000\000\000\000\000\000\000\003\003\000\003\003\000\003\003\000\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\003\000\004\004\004\004\004\004\004\000\004\004\004\004\004\004\004\004\004\004\004\004\004\000\004\004\000\000\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\004\000\000\004\004\000\000\000\000\000\000\004\004\004\004\004\004\004\!
004\004\004\004\004\004\004\000\000\000\000\000\000\000\000\00!
0\000\00
0\000\004\004\000\004\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\004\004\004\004\004\004\000\004\000\004\004\004\004\004\004\004\004\005\005\005\005\005\005\005\005\005\005\005\005\000\005\005\005\005\005\005\005\005\005\004\004\004\004\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\005\005\004\004\004\000\000\000\000\005\005\000\000\000\000\000\000\000\000\000\000\000\000\000\005\000\005\000\005\000\005\000\005\000\005\000\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\006\006\006\000\000\000\000\000\000!
\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\005\000\005\000\000\000\005\000\000\000\000\005\005\005\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\006\006\000\006\000\006\000\006\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\006\000\000\006\006\006\000\000\000\006\000\000\000\006\000\000\000\000\006\006\006\006\006\000\006\006\006\000\006\006\006\006\006\006\006\000\006\006\006\006\006\006\006\000\006\006\006\006\006\006\006\006\006\006\006\006\000\000\006\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!
\000\000\000\000\006\006\006\006\006\006\007\007\007\007\007\0!
07\007\0
07\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\007\007\007\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\000\000\000\000\000\000\000\007\000\000\007\00!
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\007\007\007\007\007\007\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\007\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\008\008\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\00!
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\
000\000\000\000\000\000\000\000\000\000\008\000\000\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0!
00\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\008\008\000\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\008\008\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\000\000\000\000\008\000\000\000\000\008\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\0!
00\000\000\000\000\000\000\008\000\008\008\000\009\000\000\000!
\000\000
\000\000\000\009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\009\000\000\000\000\000\000\000\000\000\009\000\000\000\000\009\000\000\000\000\009\000\000\000\000\009\000\000\000\000\000\000\000\000\000\000\000\000\009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\000\000\000\000\000\000\000\000\000\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\010\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\000\011\000\000\000\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\012\012\!
012\012\012\012\012\012\012\012\012\012\012\012\012\012\000\00!
0\000\00
0\000\000\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\000\000\012\012\012\012\012\012\000\000\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\013\013\000\000\012\012\012\012\013\013\000\000\013\013\013\013\013\013\013\013\000\013\000\013\000\013\000\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\004\013\004\013\004\013\004\013\004\013\004\013\004\000\000\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\013\014\014\014\014\013\013\013\013\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\014\000\014\014\014\014\013\004\014\000\005\000\000\014\014\014\014\000\014\014\013\004\013\004\014\014\014\014\014\014\014\004\000\000\014\014\014\014\013\004\000\014\014\014\014\014\015\005\015\015\015\015\014\014\013\004\015\015\004\015\000\000\015\015\015!
\000\015\015\013\004\013\004\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\015\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\015\015\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\015\015\015\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!
\000\000\000\000\000\000\000\000\000\000\015\015\015\015\015\0!
15\015\0
15\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\000\015\000\015\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\000\016\000\016\000\016\000\000\000\000\000\000\016\016\000\016\016\000\016\016\000\016\016\000\016\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\016\000\000\017\000\017\000\017\000\000\000\000\000\000\017\017\000\017\017\000\017\017\000\017\017\000\017\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\01!
7\000\000\017\017\017\017\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\017\000\000\000\000\000\000\000\000\000\000\017\017\017\017\017\017\017\017\017\017\017\017\017\000\017\017\017\017\017\000\017\000\017\017\000\017\018\000\018\018\018\018\018\018\018\018\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\018\018\018\018\018\018\018\018\018\01!
8\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\!
000\000\
000\000\000"
+let norm_second_low =
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\008\012\016\020\024\027\031\035\039\043\047\051\055\059\063\066\070\074\078\082\086\000\090\093\097\101\105\109\113\000\000\004\008\012\016\020\000\027\031\035\039\043\047\051\055\059\000\066\070\074\078\082\086\000\000\093\097\101\105\109\000\116\120\120\124\124\128\128\132\132\136\136\140\140\144\144\148\148\152\000\155\155\159\159\163\163\167\167\171\171\175\175\179\179\183\183\187\187\191\191\195\000\198\198\202\202\206\206\210\210\214\000\218\000\221\221\!
225\225\000\229\229\233\233\237\237\241\000\244\000\247\247\251\251\255\255\000\003\000\006\006\010\010\014\014\018\000\021\021\025\025\029\029\033\033\037\037\041\041\045\045\049\049\053\053\057\000\060\060\064\064\068\068\072\072\076\076\080\080\084\084\088\088\116\092\092\096\096\100\100\000\000\104\107\000\110\000\113\116\000\119\122\125\000\000\128\131\134\137\000\140\143\000\146\149\152\000\000\000\155\158\000\161\164\164\168\000\171\000\000\174\000\177\000\000\180\000\183\186\186\190\193\196\000\199\000\202\205\000\000\000\208\000\000\000\000\000\000\000\211\211\000\214\214\000\217\217\000\220\220\224\224\228\228\232\232\236\236\242\242\248\248\254\254\000\004\004\010\010\016\016\021\000\024\024\028\028\032\032\036\036\042\042\047\051\051\000\054\054\000\000\058\058\062\062\068\068\073\073\078\078\082\082\086\086\090\090\094\094\098\098\102\102\106\106\110\110\114\114\118\118\122\122\126\126\130\130\000\000\134\134\000\000\000\000\000\000\138\138\142\142\146\146\152\!
152\158\158\162\162\168\168\000\000\000\000\000\000\000\000\00!
0\000\00
0\000\172\175\000\178\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\000\191\196\201\204\209\214\000\219\000\224\229\234\241\244\247\250\253\000\003\006\009\012\015\018\021\024\027\030\033\000\036\039\042\045\048\051\054\057\062\196\204\209\214\067\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\036\000\000\000\000\000\000\000\057\062\219\224\229\000\000\000\000\074\079\000\000\000\000\000\000\000\000\000\000\000\000\000\084\000\087\000\090\000\093\000\096\000\099\000\102\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\105\110\115\118\123\126\129\132\137\140\143\146\149\154\159\164\167\170\173\176\179\182\185\188\191\194\199\202\205\208\211\214\217\220\223\226\229\232\235\238\241\244\247\250\253\000\003\006\000\000\000\000\000\000!
\000\000\000\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\105\110\000\118\000\000\000\132\000\000\000\000\149\154\159\000\009\000\012\000\015\000\018\000\021\000\024\000\027\000\030\000\033\000\036\000\039\000\042\042\047\000\050\000\053\000\056\000\059\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\062\000\065\000\068\000\071\000\074\000\077\000\080\000\083\000\086\000\089\000\092\000\095\000\098\000\101\000\104\000\107\000\110\000\113\000\116\000\119\000\122\000\125\000\128\000\131\000\000\134\134\139\000\000\000\142\000\000\000\145\000\000\000\000\148\148\153\153\158\000\161\161\166\000\169\169\174\174\179\179\184\000\187\187\192\192\197\197\202\000\205\205\210\210\215\215\220\220\225\225\230\230\000\000\235\235\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!
\000\000\000\000\240\243\246\249\252\255\002\005\008\011\014\0!
17\020\0
23\026\029\032\035\038\041\044\047\050\053\056\059\062\065\068\071\074\077\080\083\086\089\092\095\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\098\103\108\113\118\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\123\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\138\000\000\000\000\000\000\000\145\000\000\152\00!
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\159\166\173\180\187\194\201\208\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\215\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\229\236\000\243\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\250\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\015\022\000\000\029\000\000\000\000\000\000\000\000\000\000\000\000\000\00!
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\
000\000\000\000\000\000\000\000\000\000\036\000\000\043\050\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\057\064\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\071\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\078\085\092\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\099\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0!
00\000\000\000\000\000\000\000\000\000\000\106\000\000\000\000\000\000\113\120\000\127\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\151\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\000\172\179\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\203\000\000\000\000\210\000\000\000\000\217\000\000\000\000\224\000\000\000\000\000\000\000\000\000\000\000\000\231\000\000\0!
00\000\000\000\000\000\000\238\000\245\252\000\003\000\000\000!
\000\000
\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\024\000\000\000\000\031\000\000\000\000\038\000\000\000\000\045\000\000\000\000\000\000\000\000\000\000\000\000\052\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\059\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\066\070\074\078\082\086\090\094\098\102\106\110\114\118\122\126\130\134\138\142\146\150\154\158\162\166\170\174\178\182\186\190\194\198\202\206\210\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\!
000\000\000\000\000\000\000\000\000\000\000\218\218\222\222\226\226\230\230\234\234\240\240\244\244\248\248\252\252\000\000\004\004\010\010\016\016\020\020\024\024\030\030\034\034\038\038\042\042\046\046\050\050\054\054\058\058\062\062\068\068\072\072\076\076\080\080\084\084\090\090\094\094\098\098\102\102\106\106\110\110\114\114\118\118\122\122\126\126\132\132\138\138\144\144\150\150\154\154\158\158\162\162\166\166\172\172\176\176\180\180\184\184\190\190\196\196\202\202\206\206\210\210\214\214\218\218\222\222\226\226\230\230\236\236\242\242\246\246\250\250\254\254\002\002\006\006\010\010\014\014\018\018\022\022\026\026\030\030\034\034\038\042\046\050\000\054\000\000\000\000\059\059\063\063\067\067\073\073\079\079\085\085\091\091\097\097\103\103\109\109\115\115\121\121\127\127\131\131\135\135\139\139\145\145\151\151\157\157\163\163\169\169\173\173\177\177\181\181\185\185\191\191\197\197\203\203\209\209\215\215\221\221\227\227\233\233\239\239\245\245\249\249\253\253\003\003\!
009\009\015\015\021\021\027\027\031\031\035\035\039\039\000\00!
0\000\00
0\000\000\043\048\053\060\067\074\081\088\043\048\053\060\067\074\081\088\095\100\105\112\119\126\000\000\095\100\105\112\119\126\000\000\133\138\143\150\157\164\171\178\133\138\143\150\157\164\171\178\185\190\195\202\209\216\223\230\185\190\195\202\209\216\223\230\237\242\247\254\005\012\000\000\237\242\247\254\005\012\000\000\019\024\029\036\043\050\057\064\000\024\000\036\000\050\000\064\071\076\081\088\095\102\109\116\071\076\081\088\095\102\109\116\123\196\128\204\133\209\138\214\143\219\148\224\153\229\000\000\158\165\172\181\190\199\208\217\158\165\172\181\190\199\208\217\226\233\240\249\002\011\020\029\226\233\240\249\002\011\020\029\038\045\052\061\070\079\088\097\038\045\052\061\070\079\088\097\106\111\116\123\128\000\135\140\106\111\123\196\123\000\009\000\000\147\152\159\164\000\171\176\128\204\133\209\159\183\189\195\201\206\211\234\000\000\218\223\201\206\138\214\000\230\236\242\248\253\002\067\009\014\019\024\248\253\148\224\014\031\191\036\000\000\038\045\050!
\000\057\062\143\219\153\229\045\069\000\000\000\000\000\000\000\000\000\000\000\000\000\000\072\072\072\072\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\072\072\072\072\072\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\072\072\072\072\072\072\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\073\077\081\085\089\093\097\101\105\109\113\117\121\125\129\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000!
\000\000\000\000\000\000\000\000\000\000\137\141\145\149\153\1!
57\161\1
65\169\173\177\181\185\189\193\197\201\205\209\213\217\221\225\229\233\237\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\248\000\255\000\006\000\013\000\020\000\027\000\034\000\041\000\048\000\055\000\062\000\000\069\000\076\000\083\000\000\000\000\000\000\090\097\000\104\111\000\118\125\000\132\139\000\146\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\000\000\000\000\000\000\000\000\000\167\000\000\000\000\000\000\000\000\000\000\000\000\000\174\000\181\000\188\000\195\000\202\000\209\000\216\000\223\000\230\000\237\000\244\000\251\000\000\002\000\009\000\016\000\000\000\000\000\000\023\030\000\037\044\000\051\058\000\065\072\000\079\086\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\09!
3\000\000\100\107\114\121\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\140\000\000\000\000\000\000\000\000\000\000\145\150\155\162\169\174\179\184\189\194\199\204\209\000\214\219\224\229\234\000\239\000\244\249\000\254\003\000\008\013\018\023\028\033\038\043\048\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\072\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\053\057\061\065\069\073\077\081\085\089\09!
3\097\101\105\109\113\117\121\125\129\133\137\141\145\149\153\!
000\000\
000\000\000"
Modified: trunk/src/update.ml
===================================================================
--- trunk/src/update.ml 2009-05-03 00:20:31 UTC (rev 325)
+++ trunk/src/update.ml 2009-05-04 18:48:23 UTC (rev 326)
@@ -34,11 +34,13 @@
representation does not change between unison versions.) *)
(*FIX: Use similar_correct in props.ml next time the
format is modified (see file props.ml for the new function) *)
-(*FIX: use Case.normalize next time the format is modified *)
(*FIX: also change Fileinfo.stamp to drop the info.ctime component, next time the
format is modified *)
(*FIX: also make Jerome's suggested change about file times (see his mesg in
unison-pending email folder). *)
+(*FIX: one should also store whether we are in case-insensitive mode
+ in the archive and check the mode has not changed when the archive
+ is loaded *)
let archiveFormat = 22
module NameMap = MyMap.Make (Name)
@@ -1185,20 +1187,8 @@
Note that case conflicts and illegal filenames can only occur under Unix,
when syncing with a Windows file system. *)
-let badWindowsFilenameRx =
- (* FIX: This should catch all device names (like aux, con, ...). I don't
- know what all the possible device names are. *)
- Rx.case_insensitive
- (Rx.rx "\\.*|aux|con|lpt1|prn|(.*[\000-\031\\/<>:\"|].*)")
+let badFilename s = Name.bad (Prefs.read Globals.someHostIsRunningWindows) s
-let isBadWindowsFilename s =
- (* FIX: should also check for a max filename length, not sure how much *)
- Rx.match_string badWindowsFilenameRx (Name.toString s)
-let badFilename s =
- (* Don't check unless we are syncing with Windows *)
- Prefs.read Globals.someHostIsRunningWindows &&
- isBadWindowsFilename s
-
let getChildren fspath path =
let children =
(* We sort them in reverse order, as findDuplicate will reverse
More information about the Unison-hackers
mailing list