diff options
Diffstat (limited to 'libgo')
499 files changed, 20434 insertions, 12528 deletions
diff --git a/libgo/MERGE b/libgo/MERGE index 569aa9c8f93..17d01ce7265 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -52ba9506bd99 +f4470a54e6db The first line of this file holds the Mercurial revision number of the last merge done from the master library sources. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 2e874df00b7..99294f12c12 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -225,7 +225,6 @@ toolexeclibgoexp_DATA = \ $(exp_inotify_gox) \ exp/norm.gox \ exp/proxy.gox \ - exp/signal.gox \ exp/terminal.gox \ exp/types.gox \ exp/utf8string.gox @@ -325,6 +324,7 @@ toolexeclibgoosdir = $(toolexeclibgodir)/os toolexeclibgoos_DATA = \ os/exec.gox \ + os/signal.gox \ os/user.gox toolexeclibgopathdir = $(toolexeclibgodir)/path @@ -352,8 +352,7 @@ toolexeclibgotestingdir = $(toolexeclibgodir)/testing toolexeclibgotesting_DATA = \ testing/iotest.gox \ - testing/quick.gox \ - testing/script.gox + testing/quick.gox toolexeclibgotextdir = $(toolexeclibgodir)/text @@ -398,6 +397,7 @@ runtime_files = \ runtime/go-byte-array-to-string.c \ runtime/go-breakpoint.c \ runtime/go-caller.c \ + runtime/go-callers.c \ runtime/go-can-convert-interface.c \ runtime/go-cgo.c \ runtime/go-check-interface.c \ @@ -428,7 +428,6 @@ runtime_files = \ runtime/go-panic.c \ runtime/go-print.c \ runtime/go-recover.c \ - runtime/go-reflect.c \ runtime/go-reflect-call.c \ runtime/go-reflect-map.c \ runtime/go-rune.c \ @@ -450,7 +449,6 @@ runtime_files = \ runtime/go-type-string.c \ runtime/go-typedesc-equal.c \ runtime/go-typestring.c \ - runtime/go-unreflect.c \ runtime/go-unsafe-new.c \ runtime/go-unsafe-newarray.c \ runtime/go-unsafe-pointer.c \ @@ -468,6 +466,7 @@ runtime_files = \ runtime/msize.c \ runtime/proc.c \ runtime/runtime.c \ + runtime/signal_unix.c \ runtime/thread.c \ runtime/yield.c \ $(rtems_task_variable_add_file) \ @@ -505,11 +504,11 @@ runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c mv -f $@.tmp $@ sema.c: $(srcdir)/runtime/sema.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_sync $< > $@.tmp mv -f $@.tmp $@ sigqueue.c: $(srcdir)/runtime/sigqueue.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_os $< > $@.tmp mv -f $@.tmp $@ time.c: $(srcdir)/runtime/time.goc goc2c @@ -526,7 +525,8 @@ go_bufio_files = \ go_bytes_files = \ go/bytes/buffer.go \ go/bytes/bytes.go \ - go/bytes/bytes_decl.go + go/bytes/bytes_decl.go \ + go/bytes/reader.go go_bytes_c_files = \ go/bytes/indexbyte.c @@ -658,10 +658,17 @@ go_net_sock_file = go/net/sock_linux.go go_net_sockopt_file = go/net/sockopt_linux.go go_net_sockoptip_file = go/net/sockoptip_linux.go else +if LIBGO_IS_FREEBSD +go_net_cgo_file = go/net/cgo_bsd.go +go_net_sock_file = go/net/sock_bsd.go +go_net_sockopt_file = go/net/sockopt_bsd.go +go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_freebsd.go +else go_net_cgo_file = go/net/cgo_bsd.go go_net_sock_file = go/net/sock_bsd.go go_net_sockopt_file = go/net/sockopt_bsd.go -go_net_sockoptip_file = go/net/sockoptip_bsd.go +go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_netbsd.go +endif endif endif endif @@ -704,6 +711,7 @@ go_net_files = \ go/net/ipsock.go \ go/net/ipsock_posix.go \ go/net/lookup_unix.go \ + go/net/mac.go \ go/net/net.go \ go/net/parse.go \ go/net/pipe.go \ @@ -784,9 +792,7 @@ go_os_files = \ $(go_os_stat_file) \ go/os/str.go \ $(go_os_sys_file) \ - go/os/time.go \ - go/os/types.go \ - signal_unix.go + go/os/types.go go_path_files = \ go/path/match.go \ @@ -811,7 +817,6 @@ go_runtime_files = \ go/runtime/error.go \ go/runtime/extern.go \ go/runtime/mem.go \ - go/runtime/sig.go \ go/runtime/softfloat64.go \ go/runtime/type.go \ version.go @@ -850,6 +855,7 @@ go_sync_files = \ go/sync/cond.go \ go/sync/mutex.go \ go/sync/once.go \ + go/sync/runtime.go \ go/sync/rwmutex.go \ go/sync/waitgroup.go @@ -881,6 +887,7 @@ go_time_files = \ go/time/tick.go \ go/time/time.go \ go/time/zoneinfo.go \ + go/time/zoneinfo_read.go \ go/time/zoneinfo_unix.go go_unicode_files = \ @@ -1017,12 +1024,14 @@ go_debug_dwarf_files = \ go/debug/dwarf/buf.go \ go/debug/dwarf/const.go \ go/debug/dwarf/entry.go \ + go/debug/dwarf/line.go \ go/debug/dwarf/open.go \ go/debug/dwarf/type.go \ go/debug/dwarf/unit.go go_debug_elf_files = \ go/debug/elf/elf.go \ - go/debug/elf/file.go + go/debug/elf/file.go \ + go/debug/elf/runtime.go go_debug_gosym_files = \ go/debug/gosym/pclntab.go \ go/debug/gosym/symtab.go @@ -1094,6 +1103,7 @@ go_exp_norm_files = \ go/exp/norm/composition.go \ go/exp/norm/forminfo.go \ go/exp/norm/input.go \ + go/exp/norm/iter.go \ go/exp/norm/normalize.go \ go/exp/norm/readwriter.go \ go/exp/norm/tables.go \ @@ -1103,8 +1113,6 @@ go_exp_proxy_files = \ go/exp/proxy/per_host.go \ go/exp/proxy/proxy.go \ go/exp/proxy/socks5.go -go_exp_signal_files = \ - go/exp/signal/signal.go go_exp_terminal_files = \ go/exp/terminal/terminal.go \ go/exp/terminal/util.go @@ -1128,8 +1136,7 @@ go_go_ast_files = \ go/go/ast/walk.go go_go_build_files = \ go/go/build/build.go \ - go/go/build/dir.go \ - go/go/build/path.go \ + go/go/build/doc.go \ syslist.go go_go_doc_files = \ go/go/doc/comment.go \ @@ -1137,7 +1144,8 @@ go_go_doc_files = \ go/go/doc/example.go \ go/go/doc/exports.go \ go/go/doc/filter.go \ - go/go/doc/reader.go + go/go/doc/reader.go \ + go/go/doc/synopsis.go go_go_parser_files = \ go/go/parser/interface.go \ go/go/parser/parser.go @@ -1164,7 +1172,6 @@ go_hash_fnv_files = \ go_html_template_files = \ go/html/template/attr.go \ - go/html/template/clone.go \ go/html/template/content.go \ go/html/template/context.go \ go/html/template/css.go \ @@ -1302,6 +1309,10 @@ go_os_exec_files = \ go/os/exec/exec.go \ go/os/exec/lp_unix.go +go_os_signal_files = \ + go/os/signal/signal.go \ + go/os/signal/signal_unix.go + go_os_user_files = \ go/os/user/user.go \ go/os/user/lookup_unix.go @@ -1352,8 +1363,6 @@ go_testing_iotest_files = \ go/testing/iotest/writer.go go_testing_quick_files = \ go/testing/quick/quick.go -go_testing_script_files = \ - go/testing/script/script.go go_text_scanner_files = \ go/text/scanner/scanner.go @@ -1489,6 +1498,13 @@ else syscall_netlink_file = endif +# GNU/Linux specific socket filters. +if LIBGO_IS_LINUX +syscall_lsf_file = go/syscall/lsf_linux.go +else +syscall_lsf_file = +endif + go_base_syscall_files = \ go/syscall/env_unix.go \ go/syscall/syscall_errno.go \ @@ -1509,6 +1525,7 @@ go_base_syscall_files = \ $(syscall_socket_file) \ $(syscall_uname_file) \ $(syscall_netlink_file) \ + $(syscall_lsf_file) \ $(GO_LIBCALL_OS_FILE) \ $(GO_LIBCALL_OS_ARCH_FILE) \ $(GO_SYSCALL_OS_FILE) \ @@ -1521,6 +1538,7 @@ go_syscall_files = \ syscall_arch.go go_syscall_c_files = \ go/syscall/errno.c \ + go/syscall/signame.c \ $(syscall_wait_c_file) libcalls.go: s-libcalls; @true @@ -1659,7 +1677,6 @@ libgo_go_objs = \ exp/html.lo \ exp/norm.lo \ exp/proxy.lo \ - exp/signal.lo \ exp/terminal.lo \ exp/types.lo \ exp/utf8string.lo \ @@ -1704,6 +1721,7 @@ libgo_go_objs = \ old/regexp.lo \ old/template.lo \ $(os_lib_inotify_lo) \ + os/signal.lo \ os/user.lo \ path/filepath.lo \ regexp/syntax.lo \ @@ -1714,6 +1732,7 @@ libgo_go_objs = \ sync/atomic_c.lo \ syscall/syscall.lo \ syscall/errno.lo \ + syscall/signame.lo \ syscall/wait.lo \ text/scanner.lo \ text/tabwriter.lo \ @@ -1722,7 +1741,6 @@ libgo_go_objs = \ testing/testing.lo \ testing/iotest.lo \ testing/quick.lo \ - testing/script.lo \ unicode/utf16.lo \ unicode/utf8.lo @@ -1978,10 +1996,6 @@ os/check: $(CHECK_DEPS) @$(CHECK) .PHONY: os/check -signal_unix.go: $(srcdir)/go/os/mkunixsignals.sh sysinfo.go - $(SHELL) $(srcdir)/go/os/mkunixsignals.sh sysinfo.go > $@.tmp - mv -f $@.tmp $@ - @go_include@ path/path.lo.dep path/path.lo.dep: $(go_path_files) $(BUILDDEPS) @@ -2591,16 +2605,6 @@ exp/proxy/check: $(CHECK_DEPS) @$(CHECK) .PHONY: exp/proxy/check -@go_include@ exp/signal.lo.dep -exp/signal.lo.dep: $(go_exp_signal_files) - $(BUILDDEPS) -exp/signal.lo: $(go_exp_signal_files) - $(BUILDPACKAGE) -exp/signal/check: $(CHECK_DEPS) - @$(MKDIR_P) exp/signal - @$(CHECK) -.PHONY: exp/signal/check - @go_include@ exp/terminal.lo.dep exp/terminal.lo.dep: $(go_exp_terminal_files) $(BUILDDEPS) @@ -3052,6 +3056,16 @@ os/exec/check: $(CHECK_DEPS) @$(CHECK) .PHONY: os/exec/check +@go_include@ os/signal.lo.dep +os/signal.lo.dep: $(go_os_signal_files) + $(BUILDDEPS) +os/signal.lo: $(go_os_signal_files) + $(BUILDPACKAGE) +os/signal/check: $(CHECK_DEPS) + @$(MKDIR_P) os/signal + @$(CHECK) +.PHONY: os/signal/check + @go_include@ os/user.lo.dep os/user.lo.dep: $(go_os_user_files) $(BUILDDEPS) @@ -3163,16 +3177,6 @@ testing/quick/check: $(CHECK_DEPS) @$(CHECK) .PHONY: testing/quick/check -@go_include@ testing/script.lo.dep -testing/script.lo.dep: $(go_testing_script_files) - $(BUILDDEPS) -testing/script.lo: $(go_testing_script_files) - $(BUILDPACKAGE) -testing/script/check: $(CHECK_DEPS) - @$(MKDIR_P) testing/script - @$(CHECK) -.PHONY: testing/script/check - @go_include@ unicode/utf16.lo.dep unicode/utf16.lo.dep: $(go_unicode_utf16_files) $(BUILDDEPS) @@ -3200,6 +3204,8 @@ syscall/syscall.lo: $(go_syscall_files) $(BUILDPACKAGE) syscall/errno.lo: go/syscall/errno.c $(LTCOMPILE) -c -o $@ $< +syscall/signame.lo: go/syscall/signame.c + $(LTCOMPILE) -c -o $@ $< syscall/wait.lo: go/syscall/wait.c $(LTCOMPILE) -c -o $@ $< @@ -3376,8 +3382,6 @@ exp/norm.gox: exp/norm.lo $(BUILDGOX) exp/proxy.gox: exp/proxy.lo $(BUILDGOX) -exp/signal.gox: exp/signal.lo - $(BUILDGOX) exp/terminal.gox: exp/terminal.lo $(BUILDGOX) exp/types.gox: exp/types.lo @@ -3478,6 +3482,8 @@ old/template.gox: old/template.lo os/exec.gox: os/exec.lo $(BUILDGOX) +os/signal.gox: os/signal.lo + $(BUILDGOX) os/user.gox: os/user.lo $(BUILDGOX) @@ -3508,8 +3514,6 @@ testing/iotest.gox: testing/iotest.lo $(BUILDGOX) testing/quick.gox: testing/quick.lo $(BUILDGOX) -testing/script.gox: testing/script.lo - $(BUILDGOX) unicode/utf16.gox: unicode/utf16.lo $(BUILDGOX) @@ -3597,7 +3601,6 @@ TEST_PACKAGES = \ $(exp_inotify_check) \ exp/norm/check \ exp/proxy/check \ - exp/signal/check \ exp/terminal/check \ exp/utf8string/check \ html/template/check \ @@ -3627,6 +3630,7 @@ TEST_PACKAGES = \ net/http/check \ net/http/cgi/check \ net/http/fcgi/check \ + net/http/httptest/check \ net/http/httputil/check \ net/mail/check \ net/rpc/check \ @@ -3638,6 +3642,7 @@ TEST_PACKAGES = \ old/regexp/check \ old/template/check \ os/exec/check \ + os/signal/check \ os/user/check \ path/filepath/check \ regexp/syntax/check \ @@ -3647,7 +3652,6 @@ TEST_PACKAGES = \ text/template/check \ text/template/parse/check \ testing/quick/check \ - testing/script/check \ unicode/utf16/check \ unicode/utf8/check diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 50195cc458a..b57d92919b5 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -154,25 +154,25 @@ am__DEPENDENCIES_2 = bufio/bufio.lo bytes/bytes.lo bytes/index.lo \ encoding/base32.lo encoding/base64.lo encoding/binary.lo \ encoding/csv.lo encoding/gob.lo encoding/hex.lo \ encoding/json.lo encoding/pem.lo encoding/xml.lo exp/ebnf.lo \ - exp/html.lo exp/norm.lo exp/proxy.lo exp/signal.lo \ - exp/terminal.lo exp/types.lo exp/utf8string.lo \ - html/template.lo go/ast.lo go/build.lo go/doc.lo go/parser.lo \ - go/printer.lo go/scanner.lo go/token.lo hash/adler32.lo \ - hash/crc32.lo hash/crc64.lo hash/fnv.lo net/http/cgi.lo \ - net/http/fcgi.lo net/http/httptest.lo net/http/httputil.lo \ - net/http/pprof.lo image/color.lo image/draw.lo image/gif.lo \ - image/jpeg.lo image/png.lo index/suffixarray.lo io/ioutil.lo \ - log/syslog.lo log/syslog/syslog_c.lo math/big.lo math/cmplx.lo \ - math/rand.lo mime/mime.lo mime/multipart.lo net/http.lo \ - net/mail.lo net/rpc.lo net/smtp.lo net/textproto.lo net/url.lo \ + exp/html.lo exp/norm.lo exp/proxy.lo exp/terminal.lo \ + exp/types.lo exp/utf8string.lo html/template.lo go/ast.lo \ + go/build.lo go/doc.lo go/parser.lo go/printer.lo go/scanner.lo \ + go/token.lo hash/adler32.lo hash/crc32.lo hash/crc64.lo \ + hash/fnv.lo net/http/cgi.lo net/http/fcgi.lo \ + net/http/httptest.lo net/http/httputil.lo net/http/pprof.lo \ + image/color.lo image/draw.lo image/gif.lo image/jpeg.lo \ + image/png.lo index/suffixarray.lo io/ioutil.lo log/syslog.lo \ + log/syslog/syslog_c.lo math/big.lo math/cmplx.lo math/rand.lo \ + mime/mime.lo mime/multipart.lo net/http.lo net/mail.lo \ + net/rpc.lo net/smtp.lo net/textproto.lo net/url.lo \ old/netchan.lo old/regexp.lo old/template.lo \ - $(am__DEPENDENCIES_1) os/user.lo path/filepath.lo \ + $(am__DEPENDENCIES_1) os/signal.lo os/user.lo path/filepath.lo \ regexp/syntax.lo net/rpc/jsonrpc.lo runtime/debug.lo \ runtime/pprof.lo sync/atomic.lo sync/atomic_c.lo \ - syscall/syscall.lo syscall/errno.lo syscall/wait.lo \ - text/scanner.lo text/tabwriter.lo text/template.lo \ - text/template/parse.lo testing/testing.lo testing/iotest.lo \ - testing/quick.lo testing/script.lo unicode/utf16.lo \ + syscall/syscall.lo syscall/errno.lo syscall/signame.lo \ + syscall/wait.lo text/scanner.lo text/tabwriter.lo \ + text/template.lo text/template/parse.lo testing/testing.lo \ + testing/iotest.lo testing/quick.lo unicode/utf16.lo \ unicode/utf8.lo libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -180,14 +180,14 @@ libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ runtime/go-assert-interface.c \ runtime/go-byte-array-to-string.c runtime/go-breakpoint.c \ - runtime/go-caller.c runtime/go-can-convert-interface.c \ - runtime/go-cgo.c runtime/go-check-interface.c \ - runtime/go-construct-map.c runtime/go-convert-interface.c \ - runtime/go-copy.c runtime/go-defer.c \ - runtime/go-deferred-recover.c runtime/go-eface-compare.c \ - runtime/go-eface-val-compare.c runtime/go-getgoroot.c \ - runtime/go-int-array-to-string.c runtime/go-int-to-string.c \ - runtime/go-interface-compare.c \ + runtime/go-caller.c runtime/go-callers.c \ + runtime/go-can-convert-interface.c runtime/go-cgo.c \ + runtime/go-check-interface.c runtime/go-construct-map.c \ + runtime/go-convert-interface.c runtime/go-copy.c \ + runtime/go-defer.c runtime/go-deferred-recover.c \ + runtime/go-eface-compare.c runtime/go-eface-val-compare.c \ + runtime/go-getgoroot.c runtime/go-int-array-to-string.c \ + runtime/go-int-to-string.c runtime/go-interface-compare.c \ runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c runtime/go-make-slice.c \ runtime/go-map-delete.c runtime/go-map-index.c \ @@ -195,10 +195,9 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ runtime/go-matherr.c runtime/go-nanotime.c runtime/go-now.c \ runtime/go-new-map.c runtime/go-new.c runtime/go-nosys.c \ runtime/go-panic.c runtime/go-print.c runtime/go-recover.c \ - runtime/go-reflect.c runtime/go-reflect-call.c \ - runtime/go-reflect-map.c runtime/go-rune.c \ - runtime/go-runtime-error.c runtime/go-setenv.c \ - runtime/go-signal.c runtime/go-strcmp.c \ + runtime/go-reflect-call.c runtime/go-reflect-map.c \ + runtime/go-rune.c runtime/go-runtime-error.c \ + runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \ runtime/go-string-to-byte-array.c \ runtime/go-string-to-int-array.c runtime/go-strplus.c \ runtime/go-strslice.c runtime/go-trampoline.c \ @@ -206,15 +205,15 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ runtime/go-type-error.c runtime/go-type-float.c \ runtime/go-type-identity.c runtime/go-type-interface.c \ runtime/go-type-string.c runtime/go-typedesc-equal.c \ - runtime/go-typestring.c runtime/go-unreflect.c \ - runtime/go-unsafe-new.c runtime/go-unsafe-newarray.c \ - runtime/go-unsafe-pointer.c runtime/go-unwind.c runtime/chan.c \ - runtime/cpuprof.c runtime/lock_sema.c runtime/thread-sema.c \ - runtime/lock_futex.c runtime/thread-linux.c runtime/mcache.c \ - runtime/mcentral.c runtime/mem_posix_memalign.c runtime/mem.c \ - runtime/mfinal.c runtime/mfixalloc.c runtime/mgc0.c \ - runtime/mheap.c runtime/msize.c runtime/proc.c \ - runtime/runtime.c runtime/thread.c runtime/yield.c \ + runtime/go-typestring.c runtime/go-unsafe-new.c \ + runtime/go-unsafe-newarray.c runtime/go-unsafe-pointer.c \ + runtime/go-unwind.c runtime/chan.c runtime/cpuprof.c \ + runtime/lock_sema.c runtime/thread-sema.c runtime/lock_futex.c \ + runtime/thread-linux.c runtime/mcache.c runtime/mcentral.c \ + runtime/mem_posix_memalign.c runtime/mem.c runtime/mfinal.c \ + runtime/mfixalloc.c runtime/mgc0.c runtime/mheap.c \ + runtime/msize.c runtime/proc.c runtime/runtime.c \ + runtime/signal_unix.c runtime/thread.c runtime/yield.c \ runtime/rtems-task-variable-add.c iface.c malloc.c map.c \ mprof.c reflect.c runtime1.c sema.c sigqueue.c string.c time.c @LIBGO_IS_LINUX_FALSE@am__objects_1 = lock_sema.lo thread-sema.lo @@ -224,30 +223,30 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ @LIBGO_IS_RTEMS_TRUE@am__objects_3 = rtems-task-variable-add.lo am__objects_4 = go-append.lo go-assert.lo go-assert-interface.lo \ go-byte-array-to-string.lo go-breakpoint.lo go-caller.lo \ - go-can-convert-interface.lo go-cgo.lo go-check-interface.lo \ - go-construct-map.lo go-convert-interface.lo go-copy.lo \ - go-defer.lo go-deferred-recover.lo go-eface-compare.lo \ + go-callers.lo go-can-convert-interface.lo go-cgo.lo \ + go-check-interface.lo go-construct-map.lo \ + go-convert-interface.lo go-copy.lo go-defer.lo \ + go-deferred-recover.lo go-eface-compare.lo \ go-eface-val-compare.lo go-getgoroot.lo \ go-int-array-to-string.lo go-int-to-string.lo \ go-interface-compare.lo go-interface-eface-compare.lo \ go-interface-val-compare.lo go-make-slice.lo go-map-delete.lo \ go-map-index.lo go-map-len.lo go-map-range.lo go-matherr.lo \ go-nanotime.lo go-now.lo go-new-map.lo go-new.lo go-nosys.lo \ - go-panic.lo go-print.lo go-recover.lo go-reflect.lo \ - go-reflect-call.lo go-reflect-map.lo go-rune.lo \ - go-runtime-error.lo go-setenv.lo go-signal.lo go-strcmp.lo \ - go-string-to-byte-array.lo go-string-to-int-array.lo \ - go-strplus.lo go-strslice.lo go-trampoline.lo \ - go-type-complex.lo go-type-eface.lo go-type-error.lo \ - go-type-float.lo go-type-identity.lo go-type-interface.lo \ - go-type-string.lo go-typedesc-equal.lo go-typestring.lo \ - go-unreflect.lo go-unsafe-new.lo go-unsafe-newarray.lo \ + go-panic.lo go-print.lo go-recover.lo go-reflect-call.lo \ + go-reflect-map.lo go-rune.lo go-runtime-error.lo go-setenv.lo \ + go-signal.lo go-strcmp.lo go-string-to-byte-array.lo \ + go-string-to-int-array.lo go-strplus.lo go-strslice.lo \ + go-trampoline.lo go-type-complex.lo go-type-eface.lo \ + go-type-error.lo go-type-float.lo go-type-identity.lo \ + go-type-interface.lo go-type-string.lo go-typedesc-equal.lo \ + go-typestring.lo go-unsafe-new.lo go-unsafe-newarray.lo \ go-unsafe-pointer.lo go-unwind.lo chan.lo cpuprof.lo \ $(am__objects_1) mcache.lo mcentral.lo $(am__objects_2) \ mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo proc.lo \ - runtime.lo thread.lo yield.lo $(am__objects_3) iface.lo \ - malloc.lo map.lo mprof.lo reflect.lo runtime1.lo sema.lo \ - sigqueue.lo string.lo time.lo + runtime.lo signal_unix.lo thread.lo yield.lo $(am__objects_3) \ + iface.lo malloc.lo map.lo mprof.lo reflect.lo runtime1.lo \ + sema.lo sigqueue.lo string.lo time.lo am_libgo_la_OBJECTS = $(am__objects_4) libgo_la_OBJECTS = $(am_libgo_la_OBJECTS) libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -679,7 +678,6 @@ toolexeclibgoexp_DATA = \ $(exp_inotify_gox) \ exp/norm.gox \ exp/proxy.gox \ - exp/signal.gox \ exp/terminal.gox \ exp/types.gox \ exp/utf8string.gox @@ -765,6 +763,7 @@ toolexeclibgoold_DATA = \ toolexeclibgoosdir = $(toolexeclibgodir)/os toolexeclibgoos_DATA = \ os/exec.gox \ + os/signal.gox \ os/user.gox toolexeclibgopathdir = $(toolexeclibgodir)/path @@ -787,8 +786,7 @@ toolexeclibgosync_DATA = \ toolexeclibgotestingdir = $(toolexeclibgodir)/testing toolexeclibgotesting_DATA = \ testing/iotest.gox \ - testing/quick.gox \ - testing/script.gox + testing/quick.gox toolexeclibgotextdir = $(toolexeclibgodir)/text toolexeclibgotext_DATA = \ @@ -818,6 +816,7 @@ runtime_files = \ runtime/go-byte-array-to-string.c \ runtime/go-breakpoint.c \ runtime/go-caller.c \ + runtime/go-callers.c \ runtime/go-can-convert-interface.c \ runtime/go-cgo.c \ runtime/go-check-interface.c \ @@ -848,7 +847,6 @@ runtime_files = \ runtime/go-panic.c \ runtime/go-print.c \ runtime/go-recover.c \ - runtime/go-reflect.c \ runtime/go-reflect-call.c \ runtime/go-reflect-map.c \ runtime/go-rune.c \ @@ -870,7 +868,6 @@ runtime_files = \ runtime/go-type-string.c \ runtime/go-typedesc-equal.c \ runtime/go-typestring.c \ - runtime/go-unreflect.c \ runtime/go-unsafe-new.c \ runtime/go-unsafe-newarray.c \ runtime/go-unsafe-pointer.c \ @@ -888,6 +885,7 @@ runtime_files = \ runtime/msize.c \ runtime/proc.c \ runtime/runtime.c \ + runtime/signal_unix.c \ runtime/thread.c \ runtime/yield.c \ $(rtems_task_variable_add_file) \ @@ -908,7 +906,8 @@ go_bufio_files = \ go_bytes_files = \ go/bytes/buffer.go \ go/bytes/bytes.go \ - go/bytes/bytes_decl.go + go/bytes/bytes_decl.go \ + go/bytes/reader.go go_bytes_c_files = \ go/bytes/indexbyte.c @@ -1013,19 +1012,23 @@ go_mime_files = \ @LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = go/net/newpollserver.go @LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = go/net/newpollserver.go @LIBGO_IS_RTEMS_TRUE@go_net_newpollserver_file = go/net/newpollserver_rtems.go -@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go +@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go +@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go @LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_file = go/net/cgo_linux.go @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_file = go/net/cgo_linux.go @LIBGO_IS_LINUX_TRUE@go_net_cgo_file = go/net/cgo_linux.go -@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sock_file = go/net/sock_bsd.go +@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sock_file = go/net/sock_bsd.go +@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sock_file = go/net/sock_bsd.go @LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sock_file = go/net/sock_linux.go @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sock_file = go/net/sock_linux.go @LIBGO_IS_LINUX_TRUE@go_net_sock_file = go/net/sock_linux.go -@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockopt_file = go/net/sockopt_bsd.go +@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockopt_file = go/net/sockopt_bsd.go +@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockopt_file = go/net/sockopt_bsd.go @LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sockopt_file = go/net/sockopt_linux.go @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sockopt_file = go/net/sockopt_linux.go @LIBGO_IS_LINUX_TRUE@go_net_sockopt_file = go/net/sockopt_linux.go -@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockoptip_file = go/net/sockoptip_bsd.go +@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_netbsd.go +@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_freebsd.go @LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sockoptip_file = go/net/sockoptip_linux.go @LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sockoptip_file = go/net/sockoptip_linux.go @LIBGO_IS_LINUX_TRUE@go_net_sockoptip_file = go/net/sockoptip_linux.go @@ -1056,6 +1059,7 @@ go_net_files = \ go/net/ipsock.go \ go/net/ipsock_posix.go \ go/net/lookup_unix.go \ + go/net/mac.go \ go/net/net.go \ go/net/parse.go \ go/net/pipe.go \ @@ -1106,9 +1110,7 @@ go_os_files = \ $(go_os_stat_file) \ go/os/str.go \ $(go_os_sys_file) \ - go/os/time.go \ - go/os/types.go \ - signal_unix.go + go/os/types.go go_path_files = \ go/path/match.go \ @@ -1133,7 +1135,6 @@ go_runtime_files = \ go/runtime/error.go \ go/runtime/extern.go \ go/runtime/mem.go \ - go/runtime/sig.go \ go/runtime/softfloat64.go \ go/runtime/type.go \ version.go @@ -1161,6 +1162,7 @@ go_sync_files = \ go/sync/cond.go \ go/sync/mutex.go \ go/sync/once.go \ + go/sync/runtime.go \ go/sync/rwmutex.go \ go/sync/waitgroup.go @@ -1186,6 +1188,7 @@ go_time_files = \ go/time/tick.go \ go/time/time.go \ go/time/zoneinfo.go \ + go/time/zoneinfo_read.go \ go/time/zoneinfo_unix.go go_unicode_files = \ @@ -1337,13 +1340,15 @@ go_debug_dwarf_files = \ go/debug/dwarf/buf.go \ go/debug/dwarf/const.go \ go/debug/dwarf/entry.go \ + go/debug/dwarf/line.go \ go/debug/dwarf/open.go \ go/debug/dwarf/type.go \ go/debug/dwarf/unit.go go_debug_elf_files = \ go/debug/elf/elf.go \ - go/debug/elf/file.go + go/debug/elf/file.go \ + go/debug/elf/runtime.go go_debug_gosym_files = \ go/debug/gosym/pclntab.go \ @@ -1431,6 +1436,7 @@ go_exp_norm_files = \ go/exp/norm/composition.go \ go/exp/norm/forminfo.go \ go/exp/norm/input.go \ + go/exp/norm/iter.go \ go/exp/norm/normalize.go \ go/exp/norm/readwriter.go \ go/exp/norm/tables.go \ @@ -1442,9 +1448,6 @@ go_exp_proxy_files = \ go/exp/proxy/proxy.go \ go/exp/proxy/socks5.go -go_exp_signal_files = \ - go/exp/signal/signal.go - go_exp_terminal_files = \ go/exp/terminal/terminal.go \ go/exp/terminal/util.go @@ -1471,8 +1474,7 @@ go_go_ast_files = \ go_go_build_files = \ go/go/build/build.go \ - go/go/build/dir.go \ - go/go/build/path.go \ + go/go/build/doc.go \ syslist.go go_go_doc_files = \ @@ -1481,7 +1483,8 @@ go_go_doc_files = \ go/go/doc/example.go \ go/go/doc/exports.go \ go/go/doc/filter.go \ - go/go/doc/reader.go + go/go/doc/reader.go \ + go/go/doc/synopsis.go go_go_parser_files = \ go/go/parser/interface.go \ @@ -1515,7 +1518,6 @@ go_hash_fnv_files = \ go_html_template_files = \ go/html/template/attr.go \ - go/html/template/clone.go \ go/html/template/content.go \ go/html/template/context.go \ go/html/template/css.go \ @@ -1664,6 +1666,10 @@ go_os_exec_files = \ go/os/exec/exec.go \ go/os/exec/lp_unix.go +go_os_signal_files = \ + go/os/signal/signal.go \ + go/os/signal/signal_unix.go + go_os_user_files = \ go/os/user/user.go \ go/os/user/lookup_unix.go @@ -1720,9 +1726,6 @@ go_testing_iotest_files = \ go_testing_quick_files = \ go/testing/quick/quick.go -go_testing_script_files = \ - go/testing/script/script.go - go_text_scanner_files = \ go/text/scanner/scanner.go @@ -1795,6 +1798,10 @@ go_unicode_utf8_files = \ # Support for netlink sockets and messages. @LIBGO_IS_LINUX_TRUE@syscall_netlink_file = go/syscall/netlink_linux.go +@LIBGO_IS_LINUX_FALSE@syscall_lsf_file = + +# GNU/Linux specific socket filters. +@LIBGO_IS_LINUX_TRUE@syscall_lsf_file = go/syscall/lsf_linux.go go_base_syscall_files = \ go/syscall/env_unix.go \ go/syscall/syscall_errno.go \ @@ -1815,6 +1822,7 @@ go_base_syscall_files = \ $(syscall_socket_file) \ $(syscall_uname_file) \ $(syscall_netlink_file) \ + $(syscall_lsf_file) \ $(GO_LIBCALL_OS_FILE) \ $(GO_LIBCALL_OS_ARCH_FILE) \ $(GO_SYSCALL_OS_FILE) \ @@ -1828,6 +1836,7 @@ go_syscall_files = \ go_syscall_c_files = \ go/syscall/errno.c \ + go/syscall/signame.c \ $(syscall_wait_c_file) @LIBGO_IS_LINUX_FALSE@os_lib_inotify_lo = @@ -1912,7 +1921,6 @@ libgo_go_objs = \ exp/html.lo \ exp/norm.lo \ exp/proxy.lo \ - exp/signal.lo \ exp/terminal.lo \ exp/types.lo \ exp/utf8string.lo \ @@ -1957,6 +1965,7 @@ libgo_go_objs = \ old/regexp.lo \ old/template.lo \ $(os_lib_inotify_lo) \ + os/signal.lo \ os/user.lo \ path/filepath.lo \ regexp/syntax.lo \ @@ -1967,6 +1976,7 @@ libgo_go_objs = \ sync/atomic_c.lo \ syscall/syscall.lo \ syscall/errno.lo \ + syscall/signame.lo \ syscall/wait.lo \ text/scanner.lo \ text/tabwriter.lo \ @@ -1975,7 +1985,6 @@ libgo_go_objs = \ testing/testing.lo \ testing/iotest.lo \ testing/quick.lo \ - testing/script.lo \ unicode/utf16.lo \ unicode/utf8.lo @@ -2161,7 +2170,6 @@ TEST_PACKAGES = \ $(exp_inotify_check) \ exp/norm/check \ exp/proxy/check \ - exp/signal/check \ exp/terminal/check \ exp/utf8string/check \ html/template/check \ @@ -2191,6 +2199,7 @@ TEST_PACKAGES = \ net/http/check \ net/http/cgi/check \ net/http/fcgi/check \ + net/http/httptest/check \ net/http/httputil/check \ net/mail/check \ net/rpc/check \ @@ -2202,6 +2211,7 @@ TEST_PACKAGES = \ old/regexp/check \ old/template/check \ os/exec/check \ + os/signal/check \ os/user/check \ path/filepath/check \ regexp/syntax/check \ @@ -2211,7 +2221,6 @@ TEST_PACKAGES = \ text/template/check \ text/template/parse/check \ testing/quick/check \ - testing/script/check \ unicode/utf16/check \ unicode/utf8/check @@ -2357,6 +2366,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-breakpoint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-byte-array-to-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-callers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-can-convert-interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cgo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-check-interface.Plo@am__quote@ @@ -2390,7 +2400,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-recover.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-reflect-call.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-reflect-map.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-reflect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-rune.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-runtime-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-setenv.Plo@am__quote@ @@ -2410,7 +2419,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-typedesc-equal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-typestring.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unreflect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-new.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-newarray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-pointer.Plo@am__quote@ @@ -2436,6 +2444,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtime1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sema.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal_unix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigqueue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-linux.Plo@am__quote@ @@ -2521,6 +2530,13 @@ go-caller.lo: runtime/go-caller.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-caller.lo `test -f 'runtime/go-caller.c' || echo '$(srcdir)/'`runtime/go-caller.c +go-callers.lo: runtime/go-callers.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-callers.lo -MD -MP -MF $(DEPDIR)/go-callers.Tpo -c -o go-callers.lo `test -f 'runtime/go-callers.c' || echo '$(srcdir)/'`runtime/go-callers.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-callers.Tpo $(DEPDIR)/go-callers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-callers.c' object='go-callers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-callers.lo `test -f 'runtime/go-callers.c' || echo '$(srcdir)/'`runtime/go-callers.c + go-can-convert-interface.lo: runtime/go-can-convert-interface.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-can-convert-interface.lo -MD -MP -MF $(DEPDIR)/go-can-convert-interface.Tpo -c -o go-can-convert-interface.lo `test -f 'runtime/go-can-convert-interface.c' || echo '$(srcdir)/'`runtime/go-can-convert-interface.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-can-convert-interface.Tpo $(DEPDIR)/go-can-convert-interface.Plo @@ -2731,13 +2747,6 @@ go-recover.lo: runtime/go-recover.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-recover.lo `test -f 'runtime/go-recover.c' || echo '$(srcdir)/'`runtime/go-recover.c -go-reflect.lo: runtime/go-reflect.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-reflect.lo -MD -MP -MF $(DEPDIR)/go-reflect.Tpo -c -o go-reflect.lo `test -f 'runtime/go-reflect.c' || echo '$(srcdir)/'`runtime/go-reflect.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-reflect.Tpo $(DEPDIR)/go-reflect.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-reflect.c' object='go-reflect.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-reflect.lo `test -f 'runtime/go-reflect.c' || echo '$(srcdir)/'`runtime/go-reflect.c - go-reflect-call.lo: runtime/go-reflect-call.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-reflect-call.lo -MD -MP -MF $(DEPDIR)/go-reflect-call.Tpo -c -o go-reflect-call.lo `test -f 'runtime/go-reflect-call.c' || echo '$(srcdir)/'`runtime/go-reflect-call.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-reflect-call.Tpo $(DEPDIR)/go-reflect-call.Plo @@ -2885,13 +2894,6 @@ go-typestring.lo: runtime/go-typestring.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-typestring.lo `test -f 'runtime/go-typestring.c' || echo '$(srcdir)/'`runtime/go-typestring.c -go-unreflect.lo: runtime/go-unreflect.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-unreflect.lo -MD -MP -MF $(DEPDIR)/go-unreflect.Tpo -c -o go-unreflect.lo `test -f 'runtime/go-unreflect.c' || echo '$(srcdir)/'`runtime/go-unreflect.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-unreflect.Tpo $(DEPDIR)/go-unreflect.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-unreflect.c' object='go-unreflect.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-unreflect.lo `test -f 'runtime/go-unreflect.c' || echo '$(srcdir)/'`runtime/go-unreflect.c - go-unsafe-new.lo: runtime/go-unsafe-new.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-unsafe-new.lo -MD -MP -MF $(DEPDIR)/go-unsafe-new.Tpo -c -o go-unsafe-new.lo `test -f 'runtime/go-unsafe-new.c' || echo '$(srcdir)/'`runtime/go-unsafe-new.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-unsafe-new.Tpo $(DEPDIR)/go-unsafe-new.Plo @@ -3039,6 +3041,13 @@ runtime.lo: runtime/runtime.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o runtime.lo `test -f 'runtime/runtime.c' || echo '$(srcdir)/'`runtime/runtime.c +signal_unix.lo: runtime/signal_unix.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signal_unix.lo -MD -MP -MF $(DEPDIR)/signal_unix.Tpo -c -o signal_unix.lo `test -f 'runtime/signal_unix.c' || echo '$(srcdir)/'`runtime/signal_unix.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/signal_unix.Tpo $(DEPDIR)/signal_unix.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/signal_unix.c' object='signal_unix.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signal_unix.lo `test -f 'runtime/signal_unix.c' || echo '$(srcdir)/'`runtime/signal_unix.c + thread.lo: runtime/thread.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT thread.lo -MD -MP -MF $(DEPDIR)/thread.Tpo -c -o thread.lo `test -f 'runtime/thread.c' || echo '$(srcdir)/'`runtime/thread.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/thread.Tpo $(DEPDIR)/thread.Plo @@ -4318,11 +4327,11 @@ runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c mv -f $@.tmp $@ sema.c: $(srcdir)/runtime/sema.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_sync $< > $@.tmp mv -f $@.tmp $@ sigqueue.c: $(srcdir)/runtime/sigqueue.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_os $< > $@.tmp mv -f $@.tmp $@ time.c: $(srcdir)/runtime/time.goc goc2c @@ -4543,10 +4552,6 @@ os/check: $(CHECK_DEPS) @$(CHECK) .PHONY: os/check -signal_unix.go: $(srcdir)/go/os/mkunixsignals.sh sysinfo.go - $(SHELL) $(srcdir)/go/os/mkunixsignals.sh sysinfo.go > $@.tmp - mv -f $@.tmp $@ - @go_include@ path/path.lo.dep path/path.lo.dep: $(go_path_files) $(BUILDDEPS) @@ -5156,16 +5161,6 @@ exp/proxy/check: $(CHECK_DEPS) @$(CHECK) .PHONY: exp/proxy/check -@go_include@ exp/signal.lo.dep -exp/signal.lo.dep: $(go_exp_signal_files) - $(BUILDDEPS) -exp/signal.lo: $(go_exp_signal_files) - $(BUILDPACKAGE) -exp/signal/check: $(CHECK_DEPS) - @$(MKDIR_P) exp/signal - @$(CHECK) -.PHONY: exp/signal/check - @go_include@ exp/terminal.lo.dep exp/terminal.lo.dep: $(go_exp_terminal_files) $(BUILDDEPS) @@ -5617,6 +5612,16 @@ os/exec/check: $(CHECK_DEPS) @$(CHECK) .PHONY: os/exec/check +@go_include@ os/signal.lo.dep +os/signal.lo.dep: $(go_os_signal_files) + $(BUILDDEPS) +os/signal.lo: $(go_os_signal_files) + $(BUILDPACKAGE) +os/signal/check: $(CHECK_DEPS) + @$(MKDIR_P) os/signal + @$(CHECK) +.PHONY: os/signal/check + @go_include@ os/user.lo.dep os/user.lo.dep: $(go_os_user_files) $(BUILDDEPS) @@ -5728,16 +5733,6 @@ testing/quick/check: $(CHECK_DEPS) @$(CHECK) .PHONY: testing/quick/check -@go_include@ testing/script.lo.dep -testing/script.lo.dep: $(go_testing_script_files) - $(BUILDDEPS) -testing/script.lo: $(go_testing_script_files) - $(BUILDPACKAGE) -testing/script/check: $(CHECK_DEPS) - @$(MKDIR_P) testing/script - @$(CHECK) -.PHONY: testing/script/check - @go_include@ unicode/utf16.lo.dep unicode/utf16.lo.dep: $(go_unicode_utf16_files) $(BUILDDEPS) @@ -5765,6 +5760,8 @@ syscall/syscall.lo: $(go_syscall_files) $(BUILDPACKAGE) syscall/errno.lo: go/syscall/errno.c $(LTCOMPILE) -c -o $@ $< +syscall/signame.lo: go/syscall/signame.c + $(LTCOMPILE) -c -o $@ $< syscall/wait.lo: go/syscall/wait.c $(LTCOMPILE) -c -o $@ $< @@ -5936,8 +5933,6 @@ exp/norm.gox: exp/norm.lo $(BUILDGOX) exp/proxy.gox: exp/proxy.lo $(BUILDGOX) -exp/signal.gox: exp/signal.lo - $(BUILDGOX) exp/terminal.gox: exp/terminal.lo $(BUILDGOX) exp/types.gox: exp/types.lo @@ -6038,6 +6033,8 @@ old/template.gox: old/template.lo os/exec.gox: os/exec.lo $(BUILDGOX) +os/signal.gox: os/signal.lo + $(BUILDGOX) os/user.gox: os/user.lo $(BUILDGOX) @@ -6068,8 +6065,6 @@ testing/iotest.gox: testing/iotest.lo $(BUILDGOX) testing/quick.gox: testing/quick.lo $(BUILDGOX) -testing/script.gox: testing/script.lo - $(BUILDGOX) unicode/utf16.gox: unicode/utf16.lo $(BUILDGOX) diff --git a/libgo/config.h.in b/libgo/config.h.in index 5318cf58c44..ccb79e187e4 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -12,6 +12,9 @@ /* Define to 1 if you have the `faccessat' function. */ #undef HAVE_FACCESSAT +/* Define to 1 if you have the `fallocate' function. */ +#undef HAVE_FALLOCATE + /* Define to 1 if you have the `fchmodat' function. */ #undef HAVE_FCHMODAT @@ -30,6 +33,9 @@ /* Define to 1 if you have the `inotify_init' function. */ #undef HAVE_INOTIFY_INIT +/* Define to 1 if you have the `inotify_init1' function. */ +#undef HAVE_INOTIFY_INIT1 + /* Define to 1 if you have the `inotify_rm_watch' function. */ #undef HAVE_INOTIFY_RM_WATCH @@ -42,6 +48,9 @@ /* Define to 1 if you have the <linux/netlink.h> header file. */ #undef HAVE_LINUX_NETLINK_H +/* Define to 1 if you have the <linux/reboot.h> header file. */ +#undef HAVE_LINUX_REBOOT_H + /* Define to 1 if you have the <linux/rtnetlink.h> header file. */ #undef HAVE_LINUX_RTNETLINK_H @@ -121,6 +130,9 @@ uint32 */ #undef HAVE_SYNC_FETCH_AND_ADD_4 +/* Define to 1 if you have the `sync_file_range' function. */ +#undef HAVE_SYNC_FILE_RANGE + /* Define to 1 if you have the <syscall.h> header file. */ #undef HAVE_SYSCALL_H @@ -130,6 +142,9 @@ /* Define to 1 if you have the <sys/mman.h> header file. */ #undef HAVE_SYS_MMAN_H +/* Define to 1 if you have the <sys/mount.h> header file. */ +#undef HAVE_SYS_MOUNT_H + /* Define to 1 if you have the <sys/prctl.h> header file. */ #undef HAVE_SYS_PRCTL_H @@ -142,12 +157,21 @@ /* Define to 1 if you have the <sys/socket.h> header file. */ #undef HAVE_SYS_SOCKET_H +/* Define to 1 if you have the <sys/statfs.h> header file. */ +#undef HAVE_SYS_STATFS_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the <sys/syscall.h> header file. */ #undef HAVE_SYS_SYSCALL_H +/* Define to 1 if you have the <sys/sysinfo.h> header file. */ +#undef HAVE_SYS_SYSINFO_H + +/* Define to 1 if you have the <sys/timex.h> header file. */ +#undef HAVE_SYS_TIMEX_H + /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H @@ -157,6 +181,9 @@ /* Define to 1 if you have the <sys/utsname.h> header file. */ #undef HAVE_SYS_UTSNAME_H +/* Define to 1 if you have the <sys/vfs.h> header file. */ +#undef HAVE_SYS_VFS_H + /* Define to 1 if you have the `tee' function. */ #undef HAVE_TEE @@ -169,6 +196,12 @@ /* Define to 1 if you have the `unshare' function. */ #undef HAVE_UNSHARE +/* Define to 1 if you have the <ustat.h> header file and it works. */ +#undef HAVE_USTAT_H + +/* Define to 1 if you have the <utime.h> header file. */ +#undef HAVE_UTIME_H + /* Define to 1 if you have the `wait4' function. */ #undef HAVE_WAIT4 @@ -235,3 +268,6 @@ # undef WORDS_BIGENDIAN # endif #endif + +/* Define to `long int' if <sys/types.h> does not define. */ +#undef off_t diff --git a/libgo/configure b/libgo/configure index 1f61cff0fc7..d1c17f10c8b 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14508,7 +14508,7 @@ no) ;; esac -for ac_header in sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h +for ac_header in sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/reboot.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -14542,6 +14542,39 @@ fi done +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether <ustat.h> can be used" >&5 +$as_echo_n "checking whether <ustat.h> can be used... " >&6; } +if test "${libgo_cv_c_ustat_h+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + CFLAGS_hold=$CFLAGS +CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE $OSCFLAGS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#ifdef HAVE_LINUX_FILTER_H +#include <linux/filter.h> +#endif +#include <ustat.h> + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libgo_cv_c_ustat_h=yes +else + libgo_cv_c_ustat_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS=$CFLAGS_hold +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_c_ustat_h" >&5 +$as_echo "$libgo_cv_c_ustat_h" >&6; } +if test $libgo_cv_c_ustat_h = yes; then + +$as_echo "#define HAVE_USTAT_H 1" >>confdefs.h + +fi + if test "$ac_cv_header_sys_mman_h" = yes; then HAVE_SYS_MMAN_H_TRUE= HAVE_SYS_MMAN_H_FALSE='#' @@ -14581,7 +14614,7 @@ else fi -for ac_func in epoll_create1 faccessat fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_rm_watch mkdirat mknodat openat renameat splice tee unlinkat unshare +for ac_func in epoll_create1 faccessat fallocate fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_init1 inotify_rm_watch mkdirat mknodat openat renameat sync_file_range splice tee unlinkat unshare do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -14594,6 +14627,17 @@ _ACEOF fi done +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = x""yes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + ac_fn_c_check_type "$LINENO" "loff_t" "ac_cv_type_loff_t" "$ac_includes_default" if test "x$ac_cv_type_loff_t" = x""yes; then : diff --git a/libgo/configure.ac b/libgo/configure.ac index 46c2b29222b..63c5faf7db6 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -453,7 +453,7 @@ no) ;; esac -AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h) +AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/reboot.h) AC_CHECK_HEADERS([linux/filter.h linux/netlink.h linux/rtnetlink.h], [], [], [#ifdef HAVE_SYS_SOCKET_H @@ -461,13 +461,32 @@ AC_CHECK_HEADERS([linux/filter.h linux/netlink.h linux/rtnetlink.h], [], [], #endif ]) +AC_CACHE_CHECK([whether <ustat.h> can be used], +[libgo_cv_c_ustat_h], +[CFLAGS_hold=$CFLAGS +CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE $OSCFLAGS" +AC_COMPILE_IFELSE( +[AC_LANG_SOURCE([ +#include <sys/types.h> +#ifdef HAVE_LINUX_FILTER_H +#include <linux/filter.h> +#endif +#include <ustat.h> +])], [libgo_cv_c_ustat_h=yes], [libgo_cv_c_ustat_h=no]) +CFLAGS=$CFLAGS_hold]) +if test $libgo_cv_c_ustat_h = yes; then + AC_DEFINE(HAVE_USTAT_H, 1, + [Define to 1 if you have the <ustat.h> header file and it works.]) +fi + AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes) AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv) AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes) AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes) -AC_CHECK_FUNCS(epoll_create1 faccessat fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_rm_watch mkdirat mknodat openat renameat splice tee unlinkat unshare) +AC_CHECK_FUNCS(epoll_create1 faccessat fallocate fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_init1 inotify_rm_watch mkdirat mknodat openat renameat sync_file_range splice tee unlinkat unshare) +AC_TYPE_OFF_T AC_CHECK_TYPES([loff_t]) CFLAGS_hold="$CFLAGS" diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go index c3009869b60..f3826dcc48d 100644 --- a/libgo/go/archive/zip/reader.go +++ b/libgo/go/archive/zip/reader.go @@ -169,48 +169,21 @@ func (r *checksumReader) Read(b []byte) (n int, err error) { func (r *checksumReader) Close() error { return r.rc.Close() } -func readFileHeader(f *File, r io.Reader) error { - var b [fileHeaderLen]byte - if _, err := io.ReadFull(r, b[:]); err != nil { - return err - } - c := binary.LittleEndian - if sig := c.Uint32(b[:4]); sig != fileHeaderSignature { - return ErrFormat - } - f.ReaderVersion = c.Uint16(b[4:6]) - f.Flags = c.Uint16(b[6:8]) - f.Method = c.Uint16(b[8:10]) - f.ModifiedTime = c.Uint16(b[10:12]) - f.ModifiedDate = c.Uint16(b[12:14]) - f.CRC32 = c.Uint32(b[14:18]) - f.CompressedSize = c.Uint32(b[18:22]) - f.UncompressedSize = c.Uint32(b[22:26]) - filenameLen := int(c.Uint16(b[26:28])) - extraLen := int(c.Uint16(b[28:30])) - d := make([]byte, filenameLen+extraLen) - if _, err := io.ReadFull(r, d); err != nil { - return err - } - f.Name = string(d[:filenameLen]) - f.Extra = d[filenameLen:] - return nil -} - // findBodyOffset does the minimum work to verify the file has a header // and returns the file body offset. func (f *File) findBodyOffset() (int64, error) { r := io.NewSectionReader(f.zipr, f.headerOffset, f.zipsize-f.headerOffset) - var b [fileHeaderLen]byte - if _, err := io.ReadFull(r, b[:]); err != nil { + var buf [fileHeaderLen]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { return 0, err } - c := binary.LittleEndian - if sig := c.Uint32(b[:4]); sig != fileHeaderSignature { + b := readBuf(buf[:]) + if sig := b.uint32(); sig != fileHeaderSignature { return 0, ErrFormat } - filenameLen := int(c.Uint16(b[26:28])) - extraLen := int(c.Uint16(b[28:30])) + b = b[22:] // skip over most of the header + filenameLen := int(b.uint16()) + extraLen := int(b.uint16()) return int64(fileHeaderLen + filenameLen + extraLen), nil } @@ -218,30 +191,29 @@ func (f *File) findBodyOffset() (int64, error) { // It returns io.ErrUnexpectedEOF if it cannot read a complete header, // and ErrFormat if it doesn't find a valid header signature. func readDirectoryHeader(f *File, r io.Reader) error { - var b [directoryHeaderLen]byte - if _, err := io.ReadFull(r, b[:]); err != nil { + var buf [directoryHeaderLen]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { return err } - c := binary.LittleEndian - if sig := c.Uint32(b[:4]); sig != directoryHeaderSignature { + b := readBuf(buf[:]) + if sig := b.uint32(); sig != directoryHeaderSignature { return ErrFormat } - f.CreatorVersion = c.Uint16(b[4:6]) - f.ReaderVersion = c.Uint16(b[6:8]) - f.Flags = c.Uint16(b[8:10]) - f.Method = c.Uint16(b[10:12]) - f.ModifiedTime = c.Uint16(b[12:14]) - f.ModifiedDate = c.Uint16(b[14:16]) - f.CRC32 = c.Uint32(b[16:20]) - f.CompressedSize = c.Uint32(b[20:24]) - f.UncompressedSize = c.Uint32(b[24:28]) - filenameLen := int(c.Uint16(b[28:30])) - extraLen := int(c.Uint16(b[30:32])) - commentLen := int(c.Uint16(b[32:34])) - // startDiskNumber := c.Uint16(b[34:36]) // Unused - // internalAttributes := c.Uint16(b[36:38]) // Unused - f.ExternalAttrs = c.Uint32(b[38:42]) - f.headerOffset = int64(c.Uint32(b[42:46])) + f.CreatorVersion = b.uint16() + f.ReaderVersion = b.uint16() + f.Flags = b.uint16() + f.Method = b.uint16() + f.ModifiedTime = b.uint16() + f.ModifiedDate = b.uint16() + f.CRC32 = b.uint32() + f.CompressedSize = b.uint32() + f.UncompressedSize = b.uint32() + filenameLen := int(b.uint16()) + extraLen := int(b.uint16()) + commentLen := int(b.uint16()) + b = b[4:] // skipped start disk number and internal attributes (2x uint16) + f.ExternalAttrs = b.uint32() + f.headerOffset = int64(b.uint32()) d := make([]byte, filenameLen+extraLen+commentLen) if _, err := io.ReadFull(r, d); err != nil { return err @@ -253,30 +225,30 @@ func readDirectoryHeader(f *File, r io.Reader) error { } func readDataDescriptor(r io.Reader, f *File) error { - var b [dataDescriptorLen]byte - if _, err := io.ReadFull(r, b[:]); err != nil { + var buf [dataDescriptorLen]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { return err } - c := binary.LittleEndian - f.CRC32 = c.Uint32(b[:4]) - f.CompressedSize = c.Uint32(b[4:8]) - f.UncompressedSize = c.Uint32(b[8:12]) + b := readBuf(buf[:]) + f.CRC32 = b.uint32() + f.CompressedSize = b.uint32() + f.UncompressedSize = b.uint32() return nil } func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) { // look for directoryEndSignature in the last 1k, then in the last 65k - var b []byte + var buf []byte for i, bLen := range []int64{1024, 65 * 1024} { if bLen > size { bLen = size } - b = make([]byte, int(bLen)) - if _, err := r.ReadAt(b, size-bLen); err != nil && err != io.EOF { + buf = make([]byte, int(bLen)) + if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF { return nil, err } - if p := findSignatureInBlock(b); p >= 0 { - b = b[p:] + if p := findSignatureInBlock(buf); p >= 0 { + buf = buf[p:] break } if i == 1 || bLen == size { @@ -285,16 +257,21 @@ func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) } // read header into struct - c := binary.LittleEndian - d := new(directoryEnd) - d.diskNbr = c.Uint16(b[4:6]) - d.dirDiskNbr = c.Uint16(b[6:8]) - d.dirRecordsThisDisk = c.Uint16(b[8:10]) - d.directoryRecords = c.Uint16(b[10:12]) - d.directorySize = c.Uint32(b[12:16]) - d.directoryOffset = c.Uint32(b[16:20]) - d.commentLen = c.Uint16(b[20:22]) - d.comment = string(b[22 : 22+int(d.commentLen)]) + b := readBuf(buf[4:]) // skip signature + d := &directoryEnd{ + diskNbr: b.uint16(), + dirDiskNbr: b.uint16(), + dirRecordsThisDisk: b.uint16(), + directoryRecords: b.uint16(), + directorySize: b.uint32(), + directoryOffset: b.uint32(), + commentLen: b.uint16(), + } + l := int(d.commentLen) + if l > len(b) { + return nil, errors.New("zip: invalid comment length") + } + d.comment = string(b[:l]) return d, nil } @@ -311,3 +288,17 @@ func findSignatureInBlock(b []byte) int { } return -1 } + +type readBuf []byte + +func (b *readBuf) uint16() uint16 { + v := binary.LittleEndian.Uint16(*b) + *b = (*b)[2:] + return v +} + +func (b *readBuf) uint32() uint32 { + v := binary.LittleEndian.Uint32(*b) + *b = (*b)[4:] + return v +} diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go index 935860e791e..066a61580c5 100644 --- a/libgo/go/archive/zip/reader_test.go +++ b/libgo/go/archive/zip/reader_test.go @@ -165,7 +165,7 @@ func readTestZip(t *testing.T, zt ZipTest) { t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment) } if len(z.File) != len(zt.File) { - t.Errorf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File)) + t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File)) } // test read of each file @@ -278,7 +278,7 @@ func TestInvalidFiles(t *testing.T) { b := make([]byte, size) // zeroes - _, err := NewReader(sliceReaderAt(b), size) + _, err := NewReader(bytes.NewReader(b), size) if err != ErrFormat { t.Errorf("zeroes: error=%v, want %v", err, ErrFormat) } @@ -289,15 +289,8 @@ func TestInvalidFiles(t *testing.T) { for i := 0; i < size-4; i += 4 { copy(b[i:i+4], sig) } - _, err = NewReader(sliceReaderAt(b), size) + _, err = NewReader(bytes.NewReader(b), size) if err != ErrFormat { t.Errorf("sigs: error=%v, want %v", err, ErrFormat) } } - -type sliceReaderAt []byte - -func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) { - copy(b, r[int(off):int(off)+len(b)]) - return len(b), nil -} diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go index 35dcec6468b..fdbd16da048 100644 --- a/libgo/go/archive/zip/struct.go +++ b/libgo/go/archive/zip/struct.go @@ -100,16 +100,6 @@ type directoryEnd struct { comment string } -func recoverError(errp *error) { - if e := recover(); e != nil { - if err, ok := e.(error); ok { - *errp = err - return - } - panic(e) - } -} - // msDosTimeToTime converts an MS-DOS date and time into a time.Time. // The resolution is 2s. // See: http://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx diff --git a/libgo/go/archive/zip/writer.go b/libgo/go/archive/zip/writer.go index a4f0654474a..b2cc55bc93b 100644 --- a/libgo/go/archive/zip/writer.go +++ b/libgo/go/archive/zip/writer.go @@ -19,7 +19,7 @@ import ( // Writer implements a zip file writer. type Writer struct { - countWriter + cw *countWriter dir []*header last *fileWriter closed bool @@ -32,15 +32,15 @@ type header struct { // NewWriter returns a new Writer writing a zip file to w. func NewWriter(w io.Writer) *Writer { - return &Writer{countWriter: countWriter{w: bufio.NewWriter(w)}} + return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}} } // Close finishes writing the zip file by writing the central directory. // It does not (and can not) close the underlying writer. -func (w *Writer) Close() (err error) { +func (w *Writer) Close() error { if w.last != nil && !w.last.closed { - if err = w.last.close(); err != nil { - return + if err := w.last.close(); err != nil { + return err } w.last = nil } @@ -49,45 +49,57 @@ func (w *Writer) Close() (err error) { } w.closed = true - defer recoverError(&err) - // write central directory - start := w.count + start := w.cw.count for _, h := range w.dir { - write(w, uint32(directoryHeaderSignature)) - write(w, h.CreatorVersion) - write(w, h.ReaderVersion) - write(w, h.Flags) - write(w, h.Method) - write(w, h.ModifiedTime) - write(w, h.ModifiedDate) - write(w, h.CRC32) - write(w, h.CompressedSize) - write(w, h.UncompressedSize) - write(w, uint16(len(h.Name))) - write(w, uint16(len(h.Extra))) - write(w, uint16(len(h.Comment))) - write(w, uint16(0)) // disk number start - write(w, uint16(0)) // internal file attributes - write(w, h.ExternalAttrs) - write(w, h.offset) - writeBytes(w, []byte(h.Name)) - writeBytes(w, h.Extra) - writeBytes(w, []byte(h.Comment)) + var buf [directoryHeaderLen]byte + b := writeBuf(buf[:]) + b.uint32(uint32(directoryHeaderSignature)) + b.uint16(h.CreatorVersion) + b.uint16(h.ReaderVersion) + b.uint16(h.Flags) + b.uint16(h.Method) + b.uint16(h.ModifiedTime) + b.uint16(h.ModifiedDate) + b.uint32(h.CRC32) + b.uint32(h.CompressedSize) + b.uint32(h.UncompressedSize) + b.uint16(uint16(len(h.Name))) + b.uint16(uint16(len(h.Extra))) + b.uint16(uint16(len(h.Comment))) + b = b[4:] // skip disk number start and internal file attr (2x uint16) + b.uint32(h.ExternalAttrs) + b.uint32(h.offset) + if _, err := w.cw.Write(buf[:]); err != nil { + return err + } + if _, err := io.WriteString(w.cw, h.Name); err != nil { + return err + } + if _, err := w.cw.Write(h.Extra); err != nil { + return err + } + if _, err := io.WriteString(w.cw, h.Comment); err != nil { + return err + } } - end := w.count + end := w.cw.count // write end record - write(w, uint32(directoryEndSignature)) - write(w, uint16(0)) // disk number - write(w, uint16(0)) // disk number where directory starts - write(w, uint16(len(w.dir))) // number of entries this disk - write(w, uint16(len(w.dir))) // number of entries total - write(w, uint32(end-start)) // size of directory - write(w, uint32(start)) // start of directory - write(w, uint16(0)) // size of comment + var buf [directoryEndLen]byte + b := writeBuf(buf[:]) + b.uint32(uint32(directoryEndSignature)) + b = b[4:] // skip over disk number and first disk number (2x uint16) + b.uint16(uint16(len(w.dir))) // number of entries this disk + b.uint16(uint16(len(w.dir))) // number of entries total + b.uint32(uint32(end - start)) // size of directory + b.uint32(uint32(start)) // start of directory + // skipped size of comment (always zero) + if _, err := w.cw.Write(buf[:]); err != nil { + return err + } - return w.w.(*bufio.Writer).Flush() + return w.cw.w.(*bufio.Writer).Flush() } // Create adds a file to the zip file using the provided name. @@ -119,15 +131,19 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) { fh.ReaderVersion = 0x14 fw := &fileWriter{ - zipw: w, - compCount: &countWriter{w: w}, + zipw: w.cw, + compCount: &countWriter{w: w.cw}, crc32: crc32.NewIEEE(), } switch fh.Method { case Store: fw.comp = nopCloser{fw.compCount} case Deflate: - fw.comp = flate.NewWriter(fw.compCount, 5) + var err error + fw.comp, err = flate.NewWriter(fw.compCount, 5) + if err != nil { + return nil, err + } default: return nil, ErrAlgorithm } @@ -135,12 +151,12 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) { h := &header{ FileHeader: fh, - offset: uint32(w.count), + offset: uint32(w.cw.count), } w.dir = append(w.dir, h) fw.header = h - if err := writeHeader(w, fh); err != nil { + if err := writeHeader(w.cw, fh); err != nil { return nil, err } @@ -148,22 +164,28 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) { return fw, nil } -func writeHeader(w io.Writer, h *FileHeader) (err error) { - defer recoverError(&err) - write(w, uint32(fileHeaderSignature)) - write(w, h.ReaderVersion) - write(w, h.Flags) - write(w, h.Method) - write(w, h.ModifiedTime) - write(w, h.ModifiedDate) - write(w, h.CRC32) - write(w, h.CompressedSize) - write(w, h.UncompressedSize) - write(w, uint16(len(h.Name))) - write(w, uint16(len(h.Extra))) - writeBytes(w, []byte(h.Name)) - writeBytes(w, h.Extra) - return nil +func writeHeader(w io.Writer, h *FileHeader) error { + var buf [fileHeaderLen]byte + b := writeBuf(buf[:]) + b.uint32(uint32(fileHeaderSignature)) + b.uint16(h.ReaderVersion) + b.uint16(h.Flags) + b.uint16(h.Method) + b.uint16(h.ModifiedTime) + b.uint16(h.ModifiedDate) + b.uint32(h.CRC32) + b.uint32(h.CompressedSize) + b.uint32(h.UncompressedSize) + b.uint16(uint16(len(h.Name))) + b.uint16(uint16(len(h.Extra))) + if _, err := w.Write(buf[:]); err != nil { + return err + } + if _, err := io.WriteString(w, h.Name); err != nil { + return err + } + _, err := w.Write(h.Extra) + return err } type fileWriter struct { @@ -184,13 +206,13 @@ func (w *fileWriter) Write(p []byte) (int, error) { return w.rawCount.Write(p) } -func (w *fileWriter) close() (err error) { +func (w *fileWriter) close() error { if w.closed { return errors.New("zip: file closed twice") } w.closed = true - if err = w.comp.Close(); err != nil { - return + if err := w.comp.Close(); err != nil { + return err } // update FileHeader @@ -200,12 +222,13 @@ func (w *fileWriter) close() (err error) { fh.UncompressedSize = uint32(w.rawCount.count) // write data descriptor - defer recoverError(&err) - write(w.zipw, fh.CRC32) - write(w.zipw, fh.CompressedSize) - write(w.zipw, fh.UncompressedSize) - - return nil + var buf [dataDescriptorLen]byte + b := writeBuf(buf[:]) + b.uint32(fh.CRC32) + b.uint32(fh.CompressedSize) + b.uint32(fh.UncompressedSize) + _, err := w.zipw.Write(buf[:]) + return err } type countWriter struct { @@ -227,18 +250,14 @@ func (w nopCloser) Close() error { return nil } -func write(w io.Writer, data interface{}) { - if err := binary.Write(w, binary.LittleEndian, data); err != nil { - panic(err) - } +type writeBuf []byte + +func (b *writeBuf) uint16(v uint16) { + binary.LittleEndian.PutUint16(*b, v) + *b = (*b)[2:] } -func writeBytes(w io.Writer, b []byte) { - n, err := w.Write(b) - if err != nil { - panic(err) - } - if n != len(b) { - panic(io.ErrShortWrite) - } +func (b *writeBuf) uint32(v uint32) { + binary.LittleEndian.PutUint32(*b, v) + *b = (*b)[4:] } diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go index ce93fae19e5..88e5211ff7b 100644 --- a/libgo/go/archive/zip/writer_test.go +++ b/libgo/go/archive/zip/writer_test.go @@ -77,7 +77,7 @@ func TestWriter(t *testing.T) { } // read it back - r, err := NewReader(sliceReaderAt(buf.Bytes()), int64(buf.Len())) + r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len())) if err != nil { t.Fatal(err) } diff --git a/libgo/go/archive/zip/zip_test.go b/libgo/go/archive/zip/zip_test.go index 1a260cc569f..d6490c4cbbe 100644 --- a/libgo/go/archive/zip/zip_test.go +++ b/libgo/go/archive/zip/zip_test.go @@ -9,22 +9,12 @@ package zip import ( "bytes" "fmt" - "io" "reflect" + "strings" "testing" "time" ) -type stringReaderAt string - -func (s stringReaderAt) ReadAt(p []byte, off int64) (n int, err error) { - if off >= int64(len(s)) { - return 0, io.EOF - } - n = copy(p, s[off:]) - return -} - func TestOver65kFiles(t *testing.T) { if testing.Short() { t.Logf("slow test; skipping") @@ -42,8 +32,8 @@ func TestOver65kFiles(t *testing.T) { if err := w.Close(); err != nil { t.Fatalf("Writer.Close: %v", err) } - rat := stringReaderAt(buf.String()) - zr, err := NewReader(rat, int64(len(rat))) + s := buf.String() + zr, err := NewReader(strings.NewReader(s), int64(len(s))) if err != nil { t.Fatalf("NewReader: %v", err) } diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index 156dddfcf07..b44d0e7d167 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -23,7 +23,6 @@ var ( ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune") ErrBufferFull = errors.New("bufio: buffer full") ErrNegativeCount = errors.New("bufio: negative count") - errInternal = errors.New("bufio: internal error") ) // Buffered input. @@ -106,9 +105,12 @@ func (b *Reader) Peek(n int) ([]byte, error) { if m > n { m = n } - err := b.readErr() - if m < n && err == nil { - err = ErrBufferFull + var err error + if m < n { + err = b.readErr() + if err == nil { + err = ErrBufferFull + } } return b.buf[b.r : b.r+m], err } diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 9aec61ec426..a43cbd23a64 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -539,6 +539,27 @@ func TestPeek(t *testing.T) { if _, err := buf.Peek(1); err != io.EOF { t.Fatalf("want EOF got %v", err) } + + // Test for issue 3022, not exposing a reader's error on a successful Peek. + buf = NewReaderSize(dataAndEOFReader("abcd"), 32) + if s, err := buf.Peek(2); string(s) != "ab" || err != nil { + t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err) + } + if s, err := buf.Peek(4); string(s) != "abcd" || err != nil { + t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err) + } + if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil { + t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err) + } + if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF { + t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err) + } +} + +type dataAndEOFReader string + +func (r dataAndEOFReader) Read(p []byte) (int, error) { + return copy(p, r), io.EOF } func TestPeekThenUnreadRune(t *testing.T) { diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go index a95c2afd005..afdf2205598 100644 --- a/libgo/go/bytes/buffer.go +++ b/libgo/go/bytes/buffer.go @@ -182,14 +182,21 @@ func makeSlice(n int) []byte { func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) { b.lastRead = opInvalid if b.off < len(b.buf) { + nBytes := b.Len() m, e := w.Write(b.buf[b.off:]) + if m > nBytes { + panic("bytes.Buffer.WriteTo: invalid Write count") + } b.off += m n = int64(m) if e != nil { return n, e } - // otherwise all bytes were written, by definition of + // all bytes should have been written, by definition of // Write method in io.Writer + if m != nBytes { + return n, io.ErrShortWrite + } } // Buffer is now empty; reset. b.Truncate(0) diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index e94a0ec5c4f..7d1426fb417 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -13,6 +13,7 @@ import ( // Compare returns an integer comparing the two byte arrays lexicographically. // The result will be 0 if a==b, -1 if a < b, and +1 if a > b +// A nil argument is equivalent to an empty slice. func Compare(a, b []byte) int { m := len(a) if m > len(b) { @@ -37,6 +38,7 @@ func Compare(a, b []byte) int { } // Equal returns a boolean reporting whether a == b. +// A nil argument is equivalent to an empty slice. func Equal(a, b []byte) bool func equalPortable(a, b []byte) bool { diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go index 2a1d41b910e..000f235176d 100644 --- a/libgo/go/bytes/bytes_test.go +++ b/libgo/go/bytes/bytes_test.go @@ -46,32 +46,39 @@ type BinOpTest struct { i int } -var comparetests = []BinOpTest{ - {"", "", 0}, - {"a", "", 1}, - {"", "a", -1}, - {"abc", "abc", 0}, - {"ab", "abc", -1}, - {"abc", "ab", 1}, - {"x", "ab", 1}, - {"ab", "x", -1}, - {"x", "a", 1}, - {"b", "x", -1}, +var compareTests = []struct { + a, b []byte + i int +}{ + {[]byte(""), []byte(""), 0}, + {[]byte("a"), []byte(""), 1}, + {[]byte(""), []byte("a"), -1}, + {[]byte("abc"), []byte("abc"), 0}, + {[]byte("ab"), []byte("abc"), -1}, + {[]byte("abc"), []byte("ab"), 1}, + {[]byte("x"), []byte("ab"), 1}, + {[]byte("ab"), []byte("x"), -1}, + {[]byte("x"), []byte("a"), 1}, + {[]byte("b"), []byte("x"), -1}, + // nil tests + {nil, nil, 0}, + {[]byte(""), nil, 0}, + {nil, []byte(""), 0}, + {[]byte("a"), nil, 1}, + {nil, []byte("a"), -1}, } func TestCompare(t *testing.T) { - for _, tt := range comparetests { - a := []byte(tt.a) - b := []byte(tt.b) - cmp := Compare(a, b) + for _, tt := range compareTests { + cmp := Compare(tt.a, tt.b) if cmp != tt.i { t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp) } - eql := Equal(a, b) + eql := Equal(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql) } - eql = EqualPortable(a, b) + eql = EqualPortable(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql) } diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go index 0234a012a4e..6fe8cd5a90c 100644 --- a/libgo/go/bytes/example_test.go +++ b/libgo/go/bytes/example_test.go @@ -11,18 +11,18 @@ import ( "os" ) -// Hello world! func ExampleBuffer() { var b Buffer // A Buffer needs no initialization. b.Write([]byte("Hello ")) b.Write([]byte("world!")) b.WriteTo(os.Stdout) + // Output: Hello world! } -// Gophers rule! func ExampleBuffer_reader() { // A Buffer can turn a string or a []byte into an io.Reader. buf := NewBufferString("R29waGVycyBydWxlIQ==") dec := base64.NewDecoder(base64.StdEncoding, buf) io.Copy(os.Stdout, dec) + // Output: Gophers rule! } diff --git a/libgo/go/bytes/reader.go b/libgo/go/bytes/reader.go new file mode 100644 index 00000000000..a062e54ba4d --- /dev/null +++ b/libgo/go/bytes/reader.go @@ -0,0 +1,125 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytes + +import ( + "errors" + "io" + "unicode/utf8" +) + +// A Reader implements the io.Reader, io.ReaderAt, io.Seeker, +// io.ByteScanner, and io.RuneScanner interfaces by reading from +// a byte slice. +// Unlike a Buffer, a Reader is read-only and supports seeking. +type Reader struct { + s []byte + i int // current reading index + prevRune int // index of previous rune; or < 0 +} + +// Len returns the number of bytes of the unread portion of the +// slice. +func (r *Reader) Len() int { + if r.i >= len(r.s) { + return 0 + } + return len(r.s) - r.i +} + +func (r *Reader) Read(b []byte) (n int, err error) { + if len(b) == 0 { + return 0, nil + } + if r.i >= len(r.s) { + return 0, io.EOF + } + n = copy(b, r.s[r.i:]) + r.i += n + r.prevRune = -1 + return +} + +func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) { + if off < 0 { + return 0, errors.New("bytes: invalid offset") + } + if off >= int64(len(r.s)) { + return 0, io.EOF + } + n = copy(b, r.s[int(off):]) + if n < len(b) { + err = io.EOF + } + return +} + +func (r *Reader) ReadByte() (b byte, err error) { + if r.i >= len(r.s) { + return 0, io.EOF + } + b = r.s[r.i] + r.i++ + r.prevRune = -1 + return +} + +func (r *Reader) UnreadByte() error { + if r.i <= 0 { + return errors.New("bytes.Reader: at beginning of slice") + } + r.i-- + r.prevRune = -1 + return nil +} + +func (r *Reader) ReadRune() (ch rune, size int, err error) { + if r.i >= len(r.s) { + return 0, 0, io.EOF + } + r.prevRune = r.i + if c := r.s[r.i]; c < utf8.RuneSelf { + r.i++ + return rune(c), 1, nil + } + ch, size = utf8.DecodeRune(r.s[r.i:]) + r.i += size + return +} + +func (r *Reader) UnreadRune() error { + if r.prevRune < 0 { + return errors.New("bytes.Reader: previous operation was not ReadRune") + } + r.i = r.prevRune + r.prevRune = -1 + return nil +} + +// Seek implements the io.Seeker interface. +func (r *Reader) Seek(offset int64, whence int) (int64, error) { + var abs int64 + switch whence { + case 0: + abs = offset + case 1: + abs = int64(r.i) + offset + case 2: + abs = int64(len(r.s)) + offset + default: + return 0, errors.New("bytes: invalid whence") + } + if abs < 0 { + return 0, errors.New("bytes: negative position") + } + if abs >= 1<<31 { + return 0, errors.New("bytes: position out of range") + } + r.i = int(abs) + return abs, nil +} + +// NewReader returns a new Reader reading from b. +func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} } diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go new file mode 100644 index 00000000000..2e4b1f26e81 --- /dev/null +++ b/libgo/go/bytes/reader_test.go @@ -0,0 +1,88 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytes_test + +import ( + . "bytes" + "fmt" + "io" + "os" + "testing" +) + +func TestReader(t *testing.T) { + r := NewReader([]byte("0123456789")) + tests := []struct { + off int64 + seek int + n int + want string + wantpos int64 + seekerr string + }{ + {seek: os.SEEK_SET, off: 0, n: 20, want: "0123456789"}, + {seek: os.SEEK_SET, off: 1, n: 1, want: "1"}, + {seek: os.SEEK_CUR, off: 1, wantpos: 3, n: 2, want: "34"}, + {seek: os.SEEK_SET, off: -1, seekerr: "bytes: negative position"}, + {seek: os.SEEK_SET, off: 1<<31 - 1}, + {seek: os.SEEK_CUR, off: 1, seekerr: "bytes: position out of range"}, + {seek: os.SEEK_SET, n: 5, want: "01234"}, + {seek: os.SEEK_CUR, n: 5, want: "56789"}, + {seek: os.SEEK_END, off: -1, n: 1, wantpos: 9, want: "9"}, + } + + for i, tt := range tests { + pos, err := r.Seek(tt.off, tt.seek) + if err == nil && tt.seekerr != "" { + t.Errorf("%d. want seek error %q", i, tt.seekerr) + continue + } + if err != nil && err.Error() != tt.seekerr { + t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr) + continue + } + if tt.wantpos != 0 && tt.wantpos != pos { + t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos) + } + buf := make([]byte, tt.n) + n, err := r.Read(buf) + if err != nil { + t.Errorf("%d. read = %v", i, err) + continue + } + got := string(buf[:n]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + } +} + +func TestReaderAt(t *testing.T) { + r := NewReader([]byte("0123456789")) + tests := []struct { + off int64 + n int + want string + wanterr interface{} + }{ + {0, 10, "0123456789", nil}, + {1, 10, "123456789", io.EOF}, + {1, 9, "123456789", nil}, + {11, 10, "", io.EOF}, + {0, 0, "", nil}, + {-1, 0, "", "bytes: invalid offset"}, + } + for i, tt := range tests { + b := make([]byte, tt.n) + rn, err := r.ReadAt(b, tt.off) + got := string(b[:rn]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) { + t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr) + } + } +} diff --git a/libgo/go/compress/flate/deflate.go b/libgo/go/compress/flate/deflate.go index 8505da706c9..20408409c8e 100644 --- a/libgo/go/compress/flate/deflate.go +++ b/libgo/go/compress/flate/deflate.go @@ -5,6 +5,7 @@ package flate import ( + "fmt" "io" "math" ) @@ -390,7 +391,7 @@ func (d *compressor) init(w io.Writer, level int) (err error) { d.fill = (*compressor).fillDeflate d.step = (*compressor).deflate default: - return WrongValueError{"level", 0, 9, int32(level)} + return fmt.Errorf("flate: invalid compression level %d: want value in range [-1, 9]", level) } return nil } @@ -408,17 +409,22 @@ func (d *compressor) close() error { return d.w.err } -// NewWriter returns a new Writer compressing -// data at the given level. Following zlib, levels -// range from 1 (BestSpeed) to 9 (BestCompression); -// higher levels typically run slower but compress more. -// Level 0 (NoCompression) does not attempt any -// compression; it only adds the necessary DEFLATE framing. -func NewWriter(w io.Writer, level int) *Writer { +// NewWriter returns a new Writer compressing data at the given level. +// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression); +// higher levels typically run slower but compress more. Level 0 +// (NoCompression) does not attempt any compression; it only adds the +// necessary DEFLATE framing. Level -1 (DefaultCompression) uses the default +// compression level. +// +// If level is in the range [-1, 9] then the error returned will be nil. +// Otherwise the error returned will be non-nil. +func NewWriter(w io.Writer, level int) (*Writer, error) { const logWindowSize = logMaxOffsetSize var dw Writer - dw.d.init(w, level) - return &dw + if err := dw.d.init(w, level); err != nil { + return nil, err + } + return &dw, nil } // NewWriterDict is like NewWriter but initializes the new @@ -427,13 +433,16 @@ func NewWriter(w io.Writer, level int) *Writer { // any compressed output. The compressed data written to w // can only be decompressed by a Reader initialized with the // same dictionary. -func NewWriterDict(w io.Writer, level int, dict []byte) *Writer { +func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { dw := &dictWriter{w, false} - zw := NewWriter(dw, level) + zw, err := NewWriter(dw, level) + if err != nil { + return nil, err + } zw.Write(dict) zw.Flush() dw.enabled = true - return zw + return zw, err } type dictWriter struct { diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index 75d801df405..543c5950586 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -81,7 +81,11 @@ func largeDataChunk() []byte { func TestDeflate(t *testing.T) { for _, h := range deflateTests { var buf bytes.Buffer - w := NewWriter(&buf, h.level) + w, err := NewWriter(&buf, h.level) + if err != nil { + t.Errorf("NewWriter: %v", err) + continue + } w.Write(h.in) w.Close() if !bytes.Equal(buf.Bytes(), h.out) { @@ -151,7 +155,11 @@ func testSync(t *testing.T, level int, input []byte, name string) { buf := newSyncBuffer() buf1 := new(bytes.Buffer) buf.WriteMode() - w := NewWriter(io.MultiWriter(buf, buf1), level) + w, err := NewWriter(io.MultiWriter(buf, buf1), level) + if err != nil { + t.Errorf("NewWriter: %v", err) + return + } r := NewReader(buf) // Write half the input and read back. @@ -213,7 +221,7 @@ func testSync(t *testing.T, level int, input []byte, name string) { // stream should work for ordinary reader too r = NewReader(buf1) - out, err := ioutil.ReadAll(r) + out, err = ioutil.ReadAll(r) if err != nil { t.Errorf("testSync: read: %s", err) return @@ -224,31 +232,31 @@ func testSync(t *testing.T, level int, input []byte, name string) { } } -func testToFromWithLevel(t *testing.T, level int, input []byte, name string) error { - return testToFromWithLevelAndLimit(t, level, input, name, -1) -} - -func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) error { +func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) { var buffer bytes.Buffer - w := NewWriter(&buffer, level) + w, err := NewWriter(&buffer, level) + if err != nil { + t.Errorf("NewWriter: %v", err) + return + } w.Write(input) w.Close() if limit > 0 && buffer.Len() > limit { t.Errorf("level: %d, len(compress(data)) = %d > limit = %d", level, buffer.Len(), limit) + return } r := NewReader(&buffer) out, err := ioutil.ReadAll(r) if err != nil { t.Errorf("read: %s", err) - return err + return } r.Close() if !bytes.Equal(input, out) { t.Errorf("decompress(compress(data)) != data: level=%d input=%s", level, name) + return } - testSync(t, level, input, name) - return nil } func testToFromWithLimit(t *testing.T, input []byte, name string, limit [10]int) { @@ -257,13 +265,9 @@ func testToFromWithLimit(t *testing.T, input []byte, name string, limit [10]int) } } -func testToFrom(t *testing.T, input []byte, name string) { - testToFromWithLimit(t, input, name, [10]int{}) -} - func TestDeflateInflate(t *testing.T) { for i, h := range deflateInflateTests { - testToFrom(t, h.in, fmt.Sprintf("#%d", i)) + testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [10]int{}) } } @@ -302,6 +306,9 @@ func TestDeflateInflateString(t *testing.T) { t.Error(err) } testToFromWithLimit(t, gold, test.label, test.limit) + if testing.Short() { + break + } } } @@ -311,7 +318,10 @@ func TestReaderDict(t *testing.T) { text = "hello again world" ) var b bytes.Buffer - w := NewWriter(&b, 5) + w, err := NewWriter(&b, 5) + if err != nil { + t.Fatalf("NewWriter: %v", err) + } w.Write([]byte(dict)) w.Flush() b.Reset() @@ -334,7 +344,10 @@ func TestWriterDict(t *testing.T) { text = "hello again world" ) var b bytes.Buffer - w := NewWriter(&b, 5) + w, err := NewWriter(&b, 5) + if err != nil { + t.Fatalf("NewWriter: %v", err) + } w.Write([]byte(dict)) w.Flush() b.Reset() @@ -342,7 +355,7 @@ func TestWriterDict(t *testing.T) { w.Close() var b1 bytes.Buffer - w = NewWriterDict(&b1, 5, []byte(dict)) + w, _ = NewWriterDict(&b1, 5, []byte(dict)) w.Write([]byte(text)) w.Close() @@ -353,7 +366,14 @@ func TestWriterDict(t *testing.T) { // See http://code.google.com/p/go/issues/detail?id=2508 func TestRegression2508(t *testing.T) { - w := NewWriter(ioutil.Discard, 1) + if testing.Short() { + t.Logf("test disabled with -short") + return + } + w, err := NewWriter(ioutil.Discard, 1) + if err != nil { + t.Fatalf("NewWriter: %v", err) + } buf := make([]byte, 1024) for i := 0; i < 131072; i++ { if _, err := w.Write(buf); err != nil { diff --git a/libgo/go/compress/flate/huffman_bit_writer.go b/libgo/go/compress/flate/huffman_bit_writer.go index 57b56b5c96d..25e1da336aa 100644 --- a/libgo/go/compress/flate/huffman_bit_writer.go +++ b/libgo/go/compress/flate/huffman_bit_writer.go @@ -7,7 +7,6 @@ package flate import ( "io" "math" - "strconv" ) const ( @@ -85,13 +84,6 @@ type huffmanBitWriter struct { err error } -type WrongValueError struct { - name string - from int32 - to int32 - value int32 -} - func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter { return &huffmanBitWriter{ w: w, @@ -105,11 +97,6 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter { } } -func (err WrongValueError) Error() string { - return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.FormatInt(int64(err.from), 10) + ";" + - strconv.FormatInt(int64(err.to), 10) + "] but actual value is " + strconv.FormatInt(int64(err.value), 10) -} - func (w *huffmanBitWriter) flushBits() { if w.err != nil { w.nbits = 0 diff --git a/libgo/go/compress/gzip/gunzip.go b/libgo/go/compress/gzip/gunzip.go index d3743105d18..33736f63508 100644 --- a/libgo/go/compress/gzip/gunzip.go +++ b/libgo/go/compress/gzip/gunzip.go @@ -16,9 +16,6 @@ import ( "time" ) -// BUG(nigeltao): Comments and Names don't properly map UTF-8 character codes outside of -// the 0x00-0x7f range to ISO 8859-1 (Latin-1). - const ( gzipID1 = 0x1f gzipID2 = 0x8b @@ -37,11 +34,15 @@ func makeReader(r io.Reader) flate.Reader { return bufio.NewReader(r) } -var ErrHeader = errors.New("invalid gzip header") -var ErrChecksum = errors.New("gzip checksum error") +var ( + // ErrChecksum is returned when reading GZIP data that has an invalid checksum. + ErrChecksum = errors.New("gzip: invalid checksum") + // ErrHeader is returned when reading GZIP data that has an invalid header. + ErrHeader = errors.New("gzip: invalid header") +) // The gzip file stores a header giving metadata about the compressed file. -// That header is exposed as the fields of the Compressor and Decompressor structs. +// That header is exposed as the fields of the Writer and Reader structs. type Header struct { Comment string // comment Extra []byte // "extra data" @@ -50,21 +51,21 @@ type Header struct { OS byte // operating system type } -// An Decompressor is an io.Reader that can be read to retrieve +// A Reader is an io.Reader that can be read to retrieve // uncompressed data from a gzip-format compressed file. // // In general, a gzip file can be a concatenation of gzip files, -// each with its own header. Reads from the Decompressor +// each with its own header. Reads from the Reader // return the concatenation of the uncompressed data of each. -// Only the first header is recorded in the Decompressor fields. +// Only the first header is recorded in the Reader fields. // // Gzip files store a length and checksum of the uncompressed data. -// The Decompressor will return a ErrChecksum when Read +// The Reader will return a ErrChecksum when Read // reaches the end of the uncompressed data if it does not // have the expected length or checksum. Clients should treat data -// returned by Read as tentative until they receive the successful -// (zero length, nil error) Read marking the end of the data. -type Decompressor struct { +// returned by Read as tentative until they receive the io.EOF +// marking the end of the data. +type Reader struct { Header r flate.Reader decompressor io.ReadCloser @@ -75,15 +76,14 @@ type Decompressor struct { err error } -// NewReader creates a new Decompressor reading the given reader. +// NewReader creates a new Reader reading the given reader. // The implementation buffers input and may read more data than necessary from r. -// It is the caller's responsibility to call Close on the Decompressor when done. -func NewReader(r io.Reader) (*Decompressor, error) { - z := new(Decompressor) +// It is the caller's responsibility to call Close on the Reader when done. +func NewReader(r io.Reader) (*Reader, error) { + z := new(Reader) z.r = makeReader(r) z.digest = crc32.NewIEEE() if err := z.readHeader(true); err != nil { - z.err = err return nil, err } return z, nil @@ -94,7 +94,7 @@ func get4(p []byte) uint32 { return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 } -func (z *Decompressor) readString() (string, error) { +func (z *Reader) readString() (string, error) { var err error needconv := false for i := 0; ; i++ { @@ -123,7 +123,7 @@ func (z *Decompressor) readString() (string, error) { panic("not reached") } -func (z *Decompressor) read2() (uint32, error) { +func (z *Reader) read2() (uint32, error) { _, err := io.ReadFull(z.r, z.buf[0:2]) if err != nil { return 0, err @@ -131,7 +131,7 @@ func (z *Decompressor) read2() (uint32, error) { return uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil } -func (z *Decompressor) readHeader(save bool) error { +func (z *Reader) readHeader(save bool) error { _, err := io.ReadFull(z.r, z.buf[0:10]) if err != nil { return err @@ -197,7 +197,7 @@ func (z *Decompressor) readHeader(save bool) error { return nil } -func (z *Decompressor) Read(p []byte) (n int, err error) { +func (z *Reader) Read(p []byte) (n int, err error) { if z.err != nil { return 0, z.err } @@ -237,5 +237,5 @@ func (z *Decompressor) Read(p []byte) (n int, err error) { return z.Read(p) } -// Calling Close does not close the wrapped io.Reader originally passed to NewReader. -func (z *Decompressor) Close() error { return z.decompressor.Close() } +// Close closes the Reader. It does not close the underlying io.Reader. +func (z *Reader) Close() error { return z.decompressor.Close() } diff --git a/libgo/go/compress/gzip/gzip.go b/libgo/go/compress/gzip/gzip.go index f2639a688c1..3035dfffccf 100644 --- a/libgo/go/compress/gzip/gzip.go +++ b/libgo/go/compress/gzip/gzip.go @@ -7,6 +7,7 @@ package gzip import ( "compress/flate" "errors" + "fmt" "hash" "hash/crc32" "io" @@ -21,9 +22,9 @@ const ( DefaultCompression = flate.DefaultCompression ) -// A Compressor is an io.WriteCloser that satisfies writes by compressing data written +// A Writer is an io.WriteCloser that satisfies writes by compressing data written // to its wrapped io.Writer. -type Compressor struct { +type Writer struct { Header w io.Writer level int @@ -35,25 +36,40 @@ type Compressor struct { err error } -// NewWriter calls NewWriterLevel with the default compression level. -func NewWriter(w io.Writer) (*Compressor, error) { - return NewWriterLevel(w, DefaultCompression) +// NewWriter creates a new Writer that satisfies writes by compressing data +// written to w. +// +// It is the caller's responsibility to call Close on the WriteCloser when done. +// Writes may be buffered and not flushed until Close. +// +// Callers that wish to set the fields in Writer.Header must do so before +// the first call to Write or Close. The Comment and Name header fields are +// UTF-8 strings in Go, but the underlying format requires NUL-terminated ISO +// 8859-1 (Latin-1). NUL or non-Latin-1 runes in those strings will lead to an +// error on Write. +func NewWriter(w io.Writer) *Writer { + z, _ := NewWriterLevel(w, DefaultCompression) + return z } -// NewWriterLevel creates a new Compressor writing to the given writer. -// Writes may be buffered and not flushed until Close. -// Callers that wish to set the fields in Compressor.Header must -// do so before the first call to Write or Close. -// It is the caller's responsibility to call Close on the WriteCloser when done. -// level is the compression level, which can be DefaultCompression, NoCompression, -// or any integer value between BestSpeed and BestCompression (inclusive). -func NewWriterLevel(w io.Writer, level int) (*Compressor, error) { - z := new(Compressor) - z.OS = 255 // unknown - z.w = w - z.level = level - z.digest = crc32.NewIEEE() - return z, nil +// NewWriterLevel is like NewWriter but specifies the compression level instead +// of assuming DefaultCompression. +// +// The compression level can be DefaultCompression, NoCompression, or any +// integer value between BestSpeed and BestCompression inclusive. The error +// returned will be nil if the level is valid. +func NewWriterLevel(w io.Writer, level int) (*Writer, error) { + if level < DefaultCompression || level > BestCompression { + return nil, fmt.Errorf("gzip: invalid compression level: %d", level) + } + return &Writer{ + Header: Header{ + OS: 255, // unknown + }, + w: w, + level: level, + digest: crc32.NewIEEE(), + }, nil } // GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950). @@ -70,7 +86,7 @@ func put4(p []byte, v uint32) { } // writeBytes writes a length-prefixed byte slice to z.w. -func (z *Compressor) writeBytes(b []byte) error { +func (z *Writer) writeBytes(b []byte) error { if len(b) > 0xffff { return errors.New("gzip.Write: Extra data is too large") } @@ -83,10 +99,10 @@ func (z *Compressor) writeBytes(b []byte) error { return err } -// writeString writes a string (in ISO 8859-1 (Latin-1) format) to z.w. -func (z *Compressor) writeString(s string) error { - // GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1). - var err error +// writeString writes a UTF-8 string s in GZIP's format to z.w. +// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1). +func (z *Writer) writeString(s string) (err error) { + // GZIP stores Latin-1 strings; error if non-Latin-1; convert if non-ASCII. needconv := false for _, v := range s { if v == 0 || v > 0xff { @@ -114,7 +130,9 @@ func (z *Compressor) writeString(s string) error { return err } -func (z *Compressor) Write(p []byte) (int, error) { +// Write writes a compressed form of p to the underlying io.Writer. The +// compressed bytes are not necessarily flushed until the Writer is closed. +func (z *Writer) Write(p []byte) (int, error) { if z.err != nil { return 0, z.err } @@ -165,7 +183,7 @@ func (z *Compressor) Write(p []byte) (int, error) { return n, z.err } } - z.compressor = flate.NewWriter(z.w, z.level) + z.compressor, _ = flate.NewWriter(z.w, z.level) } z.size += uint32(len(p)) z.digest.Write(p) @@ -173,8 +191,8 @@ func (z *Compressor) Write(p []byte) (int, error) { return n, z.err } -// Calling Close does not close the wrapped io.Writer originally passed to NewWriter. -func (z *Compressor) Close() error { +// Close closes the Writer. It does not close the underlying io.Writer. +func (z *Writer) Close() error { if z.err != nil { return z.err } diff --git a/libgo/go/compress/gzip/gzip_test.go b/libgo/go/compress/gzip/gzip_test.go index eb7a7ec0892..6f7b5936449 100644 --- a/libgo/go/compress/gzip/gzip_test.go +++ b/libgo/go/compress/gzip/gzip_test.go @@ -7,108 +7,153 @@ package gzip import ( "bufio" "bytes" - "io" "io/ioutil" "testing" "time" ) -// pipe creates two ends of a pipe that gzip and gunzip, and runs dfunc at the -// writer end and cfunc at the reader end. -func pipe(t *testing.T, dfunc func(*Compressor), cfunc func(*Decompressor)) { - piper, pipew := io.Pipe() - defer piper.Close() - go func() { - defer pipew.Close() - compressor, err := NewWriter(pipew) - if err != nil { - t.Fatalf("%v", err) - } - defer compressor.Close() - dfunc(compressor) - }() - decompressor, err := NewReader(piper) +// TestEmpty tests that an empty payload still forms a valid GZIP stream. +func TestEmpty(t *testing.T) { + buf := new(bytes.Buffer) + + if err := NewWriter(buf).Close(); err != nil { + t.Fatalf("Writer.Close: %v", err) + } + + r, err := NewReader(buf) + if err != nil { + t.Fatalf("NewReader: %v", err) + } + b, err := ioutil.ReadAll(r) if err != nil { - t.Fatalf("%v", err) + t.Fatalf("ReadAll: %v", err) + } + if len(b) != 0 { + t.Fatalf("got %d bytes, want 0", len(b)) + } + if err := r.Close(); err != nil { + t.Fatalf("Reader.Close: %v", err) } - defer decompressor.Close() - cfunc(decompressor) } -// Tests that an empty payload still forms a valid GZIP stream. -func TestEmpty(t *testing.T) { - pipe(t, - func(compressor *Compressor) {}, - func(decompressor *Decompressor) { - b, err := ioutil.ReadAll(decompressor) - if err != nil { - t.Fatalf("%v", err) - } - if len(b) != 0 { - t.Fatalf("did not read an empty slice") - } - }) -} +// TestRoundTrip tests that gzipping and then gunzipping is the identity +// function. +func TestRoundTrip(t *testing.T) { + buf := new(bytes.Buffer) + + w := NewWriter(buf) + w.Comment = "comment" + w.Extra = []byte("extra") + w.ModTime = time.Unix(1e8, 0) + w.Name = "name" + if _, err := w.Write([]byte("payload")); err != nil { + t.Fatalf("Write: %v", err) + } + if err := w.Close(); err != nil { + t.Fatalf("Writer.Close: %v", err) + } -// Tests that gzipping and then gunzipping is the identity function. -func TestWriter(t *testing.T) { - pipe(t, - func(compressor *Compressor) { - compressor.Comment = "Äußerung" - //compressor.Comment = "comment" - compressor.Extra = []byte("extra") - compressor.ModTime = time.Unix(1e8, 0) - compressor.Name = "name" - _, err := compressor.Write([]byte("payload")) - if err != nil { - t.Fatalf("%v", err) - } - }, - func(decompressor *Decompressor) { - b, err := ioutil.ReadAll(decompressor) - if err != nil { - t.Fatalf("%v", err) - } - if string(b) != "payload" { - t.Fatalf("payload is %q, want %q", string(b), "payload") - } - if decompressor.Comment != "Äußerung" { - t.Fatalf("comment is %q, want %q", decompressor.Comment, "Äußerung") - } - if string(decompressor.Extra) != "extra" { - t.Fatalf("extra is %q, want %q", decompressor.Extra, "extra") - } - if decompressor.ModTime.Unix() != 1e8 { - t.Fatalf("mtime is %d, want %d", decompressor.ModTime.Unix(), uint32(1e8)) - } - if decompressor.Name != "name" { - t.Fatalf("name is %q, want %q", decompressor.Name, "name") - } - }) + r, err := NewReader(buf) + if err != nil { + t.Fatalf("NewReader: %v", err) + } + b, err := ioutil.ReadAll(r) + if err != nil { + t.Fatalf("ReadAll: %v", err) + } + if string(b) != "payload" { + t.Fatalf("payload is %q, want %q", string(b), "payload") + } + if r.Comment != "comment" { + t.Fatalf("comment is %q, want %q", r.Comment, "comment") + } + if string(r.Extra) != "extra" { + t.Fatalf("extra is %q, want %q", r.Extra, "extra") + } + if r.ModTime.Unix() != 1e8 { + t.Fatalf("mtime is %d, want %d", r.ModTime.Unix(), uint32(1e8)) + } + if r.Name != "name" { + t.Fatalf("name is %q, want %q", r.Name, "name") + } + if err := r.Close(); err != nil { + t.Fatalf("Reader.Close: %v", err) + } } +// TestLatin1 tests the internal functions for converting to and from Latin-1. func TestLatin1(t *testing.T) { latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0} utf8 := "Äußerung" - z := Decompressor{r: bufio.NewReader(bytes.NewBuffer(latin1))} + z := Reader{r: bufio.NewReader(bytes.NewBuffer(latin1))} s, err := z.readString() if err != nil { - t.Fatalf("%v", err) + t.Fatalf("readString: %v", err) } if s != utf8 { - t.Fatalf("string is %q, want %q", s, utf8) + t.Fatalf("read latin-1: got %q, want %q", s, utf8) } buf := bytes.NewBuffer(make([]byte, 0, len(latin1))) - c := Compressor{w: buf} + c := Writer{w: buf} if err = c.writeString(utf8); err != nil { - t.Fatalf("%v", err) + t.Fatalf("writeString: %v", err) } s = buf.String() if s != string(latin1) { - t.Fatalf("string is %v, want %v", s, latin1) + t.Fatalf("write utf-8: got %q, want %q", s, string(latin1)) + } +} + +// TestLatin1RoundTrip tests that metadata that is representable in Latin-1 +// survives a round trip. +func TestLatin1RoundTrip(t *testing.T) { + testCases := []struct { + name string + ok bool + }{ + {"", true}, + {"ASCII is OK", true}, + {"unless it contains a NUL\x00", false}, + {"no matter where \x00 occurs", false}, + {"\x00\x00\x00", false}, + {"Látin-1 also passes (U+00E1)", true}, + {"but LĀtin Extended-A (U+0100) does not", false}, + {"neither does 日本語", false}, + {"invalid UTF-8 also \xffails", false}, + {"\x00 as does Látin-1 with NUL", false}, + } + for _, tc := range testCases { + buf := new(bytes.Buffer) + + w := NewWriter(buf) + w.Name = tc.name + err := w.Close() + if (err == nil) != tc.ok { + t.Errorf("Writer.Close: name = %q, err = %v", tc.name, err) + continue + } + if !tc.ok { + continue + } + + r, err := NewReader(buf) + if err != nil { + t.Errorf("NewReader: %v", err) + continue + } + _, err = ioutil.ReadAll(r) + if err != nil { + t.Errorf("ReadAll: %v", err) + continue + } + if r.Name != tc.name { + t.Errorf("name is %q, want %q", r.Name, tc.name) + continue + } + if err := r.Close(); err != nil { + t.Errorf("Reader.Close: %v", err) + continue + } } - //if s, err = buf.ReadString(0); err != nil { - //t.Fatalf("%v", err) - //} } diff --git a/libgo/go/compress/zlib/reader.go b/libgo/go/compress/zlib/reader.go index 4638a654842..f38ef5a885e 100644 --- a/libgo/go/compress/zlib/reader.go +++ b/libgo/go/compress/zlib/reader.go @@ -34,9 +34,14 @@ import ( const zlibDeflate = 8 -var ErrChecksum = errors.New("zlib checksum error") -var ErrHeader = errors.New("invalid zlib header") -var ErrDictionary = errors.New("invalid zlib dictionary") +var ( + // ErrChecksum is returned when reading ZLIB data that has an invalid checksum. + ErrChecksum = errors.New("zlib: invalid checksum") + // ErrDictionary is returned when reading ZLIB data that has an invalid dictionary. + ErrDictionary = errors.New("zlib: invalid dictionary") + // ErrHeader is returned when reading ZLIB data that has an invalid header. + ErrHeader = errors.New("zlib: invalid header") +) type reader struct { r flate.Reader diff --git a/libgo/go/compress/zlib/writer.go b/libgo/go/compress/zlib/writer.go index bbff6375ea1..cd8dea460a4 100644 --- a/libgo/go/compress/zlib/writer.go +++ b/libgo/go/compress/zlib/writer.go @@ -6,7 +6,7 @@ package zlib import ( "compress/flate" - "errors" + "fmt" "hash" "hash/adler32" "io" @@ -24,30 +24,55 @@ const ( // A Writer takes data written to it and writes the compressed // form of that data to an underlying writer (see NewWriter). type Writer struct { - w io.Writer - compressor *flate.Writer - digest hash.Hash32 - err error - scratch [4]byte + w io.Writer + level int + dict []byte + compressor *flate.Writer + digest hash.Hash32 + err error + scratch [4]byte + wroteHeader bool } -// NewWriter calls NewWriterLevel with the default compression level. -func NewWriter(w io.Writer) (*Writer, error) { - return NewWriterLevel(w, DefaultCompression) +// NewWriter creates a new Writer that satisfies writes by compressing data +// written to w. +// +// It is the caller's responsibility to call Close on the WriteCloser when done. +// Writes may be buffered and not flushed until Close. +func NewWriter(w io.Writer) *Writer { + z, _ := NewWriterLevelDict(w, DefaultCompression, nil) + return z } -// NewWriterLevel calls NewWriterDict with no dictionary. +// NewWriterLevel is like NewWriter but specifies the compression level instead +// of assuming DefaultCompression. +// +// The compression level can be DefaultCompression, NoCompression, or any +// integer value between BestSpeed and BestCompression inclusive. The error +// returned will be nil if the level is valid. func NewWriterLevel(w io.Writer, level int) (*Writer, error) { - return NewWriterDict(w, level, nil) + return NewWriterLevelDict(w, level, nil) } -// NewWriterDict creates a new io.WriteCloser that satisfies writes by compressing data written to w. -// It is the caller's responsibility to call Close on the WriteCloser when done. -// level is the compression level, which can be DefaultCompression, NoCompression, -// or any integer value between BestSpeed and BestCompression (inclusive). -// dict is the preset dictionary to compress with, or nil to use no dictionary. -func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { - z := new(Writer) +// NewWriterLevelDict is like NewWriterLevel but specifies a dictionary to +// compress with. +// +// The dictionary may be nil. If not, its contents should not be modified until +// the Writer is closed. +func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) { + if level < DefaultCompression || level > BestCompression { + return nil, fmt.Errorf("zlib: invalid compression level: %d", level) + } + return &Writer{ + w: w, + level: level, + dict: dict, + }, nil +} + +// writeHeader writes the ZLIB header. +func (z *Writer) writeHeader() (err error) { + z.wroteHeader = true // ZLIB has a two-byte header (as documented in RFC 1950). // The first four bits is the CINFO (compression info), which is 7 for the default deflate window size. // The next four bits is the CM (compression method), which is 8 for deflate. @@ -56,7 +81,7 @@ func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { // 0=fastest, 1=fast, 2=default, 3=best. // The next bit, FDICT, is set if a dictionary is given. // The final five FCHECK bits form a mod-31 checksum. - switch level { + switch z.level { case 0, 1: z.scratch[1] = 0 << 6 case 2, 3, 4, 5: @@ -66,35 +91,41 @@ func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { case 7, 8, 9: z.scratch[1] = 3 << 6 default: - return nil, errors.New("level out of range") + panic("unreachable") } - if dict != nil { + if z.dict != nil { z.scratch[1] |= 1 << 5 } z.scratch[1] += uint8(31 - (uint16(z.scratch[0])<<8+uint16(z.scratch[1]))%31) - _, err := w.Write(z.scratch[0:2]) - if err != nil { - return nil, err + if _, err = z.w.Write(z.scratch[0:2]); err != nil { + return err } - if dict != nil { + if z.dict != nil { // The next four bytes are the Adler-32 checksum of the dictionary. - checksum := adler32.Checksum(dict) + checksum := adler32.Checksum(z.dict) z.scratch[0] = uint8(checksum >> 24) z.scratch[1] = uint8(checksum >> 16) z.scratch[2] = uint8(checksum >> 8) z.scratch[3] = uint8(checksum >> 0) - _, err = w.Write(z.scratch[0:4]) - if err != nil { - return nil, err + if _, err = z.w.Write(z.scratch[0:4]); err != nil { + return err } } - z.w = w - z.compressor = flate.NewWriterDict(w, level, dict) + z.compressor, err = flate.NewWriterDict(z.w, z.level, z.dict) + if err != nil { + return err + } z.digest = adler32.New() - return z, nil + return nil } +// Write writes a compressed form of p to the underlying io.Writer. The +// compressed bytes are not necessarily flushed until the Writer is closed or +// explicitly flushed. func (z *Writer) Write(p []byte) (n int, err error) { + if !z.wroteHeader { + z.err = z.writeHeader() + } if z.err != nil { return 0, z.err } @@ -110,8 +141,11 @@ func (z *Writer) Write(p []byte) (n int, err error) { return } -// Flush flushes the underlying compressor. +// Flush flushes the Writer to its underlying io.Writer. func (z *Writer) Flush() error { + if !z.wroteHeader { + z.err = z.writeHeader() + } if z.err != nil { return z.err } @@ -121,6 +155,9 @@ func (z *Writer) Flush() error { // Calling Close does not close the wrapped io.Writer originally passed to NewWriter. func (z *Writer) Close() error { + if !z.wroteHeader { + z.err = z.writeHeader() + } if z.err != nil { return z.err } diff --git a/libgo/go/compress/zlib/writer_test.go b/libgo/go/compress/zlib/writer_test.go index 1c75d088ddf..aee1a5c2f54 100644 --- a/libgo/go/compress/zlib/writer_test.go +++ b/libgo/go/compress/zlib/writer_test.go @@ -52,7 +52,7 @@ func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) { defer piper.Close() go func() { defer pipew.Close() - zlibw, err := NewWriterDict(pipew, level, dict) + zlibw, err := NewWriterLevelDict(pipew, level, dict) if err != nil { t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err) return @@ -125,9 +125,9 @@ func TestWriterDict(t *testing.T) { func TestWriterDictIsUsed(t *testing.T) { var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") var buf bytes.Buffer - compressor, err := NewWriterDict(&buf, BestCompression, input) + compressor, err := NewWriterLevelDict(&buf, BestCompression, input) if err != nil { - t.Errorf("error in NewWriterDict: %s", err) + t.Errorf("error in NewWriterLevelDict: %s", err) return } compressor.Write(input) diff --git a/libgo/go/container/heap/example_test.go b/libgo/go/container/heap/example_test.go new file mode 100644 index 00000000000..2050bc83591 --- /dev/null +++ b/libgo/go/container/heap/example_test.go @@ -0,0 +1,105 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This example demonstrates a priority queue built using the heap interface. +package heap_test + +import ( + "container/heap" + "fmt" +) + +// An Item is something we manage in a priority queue. +type Item struct { + value string // The value of the item; arbitrary. + priority int // The priority of the item in the queue. + // The index is needed by changePriority and is maintained by the heap.Interface methods. + index int // The index of the item in the heap. +} + +// A PriorityQueue implements heap.Interface and holds Items. +type PriorityQueue []*Item + +func (pq PriorityQueue) Len() int { return len(pq) } + +func (pq PriorityQueue) Less(i, j int) bool { + // We want Pop to give us the highest, not lowest, priority so we use greater than here. + return pq[i].priority > pq[j].priority +} + +func (pq PriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +func (pq *PriorityQueue) Push(x interface{}) { + // Push and Pop use pointer receivers because they modify the slice's length, + // not just its contents. + // To simplify indexing expressions in these methods, we save a copy of the + // slice object. We could instead write (*pq)[i]. + a := *pq + n := len(a) + a = a[0 : n+1] + item := x.(*Item) + item.index = n + a[n] = item + *pq = a +} + +func (pq *PriorityQueue) Pop() interface{} { + a := *pq + n := len(a) + item := a[n-1] + item.index = -1 // for safety + *pq = a[0 : n-1] + return item +} + +// update is not used by the example but shows how to take the top item from +// the queue, update its priority and value, and put it back. +func (pq *PriorityQueue) update(value string, priority int) { + item := heap.Pop(pq).(*Item) + item.value = value + item.priority = priority + heap.Push(pq, item) +} + +// changePriority is not used by the example but shows how to change the +// priority of an arbitrary item. +func (pq *PriorityQueue) changePriority(item *Item, priority int) { + heap.Remove(pq, item.index) + item.priority = priority + heap.Push(pq, item) +} + +// This example pushes 10 items into a PriorityQueue and takes them out in +// order of priority. +func Example() { + const nItem = 10 + // Random priorities for the items (a permutation of 0..9, times 11)). + priorities := [nItem]int{ + 77, 22, 44, 55, 11, 88, 33, 99, 00, 66, + } + values := [nItem]string{ + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", + } + // Create a priority queue and put some items in it. + pq := make(PriorityQueue, 0, nItem) + for i := 0; i < cap(pq); i++ { + item := &Item{ + value: values[i], + priority: priorities[i], + } + heap.Push(&pq, item) + } + // Take the items out; should arrive in decreasing priority order. + // For example, the highest priority (99) is the seventh item, so output starts with 99:"seven". + for i := 0; i < nItem; i++ { + item := heap.Pop(&pq).(*Item) + fmt.Printf("%.2d:%s ", item.priority, item.value) + } + // Output: + // 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight +} diff --git a/libgo/go/container/heap/heap.go b/libgo/go/container/heap/heap.go index 7af636b4513..67018e6baea 100644 --- a/libgo/go/container/heap/heap.go +++ b/libgo/go/container/heap/heap.go @@ -6,10 +6,11 @@ // heap.Interface. A heap is a tree with the property that each node is the // highest-valued node in its subtree. // -// A heap is a common way to impement a priority queue. To build a priority +// A heap is a common way to implement a priority queue. To build a priority // queue, implement the Heap interface with the (negative) priority as the // ordering for the Less method, so Push adds items while Pop removes the -// highest-priority item from the queue. +// highest-priority item from the queue. The Examples include such an +// implementation; the file example_test.go has the complete source. // package heap diff --git a/libgo/go/crypto/aes/cipher.go b/libgo/go/crypto/aes/cipher.go index 28752e73613..7d307c93a0b 100644 --- a/libgo/go/crypto/aes/cipher.go +++ b/libgo/go/crypto/aes/cipher.go @@ -4,13 +4,16 @@ package aes -import "strconv" +import ( + "crypto/cipher" + "strconv" +) // The AES block size in bytes. const BlockSize = 16 -// A Cipher is an instance of AES encryption using a particular key. -type Cipher struct { +// A cipher is an instance of AES encryption using a particular key. +type aesCipher struct { enc []uint32 dec []uint32 } @@ -21,11 +24,11 @@ func (k KeySizeError) Error() string { return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) } -// NewCipher creates and returns a new Cipher. +// NewCipher creates and returns a new cipher.Block. // The key argument should be the AES key, // either 16, 24, or 32 bytes to select // AES-128, AES-192, or AES-256. -func NewCipher(key []byte) (*Cipher, error) { +func NewCipher(key []byte) (cipher.Block, error) { k := len(key) switch k { default: @@ -35,34 +38,13 @@ func NewCipher(key []byte) (*Cipher, error) { } n := k + 28 - c := &Cipher{make([]uint32, n), make([]uint32, n)} + c := &aesCipher{make([]uint32, n), make([]uint32, n)} expandKey(key, c.enc, c.dec) return c, nil } -// BlockSize returns the AES block size, 16 bytes. -// It is necessary to satisfy the Block interface in the -// package "crypto/cipher". -func (c *Cipher) BlockSize() int { return BlockSize } +func (c *aesCipher) BlockSize() int { return BlockSize } -// Encrypt encrypts the 16-byte buffer src using the key k -// and stores the result in dst. -// Note that for amounts of data larger than a block, -// it is not safe to just call Encrypt on successive blocks; -// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). -func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.enc, dst, src) } +func (c *aesCipher) Encrypt(dst, src []byte) { encryptBlock(c.enc, dst, src) } -// Decrypt decrypts the 16-byte buffer src using the key k -// and stores the result in dst. -func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.dec, dst, src) } - -// Reset zeros the key data, so that it will no longer -// appear in the process's memory. -func (c *Cipher) Reset() { - for i := 0; i < len(c.enc); i++ { - c.enc[i] = 0 - } - for i := 0; i < len(c.dec); i++ { - c.dec[i] = 0 - } -} +func (c *aesCipher) Decrypt(dst, src []byte) { decryptBlock(c.dec, dst, src) } diff --git a/libgo/go/crypto/cipher/cbc_aes_test.go b/libgo/go/crypto/cipher/cbc_aes_test.go index 944ca1ba851..cee3a784b50 100644 --- a/libgo/go/crypto/cipher/cbc_aes_test.go +++ b/libgo/go/crypto/cipher/cbc_aes_test.go @@ -8,11 +8,12 @@ // Special Publication 800-38A, ``Recommendation for Block Cipher // Modes of Operation,'' 2001 Edition, pp. 24-29. -package cipher +package cipher_test import ( "bytes" "crypto/aes" + "crypto/cipher" "testing" ) @@ -72,14 +73,14 @@ func TestCBC_AES(t *testing.T) { continue } - encrypter := NewCBCEncrypter(c, tt.iv) + encrypter := cipher.NewCBCEncrypter(c, tt.iv) d := make([]byte, len(tt.in)) encrypter.CryptBlocks(d, tt.in) if !bytes.Equal(tt.out, d) { t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out) } - decrypter := NewCBCDecrypter(c, tt.iv) + decrypter := cipher.NewCBCDecrypter(c, tt.iv) p := make([]byte, len(d)) decrypter.CryptBlocks(p, d) if !bytes.Equal(tt.in, p) { diff --git a/libgo/go/crypto/cipher/cfb_test.go b/libgo/go/crypto/cipher/cfb_test.go index 9547bfceb7b..f704b337e4b 100644 --- a/libgo/go/crypto/cipher/cfb_test.go +++ b/libgo/go/crypto/cipher/cfb_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package cipher +package cipher_test import ( "bytes" "crypto/aes" + "crypto/cipher" "crypto/rand" "testing" ) @@ -21,11 +22,11 @@ func TestCFB(t *testing.T) { plaintext := []byte("this is the plaintext") iv := make([]byte, block.BlockSize()) rand.Reader.Read(iv) - cfb := NewCFBEncrypter(block, iv) + cfb := cipher.NewCFBEncrypter(block, iv) ciphertext := make([]byte, len(plaintext)) cfb.XORKeyStream(ciphertext, plaintext) - cfbdec := NewCFBDecrypter(block, iv) + cfbdec := cipher.NewCFBDecrypter(block, iv) plaintextCopy := make([]byte, len(plaintext)) cfbdec.XORKeyStream(plaintextCopy, ciphertext) diff --git a/libgo/go/crypto/cipher/common_test.go b/libgo/go/crypto/cipher/common_test.go index fb755757c25..c75c919d175 100644 --- a/libgo/go/crypto/cipher/common_test.go +++ b/libgo/go/crypto/cipher/common_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package cipher +package cipher_test // Common values for tests. diff --git a/libgo/go/crypto/cipher/ctr_aes_test.go b/libgo/go/crypto/cipher/ctr_aes_test.go index 8dca9968c44..d019ae0d022 100644 --- a/libgo/go/crypto/cipher/ctr_aes_test.go +++ b/libgo/go/crypto/cipher/ctr_aes_test.go @@ -8,11 +8,12 @@ // Special Publication 800-38A, ``Recommendation for Block Cipher // Modes of Operation,'' 2001 Edition, pp. 55-58. -package cipher +package cipher_test import ( "bytes" "crypto/aes" + "crypto/cipher" "testing" ) @@ -76,7 +77,7 @@ func TestCTR_AES(t *testing.T) { for j := 0; j <= 5; j += 5 { in := tt.in[0 : len(tt.in)-j] - ctr := NewCTR(c, tt.iv) + ctr := cipher.NewCTR(c, tt.iv) encrypted := make([]byte, len(in)) ctr.XORKeyStream(encrypted, in) if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) { @@ -86,7 +87,7 @@ func TestCTR_AES(t *testing.T) { for j := 0; j <= 7; j += 7 { in := tt.out[0 : len(tt.out)-j] - ctr := NewCTR(c, tt.iv) + ctr := cipher.NewCTR(c, tt.iv) plain := make([]byte, len(in)) ctr.XORKeyStream(plain, in) if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) { diff --git a/libgo/go/crypto/cipher/ofb_test.go b/libgo/go/crypto/cipher/ofb_test.go index 9b4495c8830..8d3c5d3a389 100644 --- a/libgo/go/crypto/cipher/ofb_test.go +++ b/libgo/go/crypto/cipher/ofb_test.go @@ -8,11 +8,12 @@ // Special Publication 800-38A, ``Recommendation for Block Cipher // Modes of Operation,'' 2001 Edition, pp. 52-55. -package cipher +package cipher_test import ( "bytes" "crypto/aes" + "crypto/cipher" "testing" ) @@ -76,7 +77,7 @@ func TestOFB(t *testing.T) { for j := 0; j <= 5; j += 5 { plaintext := tt.in[0 : len(tt.in)-j] - ofb := NewOFB(c, tt.iv) + ofb := cipher.NewOFB(c, tt.iv) ciphertext := make([]byte, len(plaintext)) ofb.XORKeyStream(ciphertext, plaintext) if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) { @@ -86,7 +87,7 @@ func TestOFB(t *testing.T) { for j := 0; j <= 5; j += 5 { ciphertext := tt.out[0 : len(tt.in)-j] - ofb := NewOFB(c, tt.iv) + ofb := cipher.NewOFB(c, tt.iv) plaintext := make([]byte, len(ciphertext)) ofb.XORKeyStream(plaintext, ciphertext) if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) { diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go index e18eaedf580..c11c62cd723 100644 --- a/libgo/go/crypto/des/block.go +++ b/libgo/go/crypto/des/block.go @@ -79,7 +79,7 @@ func ksRotate(in uint32) (out []uint32) { } // creates 16 56-bit subkeys from the original key -func (c *Cipher) generateSubkeys(keyBytes []byte) { +func (c *desCipher) generateSubkeys(keyBytes []byte) { // apply PC1 permutation to key key := binary.BigEndian.Uint64(keyBytes) permutedKey := permuteBlock(key, permutedChoice1[:]) diff --git a/libgo/go/crypto/des/cipher.go b/libgo/go/crypto/des/cipher.go index 1c41e29a8bd..2f929ca7bed 100644 --- a/libgo/go/crypto/des/cipher.go +++ b/libgo/go/crypto/des/cipher.go @@ -4,7 +4,10 @@ package des -import "strconv" +import ( + "crypto/cipher" + "strconv" +) // The DES block size in bytes. const BlockSize = 8 @@ -15,86 +18,56 @@ func (k KeySizeError) Error() string { return "crypto/des: invalid key size " + strconv.Itoa(int(k)) } -// Cipher is an instance of DES encryption. -type Cipher struct { +// desCipher is an instance of DES encryption. +type desCipher struct { subkeys [16]uint64 } -// NewCipher creates and returns a new Cipher. -func NewCipher(key []byte) (*Cipher, error) { +// NewCipher creates and returns a new cipher.Block. +func NewCipher(key []byte) (cipher.Block, error) { if len(key) != 8 { return nil, KeySizeError(len(key)) } - c := new(Cipher) + c := new(desCipher) c.generateSubkeys(key) return c, nil } -// BlockSize returns the DES block size, 8 bytes. -func (c *Cipher) BlockSize() int { return BlockSize } +func (c *desCipher) BlockSize() int { return BlockSize } -// Encrypt encrypts the 8-byte buffer src and stores the result in dst. -// Note that for amounts of data larger than a block, -// it is not safe to just call Encrypt on successive blocks; -// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). -func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) } +func (c *desCipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) } -// Decrypt decrypts the 8-byte buffer src and stores the result in dst. -func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) } +func (c *desCipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) } -// Reset zeros the key data, so that it will no longer -// appear in the process's memory. -func (c *Cipher) Reset() { - for i := 0; i < len(c.subkeys); i++ { - c.subkeys[i] = 0 - } -} - -// A TripleDESCipher is an instance of TripleDES encryption. -type TripleDESCipher struct { - cipher1, cipher2, cipher3 Cipher +// A tripleDESCipher is an instance of TripleDES encryption. +type tripleDESCipher struct { + cipher1, cipher2, cipher3 desCipher } -// NewCipher creates and returns a new Cipher. -func NewTripleDESCipher(key []byte) (*TripleDESCipher, error) { +// NewTripleDESCipher creates and returns a new cipher.Block. +func NewTripleDESCipher(key []byte) (cipher.Block, error) { if len(key) != 24 { return nil, KeySizeError(len(key)) } - c := new(TripleDESCipher) + c := new(tripleDESCipher) c.cipher1.generateSubkeys(key[:8]) c.cipher2.generateSubkeys(key[8:16]) c.cipher3.generateSubkeys(key[16:]) return c, nil } -// BlockSize returns the TripleDES block size, 8 bytes. -// It is necessary to satisfy the Block interface in the -// package "crypto/cipher". -func (c *TripleDESCipher) BlockSize() int { return BlockSize } +func (c *tripleDESCipher) BlockSize() int { return BlockSize } -// Encrypts the 8-byte buffer src and stores the result in dst. -// Note that for amounts of data larger than a block, -// it is not safe to just call Encrypt on successive blocks; -// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). -func (c *TripleDESCipher) Encrypt(dst, src []byte) { +func (c *tripleDESCipher) Encrypt(dst, src []byte) { c.cipher1.Encrypt(dst, src) c.cipher2.Decrypt(dst, dst) c.cipher3.Encrypt(dst, dst) } -// Decrypts the 8-byte buffer src and stores the result in dst. -func (c *TripleDESCipher) Decrypt(dst, src []byte) { +func (c *tripleDESCipher) Decrypt(dst, src []byte) { c.cipher3.Decrypt(dst, src) c.cipher2.Encrypt(dst, dst) c.cipher1.Decrypt(dst, dst) } - -// Reset zeros the key data, so that it will no longer -// appear in the process's memory. -func (c *TripleDESCipher) Reset() { - c.cipher1.Reset() - c.cipher2.Reset() - c.cipher3.Reset() -} diff --git a/libgo/go/crypto/des/des_test.go b/libgo/go/crypto/des/des_test.go index d1f3aa71ac4..e9fc236299e 100644 --- a/libgo/go/crypto/des/des_test.go +++ b/libgo/go/crypto/des/des_test.go @@ -1260,11 +1260,19 @@ var tableA4Tests = []CryptTest{ []byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}}, } +func newCipher(key []byte) *desCipher { + c, err := NewCipher(key) + if err != nil { + panic("NewCipher failed: " + err.Error()) + } + return c.(*desCipher) +} + // Use the known weak keys to test DES implementation func TestWeakKeys(t *testing.T) { for i, tt := range weakKeyTests { var encrypt = func(in []byte) (out []byte) { - c, _ := NewCipher(tt.key) + c := newCipher(tt.key) out = make([]byte, len(in)) encryptBlock(c.subkeys[:], out, in) return @@ -1285,7 +1293,7 @@ func TestWeakKeys(t *testing.T) { func TestSemiWeakKeyPairs(t *testing.T) { for i, tt := range semiWeakKeyTests { var encrypt = func(key, in []byte) (out []byte) { - c, _ := NewCipher(key) + c := newCipher(key) out = make([]byte, len(in)) encryptBlock(c.subkeys[:], out, in) return @@ -1305,7 +1313,7 @@ func TestSemiWeakKeyPairs(t *testing.T) { func TestDESEncryptBlock(t *testing.T) { for i, tt := range encryptDESTests { - c, _ := NewCipher(tt.key) + c := newCipher(tt.key) out := make([]byte, len(tt.in)) encryptBlock(c.subkeys[:], out, tt.in) @@ -1317,7 +1325,7 @@ func TestDESEncryptBlock(t *testing.T) { func TestDESDecryptBlock(t *testing.T) { for i, tt := range encryptDESTests { - c, _ := NewCipher(tt.key) + c := newCipher(tt.key) plain := make([]byte, len(tt.in)) decryptBlock(c.subkeys[:], plain, tt.out) diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go index 81487f68f41..05766a2f136 100644 --- a/libgo/go/crypto/dsa/dsa.go +++ b/libgo/go/crypto/dsa/dsa.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3 +// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3. package dsa import ( @@ -29,17 +29,11 @@ type PrivateKey struct { X *big.Int } -type invalidPublicKeyError int - -func (invalidPublicKeyError) Error() string { - return "crypto/dsa: invalid public key" -} - // ErrInvalidPublicKey results when a public key is not usable by this code. // FIPS is quite strict about the format of DSA keys, but other code may be // less so. Thus, when using keys which may have been generated by other code, // this error must be handled. -var ErrInvalidPublicKey error = invalidPublicKeyError(0) +var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key") // ParameterSizes is a enumeration of the acceptable bit lengths of the primes // in a set of DSA parameters. See FIPS 186-3, section 4.2. diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index d2f7d8f9bb3..b28239b7862 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -7,7 +7,7 @@ package ecdsa // References: -// [NSA]: Suite B implementor's guide to FIPS 186-3, +// [NSA]: Suite B implementer's guide to FIPS 186-3, // http://www.nsa.gov/ia/_files/ecdsa.pdf // [SECG]: SECG, SEC1 // http://www.secg.org/download/aid-780/sec1-v2.pdf diff --git a/libgo/go/crypto/md5/md5_test.go b/libgo/go/crypto/md5/md5_test.go index b15e4668c32..aae875464f9 100644 --- a/libgo/go/crypto/md5/md5_test.go +++ b/libgo/go/crypto/md5/md5_test.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package md5 +package md5_test import ( + "crypto/md5" "fmt" "io" "testing" @@ -52,7 +53,7 @@ var golden = []md5Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := New() + c := md5.New() for j := 0; j < 3; j++ { if j < 2 { io.WriteString(c, g.in) @@ -69,3 +70,11 @@ func TestGolden(t *testing.T) { } } } + +func ExampleNew() { + h := md5.New() + io.WriteString(h, "The fog is getting thicker!") + io.WriteString(h, "And Leon's getting laaarger!") + fmt.Printf("%x", h.Sum(nil)) + // Output: e2c569be17396eca2a2e3c11578123ed +} diff --git a/libgo/go/crypto/rand/rand_test.go b/libgo/go/crypto/rand/rand_test.go index bfae7ce4f9b..be3a5a221d7 100644 --- a/libgo/go/crypto/rand/rand_test.go +++ b/libgo/go/crypto/rand/rand_test.go @@ -22,7 +22,7 @@ func TestRead(t *testing.T) { } var z bytes.Buffer - f := flate.NewWriter(&z, 5) + f, _ := flate.NewWriter(&z, 5) f.Write(b) f.Close() if z.Len() < len(b)*99/100 { diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go index 5d4fc8198ac..5eb4cda2b3a 100644 --- a/libgo/go/crypto/rand/rand_unix.go +++ b/libgo/go/crypto/rand/rand_unix.go @@ -12,6 +12,7 @@ package rand import ( "bufio" "crypto/aes" + "crypto/cipher" "io" "os" "sync" @@ -66,7 +67,7 @@ func newReader(entropy io.Reader) io.Reader { type reader struct { mu sync.Mutex budget int // number of bytes that can be generated - cipher *aes.Cipher + cipher cipher.Block entropy io.Reader time, seed, dst, key [aes.BlockSize]byte } diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go index 4f12cbea5c5..254f4a3da04 100644 --- a/libgo/go/crypto/rsa/pkcs1v15.go +++ b/libgo/go/crypto/rsa/pkcs1v15.go @@ -21,7 +21,7 @@ import ( func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) { k := (pub.N.BitLen() + 7) / 8 if len(msg) > k-11 { - err = MessageTooLongError{} + err = ErrMessageTooLong return } @@ -47,7 +47,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) { valid, out, err := decryptPKCS1v15(rand, priv, ciphertext) if err == nil && valid == 0 { - err = DecryptionError{} + err = ErrDecryption } return @@ -69,7 +69,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) { k := (priv.N.BitLen() + 7) / 8 if k-(len(key)+3+8) < 0 { - err = DecryptionError{} + err = ErrDecryption return } @@ -86,7 +86,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err error) { k := (priv.N.BitLen() + 7) / 8 if k < 11 { - err = DecryptionError{} + err = ErrDecryption return } @@ -170,7 +170,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b tLen := len(prefix) + hashLen k := (priv.N.BitLen() + 7) / 8 if k < tLen+11 { - return nil, MessageTooLongError{} + return nil, ErrMessageTooLong } // EM = 0x00 || 0x01 || PS || 0x00 || T @@ -203,7 +203,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) tLen := len(prefix) + hashLen k := (pub.N.BitLen() + 7) / 8 if k < tLen+11 { - err = VerificationError{} + err = ErrVerification return } @@ -223,7 +223,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) } if ok != 1 { - return VerificationError{} + return ErrVerification } return nil diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index 677d27be5d2..ec77e68696b 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -206,13 +206,9 @@ func mgf1XOR(out []byte, hash hash.Hash, seed []byte) { } } -// MessageTooLongError is returned when attempting to encrypt a message which -// is too large for the size of the public key. -type MessageTooLongError struct{} - -func (MessageTooLongError) Error() string { - return "message too long for RSA public key size" -} +// ErrMessageTooLong is returned when attempting to encrypt a message which is +// too large for the size of the public key. +var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size") func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int { e := big.NewInt(int64(pub.E)) @@ -227,7 +223,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l hash.Reset() k := (pub.N.BitLen() + 7) / 8 if len(msg) > k-2*hash.Size()-2 { - err = MessageTooLongError{} + err = ErrMessageTooLong return } @@ -266,17 +262,13 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l return } -// A DecryptionError represents a failure to decrypt a message. +// ErrDecryption represents a failure to decrypt a message. // It is deliberately vague to avoid adaptive attacks. -type DecryptionError struct{} +var ErrDecryption = errors.New("crypto/rsa: decryption error") -func (DecryptionError) Error() string { return "RSA decryption error" } - -// A VerificationError represents a failure to verify a signature. +// ErrVerification represents a failure to verify a signature. // It is deliberately vague to avoid adaptive attacks. -type VerificationError struct{} - -func (VerificationError) Error() string { return "RSA verification error" } +var ErrVerification = errors.New("crypto/rsa: verification error") // modInverse returns ia, the inverse of a in the multiplicative group of prime // order n. It requires that a be a member of the group (i.e. less than n). @@ -338,7 +330,7 @@ func (priv *PrivateKey) Precompute() { func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) { // TODO(agl): can we get away with reusing blinds? if c.Cmp(priv.N) > 0 { - err = DecryptionError{} + err = ErrDecryption return } @@ -417,7 +409,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext k := (priv.N.BitLen() + 7) / 8 if len(ciphertext) > k || k < hash.Size()*2+2 { - err = DecryptionError{} + err = ErrDecryption return } @@ -473,7 +465,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext } if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 { - err = DecryptionError{} + err = ErrDecryption return } diff --git a/libgo/go/crypto/sha1/sha1_test.go b/libgo/go/crypto/sha1/sha1_test.go index c23df6c41e9..2dc14ac9868 100644 --- a/libgo/go/crypto/sha1/sha1_test.go +++ b/libgo/go/crypto/sha1/sha1_test.go @@ -4,9 +4,10 @@ // SHA1 hash algorithm. See RFC 3174. -package sha1 +package sha1_test import ( + "crypto/sha1" "fmt" "io" "testing" @@ -54,7 +55,7 @@ var golden = []sha1Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := New() + c := sha1.New() for j := 0; j < 3; j++ { if j < 2 { io.WriteString(c, g.in) @@ -71,3 +72,10 @@ func TestGolden(t *testing.T) { } } } + +func ExampleNew() { + h := sha1.New() + io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") + fmt.Printf("% x", h.Sum(nil)) + // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd +} diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index e6cee1278c3..2a5115dc6ab 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -87,9 +87,9 @@ func (c *Conn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() } -// SetDeadline sets the read deadline associated with the connection. -// There is no write deadline. -// A zero value for t means Read will not time out. +// SetDeadline sets the read and write deadlines associated with the connection. +// A zero value for t means Read and Write will not time out. +// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. func (c *Conn) SetDeadline(t time.Time) error { return c.conn.SetDeadline(t) } @@ -100,10 +100,11 @@ func (c *Conn) SetReadDeadline(t time.Time) error { return c.conn.SetReadDeadline(t) } -// SetWriteDeadline exists to satisfy the net.Conn interface -// but is not implemented by TLS. It always returns an error. +// SetWriteDeadline sets the write deadline on the underlying conneciton. +// A zero value for t means Write will not time out. +// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. func (c *Conn) SetWriteDeadline(t time.Time) error { - return errors.New("TLS does not support SetWriteDeadline") + return c.conn.SetWriteDeadline(t) } // A halfConn represents one direction of the record layer @@ -726,9 +727,13 @@ func (c *Conn) readHandshake() (interface{}, error) { } // Write writes data to the connection. -func (c *Conn) Write(b []byte) (n int, err error) { - if err = c.Handshake(); err != nil { - return +func (c *Conn) Write(b []byte) (int, error) { + if c.err != nil { + return 0, c.err + } + + if c.err = c.Handshake(); c.err != nil { + return 0, c.err } c.out.Lock() @@ -737,10 +742,10 @@ func (c *Conn) Write(b []byte) (n int, err error) { if !c.handshakeComplete { return 0, alertInternalError } - if c.err != nil { - return 0, c.err - } - return c.writeRecord(recordTypeApplicationData, b) + + var n int + n, c.err = c.writeRecord(recordTypeApplicationData, b) + return n, c.err } // Read can be made to time out and return a net.Error with Timeout() == true diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go index 7c0718b82ab..84be5bfd856 100644 --- a/libgo/go/crypto/tls/generate_cert.go +++ b/libgo/go/crypto/tls/generate_cert.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + // Generate a self-signed X.509 certificate for a TLS server. Outputs to // 'cert.pem' and 'key.pem' and will overwrite existing files. diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index 687e5ef11b4..0d7b806ff5b 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -273,7 +273,7 @@ func (c *Conn) clientHandshake() error { masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) - clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */ ) + clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */) clientHash := suite.mac(c.vers, clientMAC) c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) @@ -294,7 +294,7 @@ func (c *Conn) clientHandshake() error { finishedHash.Write(finished.marshal()) c.writeRecord(recordTypeHandshake, finished.marshal()) - serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */ ) + serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */) serverHash := suite.mac(c.vers, serverMAC) c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) c.readRecord(recordTypeChangeCipherSpec) diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go index c0abcda2001..8c56daaf619 100644 --- a/libgo/go/crypto/tls/handshake_client_test.go +++ b/libgo/go/crypto/tls/handshake_client_test.go @@ -62,7 +62,7 @@ func TestRunClient(t *testing.T) { // Script of interaction with gnutls implementation. // The values for this test are obtained by building and running in client mode: -// % gotest -test.run "TestRunClient" -connect +// % go test -run "TestRunClient" -connect // and then: // % gnutls-serv -p 10443 --debug 100 --x509keyfile key.pem --x509certfile cert.pem -a > /tmp/log 2>&1 // % python parse-gnutls-cli-debug-log.py < /tmp/log diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index fb53767f3e0..23ec5587235 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -295,7 +295,7 @@ FindCipherSuite: masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromPreMasterSecret(c.vers, preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen) - clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */ ) + clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */) clientHash := suite.mac(c.vers, clientMAC) c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) c.readRecord(recordTypeChangeCipherSpec) @@ -333,7 +333,7 @@ FindCipherSuite: finishedHash.Write(clientFinished.marshal()) - serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */ ) + serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */) serverHash := suite.mac(c.vers, serverMAC) c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index 4bff5327e2c..bd31d31ae1a 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -284,7 +284,7 @@ func loadPEMCert(in string) *x509.Certificate { // Script of interaction with gnutls implementation. // The values for this test are obtained by building and running in server mode: -// % gotest -test.run "TestRunServer" -serve +// % go test -run "TestRunServer" -serve // and then: // % gnutls-cli --insecure --debug 100 -p 10443 localhost > /tmp/log 2>&1 // % python parse-gnutls-cli-debug-log.py < /tmp/log @@ -949,7 +949,7 @@ var sslv3ServerScript = [][]byte{ var clientauthTests = []clientauthTest{ // Server doesn't asks for cert - // gotest -test.run "TestRunServer" -serve -clientauth 0 + // go test -run "TestRunServer" -serve -clientauth 0 // gnutls-cli --insecure --debug 100 -p 10443 localhost 2>&1 | // python parse-gnutls-cli-debug-log.py {"NoClientCert", NoClientCert, nil, @@ -1115,7 +1115,7 @@ var clientauthTests = []clientauthTest{ 0x03, 0x11, 0x43, 0x3e, 0xee, 0xb7, 0x4d, 0x69, }}}, // Server asks for cert with empty CA list, client doesn't give it. - // gotest -test.run "TestRunServer" -serve -clientauth 1 + // go test -run "TestRunServer" -serve -clientauth 1 // gnutls-cli --insecure --debug 100 -p 10443 localhost {"RequestClientCert, none given", RequestClientCert, nil, [][]byte{{ @@ -1282,7 +1282,7 @@ var clientauthTests = []clientauthTest{ 0xf4, 0x70, 0xcc, 0xb4, 0xed, 0x07, 0x76, 0x3a, }}}, // Server asks for cert with empty CA list, client gives one - // gotest -test.run "TestRunServer" -serve -clientauth 1 + // go test -run "TestRunServer" -serve -clientauth 1 // gnutls-cli --insecure --debug 100 -p 10443 localhost {"RequestClientCert, client gives it", RequestClientCert, []*x509.Certificate{clicert}, diff --git a/libgo/go/crypto/tls/root_darwin.go b/libgo/go/crypto/tls/root_darwin.go index db1b18b3c07..911a9a62e3c 100644 --- a/libgo/go/crypto/tls/root_darwin.go +++ b/libgo/go/crypto/tls/root_darwin.go @@ -5,11 +5,9 @@ package tls /* -// Note: We disable -Werror here because the code in this file uses a deprecated API to stay -// compatible with both Mac OS X 10.6 and 10.7. Using a deprecated function on Darwin generates -// a warning. -#cgo CFLAGS: -Wno-error -Wno-deprecated-declarations +#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060 #cgo LDFLAGS: -framework CoreFoundation -framework Security + #include <CoreFoundation/CoreFoundation.h> #include <Security/Security.h> @@ -40,26 +38,12 @@ int FetchPEMRoots(CFDataRef *pemRoots) { continue; } - // SecKeychainImportExport is deprecated in >= OS X 10.7, and has been replaced by - // SecItemExport. If we're built on a host with a Lion SDK, this code gets conditionally - // included in the output, also for binaries meant for 10.6. - // - // To make sure that we run on both Mac OS X 10.6 and 10.7 we use weak linking - // and check whether SecItemExport is available before we attempt to call it. On - // 10.6, this won't be the case, and we'll fall back to calling SecKeychainItemExport. -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (SecItemExport) { - err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); - if (err != noErr) { - continue; - } - } else -#endif - if (data == NULL) { - err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); - if (err != noErr) { - continue; - } + // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport. + // Once we support weak imports via cgo we should prefer that, and fall back to this + // for older systems. + err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); + if (err != noErr) { + continue; } if (data != NULL) { diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index 87b1cb7bb1c..3859dd8d488 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -135,8 +135,8 @@ func (c *Certificate) isValid(certType int, opts *VerifyOptions) error { // Verify attempts to verify c by building one or more chains from c to a // certificate in opts.roots, using certificates in opts.Intermediates if -// needed. If successful, it returns one or chains where the first element of -// the chain is c and the last element is from opts.Roots. +// needed. If successful, it returns one or more chains where the first +// element of the chain is c and the last element is from opts.Roots. // // WARNING: this doesn't do any revocation checking. func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) { diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 7b45ba51f43..f5da86b54a0 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -153,7 +153,7 @@ const ( // // md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } // -// md5WithRSAEncryption OBJECT IDENTIFER ::= { pkcs-1 4 } +// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } // // sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } // @@ -172,9 +172,9 @@ const ( // // RFC 5758 3.1 DSA Signature Algorithms // -// dsaWithSha356 OBJECT IDENTIFER ::= { +// dsaWithSha256 OBJECT IDENTIFIER ::= { // joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101) -// algorithms(4) id-dsa-with-sha2(3) 2} +// csor(3) algorithms(4) id-dsa-with-sha2(3) 2} // var ( oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} @@ -327,13 +327,9 @@ type Certificate struct { PolicyIdentifiers []asn1.ObjectIdentifier } -// UnsupportedAlgorithmError results from attempting to perform an operation -// that involves algorithms that are not currently implemented. -type UnsupportedAlgorithmError struct{} - -func (UnsupportedAlgorithmError) Error() string { - return "cannot verify signature: algorithm unimplemented" -} +// ErrUnsupportedAlgorithm results from attempting to perform an operation that +// involves algorithms that are not currently implemented. +var ErrUnsupportedAlgorithm = errors.New("crypto/x509: cannot verify signature: algorithm unimplemented") // ConstraintViolationError results when a requested usage is not permitted by // a certificate. For example: checking a signature when the public key isn't a @@ -341,7 +337,7 @@ func (UnsupportedAlgorithmError) Error() string { type ConstraintViolationError struct{} func (ConstraintViolationError) Error() string { - return "invalid signature: parent certificate cannot sign this kind of certificate" + return "crypto/x509: invalid signature: parent certificate cannot sign this kind of certificate" } func (c *Certificate) Equal(other *Certificate) bool { @@ -366,7 +362,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) { } if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm { - return UnsupportedAlgorithmError{} + return ErrUnsupportedAlgorithm } // TODO(agl): don't ignore the path length constraint. @@ -389,12 +385,12 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature case SHA512WithRSA: hashType = crypto.SHA512 default: - return UnsupportedAlgorithmError{} + return ErrUnsupportedAlgorithm } h := hashType.New() if h == nil { - return UnsupportedAlgorithmError{} + return ErrUnsupportedAlgorithm } h.Write(signed) @@ -416,7 +412,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature } return } - return UnsupportedAlgorithmError{} + return ErrUnsupportedAlgorithm } // CheckCRLSignature checks that the signature in crl is from c. @@ -795,7 +791,7 @@ var ( ) func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { - ret = make([]pkix.Extension, 7 /* maximum number of elements. */ ) + ret = make([]pkix.Extension, 7 /* maximum number of elements. */) n := 0 if template.KeyUsage != 0 { diff --git a/libgo/go/database/sql/convert.go b/libgo/go/database/sql/convert.go index 4924ac14e46..bfcb03ccf8d 100644 --- a/libgo/go/database/sql/convert.go +++ b/libgo/go/database/sql/convert.go @@ -17,8 +17,8 @@ import ( // subsetTypeArgs takes a slice of arguments from callers of the sql // package and converts them into a slice of the driver package's // "subset types". -func subsetTypeArgs(args []interface{}) ([]interface{}, error) { - out := make([]interface{}, len(args)) +func subsetTypeArgs(args []interface{}) ([]driver.Value, error) { + out := make([]driver.Value, len(args)) for n, arg := range args { var err error out[n], err = driver.DefaultParameterConverter.ConvertValue(arg) @@ -90,8 +90,8 @@ func convertAssign(dest, src interface{}) error { return nil } - if scanner, ok := dest.(ScannerInto); ok { - return scanner.ScanInto(src) + if scanner, ok := dest.(Scanner); ok { + return scanner.Scan(src) } dpv := reflect.ValueOf(dest) @@ -110,6 +110,14 @@ func convertAssign(dest, src interface{}) error { } switch dv.Kind() { + case reflect.Ptr: + if src == nil { + dv.Set(reflect.Zero(dv.Type())) + return nil + } else { + dv.Set(reflect.New(dv.Type().Elem())) + return convertAssign(dv.Interface(), src) + } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s := asString(src) i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) diff --git a/libgo/go/database/sql/convert_test.go b/libgo/go/database/sql/convert_test.go index 34ee93987fc..9c362d7320a 100644 --- a/libgo/go/database/sql/convert_test.go +++ b/libgo/go/database/sql/convert_test.go @@ -13,6 +13,7 @@ import ( ) var someTime = time.Unix(123, 0) +var answer int64 = 42 type conversionTest struct { s, d interface{} // source and destination @@ -27,6 +28,8 @@ type conversionTest struct { wantbool bool // used if d is of type *bool wanterr string wantiface interface{} + wantptr *int64 // if non-nil, *d's pointed value must be equal to *wantptr + wantnil bool // if true, *d must be *int64(nil) } // Target variables for scanning into. @@ -42,6 +45,7 @@ var ( scanf32 float32 scanf64 float64 scantime time.Time + scanptr *int64 scaniface interface{} ) @@ -98,6 +102,10 @@ var conversionTests = []conversionTest{ {s: "1.5", d: &scanf32, wantf32: float32(1.5)}, {s: "1.5", d: &scanf64, wantf64: float64(1.5)}, + // Pointers + {s: interface{}(nil), d: &scanptr, wantnil: true}, + {s: int64(42), d: &scanptr, wantptr: &answer}, + // To interface{} {s: float64(1.5), d: &scaniface, wantiface: float64(1.5)}, {s: int64(1), d: &scaniface, wantiface: int64(1)}, @@ -107,6 +115,10 @@ var conversionTests = []conversionTest{ {s: nil, d: &scaniface}, } +func intPtrValue(intptr interface{}) interface{} { + return reflect.Indirect(reflect.Indirect(reflect.ValueOf(intptr))).Int() +} + func intValue(intptr interface{}) int64 { return reflect.Indirect(reflect.ValueOf(intptr)).Int() } @@ -162,6 +174,16 @@ func TestConversions(t *testing.T) { if !ct.wanttime.IsZero() && !ct.wanttime.Equal(timeValue(ct.d)) { errf("want time %v, got %v", ct.wanttime, timeValue(ct.d)) } + if ct.wantnil && *ct.d.(**int64) != nil { + errf("want nil, got %v", intPtrValue(ct.d)) + } + if ct.wantptr != nil { + if *ct.d.(**int64) == nil { + errf("want pointer to %v, got nil", *ct.wantptr) + } else if *ct.wantptr != intPtrValue(ct.d) { + errf("want pointer to %v, got %v", *ct.wantptr, intPtrValue(ct.d)) + } + } if ifptr, ok := ct.d.(*interface{}); ok { if !reflect.DeepEqual(ct.wantiface, scaniface) { errf("want interface %#v, got %#v", ct.wantiface, scaniface) diff --git a/libgo/go/database/sql/driver/driver.go b/libgo/go/database/sql/driver/driver.go index b9300776050..7f986b80f2c 100644 --- a/libgo/go/database/sql/driver/driver.go +++ b/libgo/go/database/sql/driver/driver.go @@ -6,21 +6,20 @@ // drivers as used by package sql. // // Most code should use package sql. -// -// Drivers only need to be aware of a subset of Go's types. The sql package -// will convert all types into one of the following: +package driver + +import "errors" + +// A driver Value is a value that drivers must be able to handle. +// A Value is either nil or an instance of one of these types: // // int64 // float64 // bool -// nil // []byte // string [*] everywhere except from Rows.Next. // time.Time -// -package driver - -import "errors" +type Value interface{} // Driver is the interface that must be implemented by a database // driver. @@ -50,11 +49,9 @@ var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented") // first prepare a query, execute the statement, and then close the // statement. // -// All arguments are of a subset type as defined in the package docs. -// // Exec may return ErrSkip. type Execer interface { - Exec(query string, args []interface{}) (Result, error) + Exec(query string, args []Value) (Result, error) } // Conn is a connection to a database. It is not used concurrently @@ -127,18 +124,17 @@ type Stmt interface { NumInput() int // Exec executes a query that doesn't return rows, such - // as an INSERT or UPDATE. The args are all of a subset - // type as defined above. - Exec(args []interface{}) (Result, error) + // as an INSERT or UPDATE. + Exec(args []Value) (Result, error) // Exec executes a query that may return rows, such as a - // SELECT. The args of all of a subset type as defined above. - Query(args []interface{}) (Rows, error) + // SELECT. + Query(args []Value) (Rows, error) } // ColumnConverter may be optionally implemented by Stmt if the // the statement is aware of its own columns' types and can -// convert from any type to a driver subset type. +// convert from any type to a driver Value. type ColumnConverter interface { // ColumnConverter returns a ValueConverter for the provided // column index. If the type of a specific column isn't known @@ -162,12 +158,12 @@ type Rows interface { // the provided slice. The provided slice will be the same // size as the Columns() are wide. // - // The dest slice may be populated with only with values - // of subset types defined above, but excluding string. + // The dest slice may be populated only with + // a driver Value type, but excluding string. // All string values must be converted to []byte. // // Next should return io.EOF when there are no more rows. - Next(dest []interface{}) error + Next(dest []Value) error } // Tx is a transaction. @@ -190,18 +186,19 @@ func (v RowsAffected) RowsAffected() (int64, error) { return int64(v), nil } -// DDLSuccess is a pre-defined Result for drivers to return when a DDL -// command succeeds. -var DDLSuccess ddlSuccess +// ResultNoRows is a pre-defined Result for drivers to return when a DDL +// command (such as a CREATE TABLE) succeeds. It returns an error for both +// LastInsertId and RowsAffected. +var ResultNoRows noRows -type ddlSuccess struct{} +type noRows struct{} -var _ Result = ddlSuccess{} +var _ Result = noRows{} -func (ddlSuccess) LastInsertId() (int64, error) { +func (noRows) LastInsertId() (int64, error) { return 0, errors.New("no LastInsertId available after DDL statement") } -func (ddlSuccess) RowsAffected() (int64, error) { +func (noRows) RowsAffected() (int64, error) { return 0, errors.New("no RowsAffected available after DDL statement") } diff --git a/libgo/go/database/sql/driver/types.go b/libgo/go/database/sql/driver/types.go index f3838852311..3305354dfd0 100644 --- a/libgo/go/database/sql/driver/types.go +++ b/libgo/go/database/sql/driver/types.go @@ -17,28 +17,28 @@ import ( // driver package to provide consistent implementations of conversions // between drivers. The ValueConverters have several uses: // -// * converting from the subset types as provided by the sql package +// * converting from the Value types as provided by the sql package // into a database table's specific column type and making sure it // fits, such as making sure a particular int64 fits in a // table's uint16 column. // // * converting a value as given from the database into one of the -// subset types. +// driver Value types. // -// * by the sql package, for converting from a driver's subset type +// * by the sql package, for converting from a driver's Value type // to a user's type in a scan. type ValueConverter interface { - // ConvertValue converts a value to a restricted subset type. - ConvertValue(v interface{}) (interface{}, error) + // ConvertValue converts a value to a driver Value. + ConvertValue(v interface{}) (Value, error) } -// SubsetValuer is the interface providing the SubsetValue method. +// Valuer is the interface providing the Value method. // -// Types implementing SubsetValuer interface are able to convert -// themselves to one of the driver's allowed subset values. -type SubsetValuer interface { - // SubsetValue returns a driver parameter subset value. - SubsetValue() (interface{}, error) +// Types implementing Valuer interface are able to convert +// themselves to a driver Value. +type Valuer interface { + // Value returns a driver Value. + Value() (Value, error) } // Bool is a ValueConverter that converts input values to bools. @@ -59,7 +59,7 @@ var _ ValueConverter = boolType{} func (boolType) String() string { return "Bool" } -func (boolType) ConvertValue(src interface{}) (interface{}, error) { +func (boolType) ConvertValue(src interface{}) (Value, error) { switch s := src.(type) { case bool: return s, nil @@ -104,7 +104,7 @@ type int32Type struct{} var _ ValueConverter = int32Type{} -func (int32Type) ConvertValue(v interface{}) (interface{}, error) { +func (int32Type) ConvertValue(v interface{}) (Value, error) { rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: @@ -137,7 +137,7 @@ var String stringType type stringType struct{} -func (stringType) ConvertValue(v interface{}) (interface{}, error) { +func (stringType) ConvertValue(v interface{}) (Value, error) { switch v.(type) { case string, []byte: return v, nil @@ -151,7 +151,7 @@ type Null struct { Converter ValueConverter } -func (n Null) ConvertValue(v interface{}) (interface{}, error) { +func (n Null) ConvertValue(v interface{}) (Value, error) { if v == nil { return nil, nil } @@ -164,28 +164,17 @@ type NotNull struct { Converter ValueConverter } -func (n NotNull) ConvertValue(v interface{}) (interface{}, error) { +func (n NotNull) ConvertValue(v interface{}) (Value, error) { if v == nil { return nil, fmt.Errorf("nil value not allowed") } return n.Converter.ConvertValue(v) } -// IsParameterSubsetType reports whether v is of a valid type for a -// parameter. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// string -// -// This is the same list as IsScanSubsetType, with the addition of -// string. -func IsParameterSubsetType(v interface{}) bool { - if IsScanSubsetType(v) { +// IsValue reports whether v is a valid Value parameter type. +// Unlike IsScanValue, IsValue permits the string type. +func IsValue(v interface{}) bool { + if IsScanValue(v) { return true } if _, ok := v.(string); ok { @@ -194,18 +183,9 @@ func IsParameterSubsetType(v interface{}) bool { return false } -// IsScanSubsetType reports whether v is of a valid type for a -// value populated by Rows.Next. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// -// This is the same list as IsParameterSubsetType, without string. -func IsScanSubsetType(v interface{}) bool { +// IsScanValue reports whether v is a valid Value scan type. +// Unlike IsValue, IsScanValue does not permit the string type. +func IsScanValue(v interface{}) bool { if v == nil { return true } @@ -221,7 +201,7 @@ func IsScanSubsetType(v interface{}) bool { // ColumnConverter. // // DefaultParameterConverter returns the given value directly if -// IsSubsetType(value). Otherwise integer type are converted to +// IsValue(value). Otherwise integer type are converted to // int64, floats to float64, and strings to []byte. Other types are // an error. var DefaultParameterConverter defaultConverter @@ -230,24 +210,31 @@ type defaultConverter struct{} var _ ValueConverter = defaultConverter{} -func (defaultConverter) ConvertValue(v interface{}) (interface{}, error) { - if IsParameterSubsetType(v) { +func (defaultConverter) ConvertValue(v interface{}) (Value, error) { + if IsValue(v) { return v, nil } - if svi, ok := v.(SubsetValuer); ok { - sv, err := svi.SubsetValue() + if svi, ok := v.(Valuer); ok { + sv, err := svi.Value() if err != nil { return nil, err } - if !IsParameterSubsetType(sv) { - return nil, fmt.Errorf("non-subset type %T returned from SubsetValue", sv) + if !IsValue(sv) { + return nil, fmt.Errorf("non-Value type %T returned from Value", sv) } return sv, nil } rv := reflect.ValueOf(v) switch rv.Kind() { + case reflect.Ptr: + // indirect pointers + if rv.IsNil() { + return nil, nil + } else { + return defaultConverter{}.ConvertValue(rv.Elem().Interface()) + } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return rv.Int(), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: diff --git a/libgo/go/database/sql/driver/types_test.go b/libgo/go/database/sql/driver/types_test.go index 966bc6b4587..ab82bca7166 100644 --- a/libgo/go/database/sql/driver/types_test.go +++ b/libgo/go/database/sql/driver/types_test.go @@ -18,6 +18,7 @@ type valueConverterTest struct { } var now = time.Now() +var answer int64 = 42 var valueConverterTests = []valueConverterTest{ {Bool, "true", true, ""}, @@ -37,6 +38,9 @@ var valueConverterTests = []valueConverterTest{ {c: Bool, in: "foo", err: "sql/driver: couldn't convert \"foo\" into type bool"}, {c: Bool, in: 2, err: "sql/driver: couldn't convert 2 into type bool"}, {DefaultParameterConverter, now, now, ""}, + {DefaultParameterConverter, (*int64)(nil), nil, ""}, + {DefaultParameterConverter, &answer, answer, ""}, + {DefaultParameterConverter, &now, now, ""}, } func TestValueConverters(t *testing.T) { diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go index 889e2a25232..fc63f03740a 100644 --- a/libgo/go/database/sql/fakedb_test.go +++ b/libgo/go/database/sql/fakedb_test.go @@ -217,7 +217,7 @@ func (c *fakeConn) Close() error { return nil } -func checkSubsetTypes(args []interface{}) error { +func checkSubsetTypes(args []driver.Value) error { for n, arg := range args { switch arg.(type) { case int64, float64, bool, nil, []byte, string, time.Time: @@ -228,7 +228,7 @@ func checkSubsetTypes(args []interface{}) error { return nil } -func (c *fakeConn) Exec(query string, args []interface{}) (driver.Result, error) { +func (c *fakeConn) Exec(query string, args []driver.Value) (driver.Result, error) { // This is an optional interface, but it's implemented here // just to check that all the args of of the proper types. // ErrSkip is returned so the caller acts as if we didn't @@ -379,7 +379,7 @@ func (s *fakeStmt) Close() error { var errClosed = errors.New("fakedb: statement has been closed") -func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { +func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) { if s.closed { return nil, errClosed } @@ -392,12 +392,12 @@ func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { switch s.cmd { case "WIPE": db.wipe() - return driver.DDLSuccess, nil + return driver.ResultNoRows, nil case "CREATE": if err := db.createTable(s.table, s.colName, s.colType); err != nil { return nil, err } - return driver.DDLSuccess, nil + return driver.ResultNoRows, nil case "INSERT": return s.execInsert(args) } @@ -405,7 +405,7 @@ func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { return nil, fmt.Errorf("unimplemented statement Exec command type of %q", s.cmd) } -func (s *fakeStmt) execInsert(args []interface{}) (driver.Result, error) { +func (s *fakeStmt) execInsert(args []driver.Value) (driver.Result, error) { db := s.c.db if len(args) != s.placeholders { panic("error in pkg db; should only get here if size is correct") @@ -441,7 +441,7 @@ func (s *fakeStmt) execInsert(args []interface{}) (driver.Result, error) { return driver.RowsAffected(1), nil } -func (s *fakeStmt) Query(args []interface{}) (driver.Rows, error) { +func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) { if s.closed { return nil, errClosed } @@ -548,7 +548,7 @@ func (rc *rowsCursor) Columns() []string { return rc.cols } -func (rc *rowsCursor) Next(dest []interface{}) error { +func (rc *rowsCursor) Next(dest []driver.Value) error { if rc.closed { return errors.New("fakedb: cursor is closed") } diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index 436d4953ecd..62b551d89b5 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -35,7 +35,7 @@ func Register(name string, driver driver.Driver) { type RawBytes []byte // NullString represents a string that may be null. -// NullString implements the ScannerInto interface so +// NullString implements the Scanner interface so // it can be used as a scan destination: // // var s NullString @@ -52,8 +52,8 @@ type NullString struct { Valid bool // Valid is true if String is not NULL } -// ScanInto implements the ScannerInto interface. -func (ns *NullString) ScanInto(value interface{}) error { +// Scan implements the Scanner interface. +func (ns *NullString) Scan(value interface{}) error { if value == nil { ns.String, ns.Valid = "", false return nil @@ -62,8 +62,8 @@ func (ns *NullString) ScanInto(value interface{}) error { return convertAssign(&ns.String, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (ns NullString) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (ns NullString) Value() (driver.Value, error) { if !ns.Valid { return nil, nil } @@ -71,15 +71,15 @@ func (ns NullString) SubsetValue() (interface{}, error) { } // NullInt64 represents an int64 that may be null. -// NullInt64 implements the ScannerInto interface so +// NullInt64 implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL } -// ScanInto implements the ScannerInto interface. -func (n *NullInt64) ScanInto(value interface{}) error { +// Scan implements the Scanner interface. +func (n *NullInt64) Scan(value interface{}) error { if value == nil { n.Int64, n.Valid = 0, false return nil @@ -88,8 +88,8 @@ func (n *NullInt64) ScanInto(value interface{}) error { return convertAssign(&n.Int64, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullInt64) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullInt64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } @@ -97,15 +97,15 @@ func (n NullInt64) SubsetValue() (interface{}, error) { } // NullFloat64 represents a float64 that may be null. -// NullFloat64 implements the ScannerInto interface so +// NullFloat64 implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullFloat64 struct { Float64 float64 Valid bool // Valid is true if Float64 is not NULL } -// ScanInto implements the ScannerInto interface. -func (n *NullFloat64) ScanInto(value interface{}) error { +// Scan implements the Scanner interface. +func (n *NullFloat64) Scan(value interface{}) error { if value == nil { n.Float64, n.Valid = 0, false return nil @@ -114,8 +114,8 @@ func (n *NullFloat64) ScanInto(value interface{}) error { return convertAssign(&n.Float64, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullFloat64) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullFloat64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } @@ -123,15 +123,15 @@ func (n NullFloat64) SubsetValue() (interface{}, error) { } // NullBool represents a bool that may be null. -// NullBool implements the ScannerInto interface so +// NullBool implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullBool struct { Bool bool Valid bool // Valid is true if Bool is not NULL } -// ScanInto implements the ScannerInto interface. -func (n *NullBool) ScanInto(value interface{}) error { +// Scan implements the Scanner interface. +func (n *NullBool) Scan(value interface{}) error { if value == nil { n.Bool, n.Valid = false, false return nil @@ -140,30 +140,32 @@ func (n *NullBool) ScanInto(value interface{}) error { return convertAssign(&n.Bool, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullBool) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullBool) Value() (driver.Value, error) { if !n.Valid { return nil, nil } return n.Bool, nil } -// ScannerInto is an interface used by Scan. -type ScannerInto interface { - // ScanInto assigns a value from a database driver. +// Scanner is an interface used by Scan. +type Scanner interface { + // Scan assigns a value from a database driver. // - // The value will be of one of the following restricted + // The src value will be of one of the following restricted // set of types: // // int64 // float64 // bool // []byte + // string + // time.Time // nil - for NULL values // // An error should be returned if the value can not be stored // without loss of information. - ScanInto(value interface{}) error + Scan(src interface{}) error } // ErrNoRows is returned by Scan when QueryRow doesn't return a @@ -368,7 +370,7 @@ func (db *DB) Begin() (*Tx, error) { }, nil } -// DriverDatabase returns the database's underlying driver. +// Driver returns the database's underlying driver. func (db *DB) Driver() driver.Driver { return db.driver } @@ -378,7 +380,7 @@ func (db *DB) Driver() driver.Driver { // A transaction must end with a call to Commit or Rollback. // // After a call to Commit or Rollback, all operations on the -// transaction fail with ErrTransactionFinished. +// transaction fail with ErrTxDone. type Tx struct { db *DB @@ -393,11 +395,11 @@ type Tx struct { // done transitions from false to true exactly once, on Commit // or Rollback. once done, all operations fail with - // ErrTransactionFinished. + // ErrTxDone. done bool } -var ErrTransactionFinished = errors.New("sql: Transaction has already been committed or rolled back") +var ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back") func (tx *Tx) close() { if tx.done { @@ -411,7 +413,7 @@ func (tx *Tx) close() { func (tx *Tx) grabConn() (driver.Conn, error) { if tx.done { - return nil, ErrTransactionFinished + return nil, ErrTxDone } tx.cimu.Lock() return tx.ci, nil @@ -424,7 +426,7 @@ func (tx *Tx) releaseConn() { // Commit commits the transaction. func (tx *Tx) Commit() error { if tx.done { - return ErrTransactionFinished + return ErrTxDone } defer tx.close() return tx.txi.Commit() @@ -433,7 +435,7 @@ func (tx *Tx) Commit() error { // Rollback aborts the transaction. func (tx *Tx) Rollback() error { if tx.done { - return ErrTransactionFinished + return ErrTxDone } defer tx.close() return tx.txi.Rollback() @@ -521,12 +523,19 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { } defer tx.releaseConn() + sargs, err := subsetTypeArgs(args) + if err != nil { + return nil, err + } + if execer, ok := ci.(driver.Execer); ok { - resi, err := execer.Exec(query, args) - if err != nil { + resi, err := execer.Exec(query, sargs) + if err == nil { + return result{resi}, nil + } + if err != driver.ErrSkip { return nil, err } - return result{resi}, nil } sti, err := ci.Prepare(query) @@ -535,11 +544,6 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { } defer sti.Close() - sargs, err := subsetTypeArgs(args) - if err != nil { - return nil, err - } - resi, err := sti.Exec(sargs) if err != nil { return nil, err @@ -550,7 +554,7 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { // Query executes a query that returns rows, typically a SELECT. func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) { if tx.done { - return nil, ErrTransactionFinished + return nil, ErrTxDone } stmt, err := tx.Prepare(query) if err != nil { @@ -614,19 +618,21 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) { return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args)) } + sargs := make([]driver.Value, len(args)) + // Convert args to subset types. if cc, ok := si.(driver.ColumnConverter); ok { for n, arg := range args { // First, see if the value itself knows how to convert // itself to a driver type. For example, a NullString // struct changing into a string or nil. - if svi, ok := arg.(driver.SubsetValuer); ok { - sv, err := svi.SubsetValue() + if svi, ok := arg.(driver.Valuer); ok { + sv, err := svi.Value() if err != nil { - return nil, fmt.Errorf("sql: argument index %d from SubsetValue: %v", n, err) + return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err) } - if !driver.IsParameterSubsetType(sv) { - return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from SubsetValue", n, sv) + if !driver.IsValue(sv) { + return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv) } arg = sv } @@ -638,25 +644,25 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) { // truncated), or that a nil can't go into a NOT NULL // column before going across the network to get the // same error. - args[n], err = cc.ColumnConverter(n).ConvertValue(arg) + sargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } - if !driver.IsParameterSubsetType(args[n]) { + if !driver.IsValue(sargs[n]) { return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T", - arg, args[n]) + arg, sargs[n]) } } } else { for n, arg := range args { - args[n], err = driver.DefaultParameterConverter.ConvertValue(arg) + sargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } } } - resi, err := si.Exec(args) + resi, err := si.Exec(sargs) if err != nil { return nil, err } @@ -767,7 +773,7 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) { // Example usage: // // var name string -// err := nameByUseridStmt.QueryRow(id).Scan(&s) +// err := nameByUseridStmt.QueryRow(id).Scan(&name) func (s *Stmt) QueryRow(args ...interface{}) *Row { rows, err := s.Query(args...) if err != nil { @@ -825,7 +831,7 @@ type Rows struct { rowsi driver.Rows closed bool - lastcols []interface{} + lastcols []driver.Value lasterr error closeStmt *Stmt // if non-nil, statement to Close on close } @@ -842,7 +848,7 @@ func (rs *Rows) Next() bool { return false } if rs.lastcols == nil { - rs.lastcols = make([]interface{}, len(rs.rowsi.Columns())) + rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns())) } rs.lasterr = rs.rowsi.Next(rs.lastcols) if rs.lasterr == io.EOF { diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go index c5cadad8499..c985a10beee 100644 --- a/libgo/go/database/sql/sql_test.go +++ b/libgo/go/database/sql/sql_test.go @@ -386,6 +386,38 @@ func TestNullByteSlice(t *testing.T) { } } +func TestPointerParamsAndScans(t *testing.T) { + db := newTestDB(t, "") + defer closeDB(t, db) + exec(t, db, "CREATE|t|id=int32,name=nullstring") + + bob := "bob" + var name *string + + name = &bob + exec(t, db, "INSERT|t|id=10,name=?", name) + name = nil + exec(t, db, "INSERT|t|id=20,name=?", name) + + err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name) + if err != nil { + t.Fatalf("querying id 10: %v", err) + } + if name == nil { + t.Errorf("id 10's name = nil; want bob") + } else if *name != "bob" { + t.Errorf("id 10's name = %q; want bob", *name) + } + + err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name) + if err != nil { + t.Fatalf("querying id 20: %v", err) + } + if name != nil { + t.Errorf("id 20 = %q; want nil", *name) + } +} + func TestQueryRowClosingStmt(t *testing.T) { db := newTestDB(t, "people") defer closeDB(t, db) diff --git a/libgo/go/debug/dwarf/buf.go b/libgo/go/debug/dwarf/buf.go index 6dc28d2568c..08e37be4b38 100644 --- a/libgo/go/debug/dwarf/buf.go +++ b/libgo/go/debug/dwarf/buf.go @@ -13,17 +13,17 @@ import ( // Data buffer being decoded. type buf struct { - dwarf *Data - order binary.ByteOrder - name string - off Offset - data []byte - addrsize int - err error + dwarf *Data + u *unit + order binary.ByteOrder + name string + off Offset + data []byte + err error } -func makeBuf(d *Data, name string, off Offset, data []byte, addrsize int) buf { - return buf{d, d.order, name, off, data, addrsize, nil} +func makeBuf(d *Data, u *unit, name string, off Offset, data []byte) buf { + return buf{d, u, d.order, name, off, data, nil} } func (b *buf) uint8() uint8 { @@ -121,15 +121,17 @@ func (b *buf) int() int64 { // Address-sized uint. func (b *buf) addr() uint64 { - switch b.addrsize { - case 1: - return uint64(b.uint8()) - case 2: - return uint64(b.uint16()) - case 4: - return uint64(b.uint32()) - case 8: - return uint64(b.uint64()) + if b.u != nil { + switch b.u.addrsize { + case 1: + return uint64(b.uint8()) + case 2: + return uint64(b.uint16()) + case 4: + return uint64(b.uint32()) + case 8: + return uint64(b.uint64()) + } } b.error("unknown address size") return 0 diff --git a/libgo/go/debug/dwarf/const.go b/libgo/go/debug/dwarf/const.go index 918b153d078..ebe9a71a0c5 100644 --- a/libgo/go/debug/dwarf/const.go +++ b/libgo/go/debug/dwarf/const.go @@ -207,6 +207,11 @@ const ( formRef8 format = 0x14 formRefUdata format = 0x15 formIndirect format = 0x16 + // following are defined in DWARF 4 + formSecOffset format = 0x17 + formExprLoc format = 0x18 + formFlagPresent format = 0x19 + formRefSig8 format = 0x20 ) // A Tag is the classification (the type) of an Entry. @@ -431,3 +436,30 @@ const ( encUnsignedChar = 0x08 encImaginaryFloat = 0x09 ) + +// Line number opcodes. +const ( + LineExtendedOp = 0 + LineCopy = 1 + LineAdvancePC = 2 + LineAdvanceLine = 3 + LineSetFile = 4 + LineSetColumn = 5 + LineNegateStmt = 6 + LineSetBasicBlock = 7 + LineConstAddPC = 8 + LineFixedAdvancePC = 9 + // next 3 are DWARF 3 + LineSetPrologueEnd = 10 + LineSetEpilogueBegin = 11 + LineSetISA = 12 +) + +// Line number extended opcodes. +const ( + LineExtEndSequence = 1 + LineExtSetAddress = 2 + LineExtDefineFile = 3 + // next 1 is DWARF 4 + LineExtSetDiscriminator = 4 +) diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go index 2885d8fa26c..4761d74cd79 100644 --- a/libgo/go/debug/dwarf/entry.go +++ b/libgo/go/debug/dwarf/entry.go @@ -40,7 +40,7 @@ func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) { } else { data = data[off:] } - b := makeBuf(d, "abbrev", 0, data, 0) + b := makeBuf(d, nil, "abbrev", 0, data) // Error handling is simplified by the buf getters // returning an endless stream of 0s after an error. @@ -182,13 +182,37 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { case formUdata: val = int64(b.uint()) + // exprloc + case formExprLoc: + val = b.bytes(int(b.uint())) + // flag case formFlag: val = b.uint8() == 1 + case formFlagPresent: + val = true + + // lineptr, loclistptr, macptr, rangelistptr + case formSecOffset: + if b.u == nil { + b.error("unknown size for DW_FORM_sec_offset") + } else if b.u.dwarf64 { + val = Offset(b.uint64()) + } else { + val = Offset(b.uint32()) + } // reference to other entry case formRefAddr: - val = Offset(b.addr()) + if b.u == nil { + b.error("unknown version for DW_FORM_ref_addr") + } else if b.u.version == 2 { + val = Offset(b.addr()) + } else if b.u.dwarf64 { + val = Offset(b.uint64()) + } else { + val = Offset(b.uint32()) + } case formRef1: val = Offset(b.uint8()) + ubase case formRef2: @@ -199,6 +223,8 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { val = Offset(b.uint64()) + ubase case formRefUdata: val = Offset(b.uint()) + ubase + case formRefSig8: + val = b.uint64() // string case formString: @@ -208,7 +234,7 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { if b.err != nil { return nil } - b1 := makeBuf(b.dwarf, "str", 0, b.dwarf.str, 0) + b1 := makeBuf(b.dwarf, b.u, "str", 0, b.dwarf.str) b1.skip(int(off)) val = b1.string() if b1.err != nil { @@ -246,6 +272,15 @@ func (d *Data) Reader() *Reader { return r } +// unitReader returns a new reader starting at a specific unit. +func (d *Data) unitReader(i int) *Reader { + r := &Reader{d: d} + r.unit = i + u := &d.unit[i] + r.b = makeBuf(d, u, "info", u.off, u.data) + return r +} + // Seek positions the Reader at offset off in the encoded entry stream. // Offset 0 can be used to denote the first entry. func (r *Reader) Seek(off Offset) { @@ -258,7 +293,7 @@ func (r *Reader) Seek(off Offset) { } u := &d.unit[0] r.unit = 0 - r.b = makeBuf(r.d, "info", u.off, u.data, u.addrsize) + r.b = makeBuf(r.d, u, "info", u.off, u.data) return } @@ -269,7 +304,7 @@ func (r *Reader) Seek(off Offset) { u = &d.unit[i] if u.off <= off && off < u.off+Offset(len(u.data)) { r.unit = i - r.b = makeBuf(r.d, "info", off, u.data[off-u.off:], u.addrsize) + r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) return } } @@ -281,7 +316,7 @@ func (r *Reader) maybeNextUnit() { for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) { r.unit++ u := &r.d.unit[r.unit] - r.b = makeBuf(r.d, "info", u.off, u.data, u.addrsize) + r.b = makeBuf(r.d, u, "info", u.off, u.data) } } diff --git a/libgo/go/debug/dwarf/line.go b/libgo/go/debug/dwarf/line.go new file mode 100644 index 00000000000..f9c77cc87e4 --- /dev/null +++ b/libgo/go/debug/dwarf/line.go @@ -0,0 +1,435 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// DWARF line number information. + +package dwarf + +import ( + "errors" + "path/filepath" + "sort" + "strconv" +) + +// A Line holds all the available information about the source code +// corresponding to a specific program counter address. +type Line struct { + Filename string // source file name + OpIndex int // index of operation in VLIW instruction + Line int // line number + Column int // column number + ISA int // instruction set code + Discriminator int // block discriminator + Stmt bool // instruction starts statement + Block bool // instruction starts basic block + EndPrologue bool // instruction ends function prologue + BeginEpilogue bool // instruction begins function epilogue +} + +// LineForPc returns the line number information for a program counter +// address, if any. When this returns multiple Line structures in a +// context where only one can be used, the last one is the best. +func (d *Data) LineForPC(pc uint64) ([]*Line, error) { + for i := range d.unit { + u := &d.unit[i] + if u.pc == nil { + if err := d.readUnitLine(i, u); err != nil { + return nil, err + } + } + for _, ar := range u.pc { + if pc >= ar.low && pc < ar.high { + return d.findLine(u, pc) + } + } + } + return nil, nil +} + +// readUnitLine reads in the line number information for a compilation +// unit. +func (d *Data) readUnitLine(i int, u *unit) error { + r := d.unitReader(i) + setLineOff := false + for { + e, err := r.Next() + if err != nil { + return err + } + if e == nil { + break + } + if r.unit != i { + break + } + switch e.Tag { + case TagCompileUnit, TagSubprogram, TagEntryPoint, TagInlinedSubroutine: + low, lowok := e.Val(AttrLowpc).(uint64) + high, highok := e.Val(AttrHighpc).(uint64) + if lowok && highok { + u.pc = append(u.pc, addrRange{low, high}) + } else if f, ok := e.Val(AttrRanges).(Offset); ok { + // TODO: Handle AttrRanges and .debug_ranges. + _ = f + } + val := e.Val(AttrStmtList) + if val != nil { + if off, ok := val.(int64); ok { + u.lineoff = Offset(off) + setLineOff = true + } else if off, ok := val.(Offset); ok { + u.lineoff = off + setLineOff = true + } else { + return errors.New("unrecognized format for DW_ATTR_stmt_list") + } + } + if dir, ok := e.Val(AttrCompDir).(string); ok { + u.dir = dir + } + } + } + if !setLineOff { + u.lineoff = Offset(0) + u.lineoff-- + } + return nil +} + +// findLine finds the line information for a PC value, given the unit +// containing the information. +func (d *Data) findLine(u *unit, pc uint64) ([]*Line, error) { + if u.lines == nil { + if err := d.parseLine(u); err != nil { + return nil, err + } + } + + for _, ln := range u.lines { + if pc < ln.addrs[0].pc || pc > ln.addrs[len(ln.addrs)-1].pc { + continue + } + i := sort.Search(len(ln.addrs), + func(i int) bool { return ln.addrs[i].pc > pc }) + i-- + p := new(Line) + *p = ln.line + p.Line = ln.addrs[i].line + ret := []*Line{p} + for i++; i < len(ln.addrs) && ln.addrs[i].pc == pc; i++ { + p = new(Line) + *p = ln.line + p.Line = ln.addrs[i].line + ret = append(ret, p) + } + return ret, nil + } + + return nil, nil +} + +// FileLine returns the file name and line number for a program +// counter address, or "", 0 if unknown. +func (d *Data) FileLine(pc uint64) (string, int, error) { + r, err := d.LineForPC(pc) + if err != nil { + return "", 0, err + } + if r == nil { + return "", 0, nil + } + ln := r[len(r)-1] + return ln.Filename, ln.Line, nil +} + +// A mapLineInfo holds the PC values and line numbers associated with +// a single Line structure. This representation is chosen to reduce +// memory usage based on typical debug info. +type mapLineInfo struct { + line Line // line.Line will be zero + addrs lineAddrs // sorted by PC +} + +// A list of lines. This will be sorted by PC. +type lineAddrs []oneLineInfo + +func (p lineAddrs) Len() int { return len(p) } +func (p lineAddrs) Less(i, j int) bool { return p[i].pc < p[j].pc } +func (p lineAddrs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// A oneLineInfo is a single PC and line number. +type oneLineInfo struct { + pc uint64 + line int +} + +// A lineHdr holds the relevant information from a line number +// program header. +type lineHdr struct { + version uint16 // version of line number encoding + minInsnLen uint8 // minimum instruction length + maxOpsPerInsn uint8 // maximum number of ops per instruction + defStmt bool // initial value of stmt register + lineBase int8 // line adjustment base + lineRange uint8 // line adjustment step + opBase uint8 // base of special opcode values + opLen []uint8 // lengths of standard opcodes + dirs []string // directories + files []string // file names +} + +// parseLine parses the line number information for a compilation unit +func (d *Data) parseLine(u *unit) error { + if u.lineoff+1 == 0 { + return errors.New("unknown line offset") + } + b := makeBuf(d, u, "line", u.lineoff, d.line[u.lineoff:]) + len := uint64(b.uint32()) + dwarf64 := false + if len == 0xffffffff { + len = b.uint64() + dwarf64 = true + } + end := b.off + Offset(len) + hdr := d.parseLineHdr(u, &b, dwarf64) + if b.err == nil { + d.parseLineProgram(u, &b, hdr, end) + } + return b.err +} + +// parseLineHdr parses a line number program header. +func (d *Data) parseLineHdr(u *unit, b *buf, dwarf64 bool) (hdr lineHdr) { + hdr.version = b.uint16() + if hdr.version < 2 || hdr.version > 4 { + b.error("unsupported DWARF version " + strconv.Itoa(int(hdr.version))) + return + } + + var hlen Offset + if dwarf64 { + hlen = Offset(b.uint64()) + } else { + hlen = Offset(b.uint32()) + } + end := b.off + hlen + + hdr.minInsnLen = b.uint8() + if hdr.version < 4 { + hdr.maxOpsPerInsn = 1 + } else { + hdr.maxOpsPerInsn = b.uint8() + } + + if b.uint8() == 0 { + hdr.defStmt = false + } else { + hdr.defStmt = true + } + hdr.lineBase = int8(b.uint8()) + hdr.lineRange = b.uint8() + hdr.opBase = b.uint8() + hdr.opLen = b.bytes(int(hdr.opBase - 1)) + + for d := b.string(); len(d) > 0; d = b.string() { + hdr.dirs = append(hdr.dirs, d) + } + + for f := b.string(); len(f) > 0; f = b.string() { + d := b.uint() + if !filepath.IsAbs(f) { + if d > 0 { + if d > uint64(len(hdr.dirs)) { + b.error("DWARF directory index out of range") + return + } + f = filepath.Join(hdr.dirs[d-1], f) + } else if u.dir != "" { + f = filepath.Join(u.dir, f) + } + } + b.uint() // file's last mtime + b.uint() // file length + hdr.files = append(hdr.files, f) + } + + if end > b.off { + b.bytes(int(end - b.off)) + } + + return +} + +// parseLineProgram parses a line program, adding information to +// d.lineInfo as it goes. +func (d *Data) parseLineProgram(u *unit, b *buf, hdr lineHdr, end Offset) { + address := uint64(0) + line := 1 + resetLineInfo := Line{ + Filename: "", + OpIndex: 0, + Line: 0, + Column: 0, + ISA: 0, + Discriminator: 0, + Stmt: hdr.defStmt, + Block: false, + EndPrologue: false, + BeginEpilogue: false, + } + if len(hdr.files) > 0 { + resetLineInfo.Filename = hdr.files[0] + } + lineInfo := resetLineInfo + + var lines []mapLineInfo + + minInsnLen := uint64(hdr.minInsnLen) + maxOpsPerInsn := uint64(hdr.maxOpsPerInsn) + lineBase := int(hdr.lineBase) + lineRange := hdr.lineRange + newLineInfo := true + for b.off < end && b.err == nil { + op := b.uint8() + if op >= hdr.opBase { + // This is a special opcode. + op -= hdr.opBase + advance := uint64(op / hdr.lineRange) + opIndex := uint64(lineInfo.OpIndex) + address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn) + newOpIndex := int((opIndex + advance) % maxOpsPerInsn) + line += lineBase + int(op%lineRange) + if newOpIndex != lineInfo.OpIndex { + lineInfo.OpIndex = newOpIndex + newLineInfo = true + } + lines, lineInfo, newLineInfo = d.addLine(lines, lineInfo, address, line, newLineInfo) + } else if op == LineExtendedOp { + c := b.uint() + op = b.uint8() + switch op { + case LineExtEndSequence: + u.lines = append(u.lines, lines...) + lineInfo = resetLineInfo + lines = nil + newLineInfo = true + case LineExtSetAddress: + address = b.addr() + case LineExtDefineFile: + f := b.string() + d := b.uint() + b.uint() // mtime + b.uint() // length + if d > 0 && !filepath.IsAbs(f) { + if d >= uint64(len(hdr.dirs)) { + b.error("DWARF directory index out of range") + return + } + f = filepath.Join(hdr.dirs[d-1], f) + } + hdr.files = append(hdr.files, f) + case LineExtSetDiscriminator: + lineInfo.Discriminator = int(b.uint()) + newLineInfo = true + default: + if c > 0 { + b.bytes(int(c) - 1) + } + } + } else { + switch op { + case LineCopy: + lines, lineInfo, newLineInfo = d.addLine(lines, lineInfo, address, line, newLineInfo) + case LineAdvancePC: + advance := b.uint() + opIndex := uint64(lineInfo.OpIndex) + address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn) + newOpIndex := int((opIndex + advance) % maxOpsPerInsn) + if newOpIndex != lineInfo.OpIndex { + lineInfo.OpIndex = newOpIndex + newLineInfo = true + } + case LineAdvanceLine: + line += int(b.int()) + case LineSetFile: + i := b.uint() + if i > uint64(len(hdr.files)) { + b.error("DWARF file number out of range") + return + } + lineInfo.Filename = hdr.files[i] + newLineInfo = true + case LineSetColumn: + lineInfo.Column = int(b.uint()) + newLineInfo = true + case LineNegateStmt: + lineInfo.Stmt = !lineInfo.Stmt + newLineInfo = true + case LineSetBasicBlock: + lineInfo.Block = true + newLineInfo = true + case LineConstAddPC: + op = 255 - hdr.opBase + advance := uint64(op / hdr.lineRange) + opIndex := uint64(lineInfo.OpIndex) + address += minInsnLen * ((opIndex + advance) / maxOpsPerInsn) + newOpIndex := int((opIndex + advance) % maxOpsPerInsn) + if newOpIndex != lineInfo.OpIndex { + lineInfo.OpIndex = newOpIndex + newLineInfo = true + } + case LineFixedAdvancePC: + address += uint64(b.uint16()) + if lineInfo.OpIndex != 0 { + lineInfo.OpIndex = 0 + newLineInfo = true + } + case LineSetPrologueEnd: + lineInfo.EndPrologue = true + newLineInfo = true + case LineSetEpilogueBegin: + lineInfo.BeginEpilogue = true + newLineInfo = true + case LineSetISA: + lineInfo.ISA = int(b.uint()) + newLineInfo = true + default: + if int(op) >= len(hdr.opLen) { + b.error("DWARF line opcode has unknown length") + return + } + for i := hdr.opLen[op-1]; i > 0; i-- { + b.int() + } + } + } + } +} + +// addLine adds the current address and line to lines using lineInfo. +// If newLineInfo is true this is a new lineInfo. This returns the +// updated lines, lineInfo, and newLineInfo. +func (d *Data) addLine(lines []mapLineInfo, lineInfo Line, address uint64, line int, newLineInfo bool) ([]mapLineInfo, Line, bool) { + if newLineInfo { + if len(lines) > 0 { + sort.Sort(lines[len(lines)-1].addrs) + } + lines = append(lines, mapLineInfo{line: lineInfo}) + } + p := &lines[len(lines)-1] + p.addrs = append(p.addrs, oneLineInfo{address, line}) + + if lineInfo.Block || lineInfo.EndPrologue || lineInfo.BeginEpilogue || lineInfo.Discriminator != 0 { + lineInfo.Block = false + lineInfo.EndPrologue = false + lineInfo.BeginEpilogue = false + lineInfo.Discriminator = 0 + newLineInfo = true + } else { + newLineInfo = false + } + + return lines, lineInfo, newLineInfo +} diff --git a/libgo/go/debug/dwarf/line_test.go b/libgo/go/debug/dwarf/line_test.go new file mode 100644 index 00000000000..2476a6faf53 --- /dev/null +++ b/libgo/go/debug/dwarf/line_test.go @@ -0,0 +1,53 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dwarf_test + +import ( + . "debug/dwarf" + "path/filepath" + "testing" +) + +type lineTest struct { + pc uint64 + file string + line int +} + +var elfLineTests = [...]lineTest{ + {0x4004c4, "typedef.c", 83}, + {0x4004c8, "typedef.c", 84}, + {0x4004ca, "typedef.c", 84}, + {0x4003e0, "", 0}, +} + +var machoLineTests = [...]lineTest{ + {0x0, "typedef.c", 83}, +} + +func TestLineElf(t *testing.T) { + testLine(t, elfData(t, "testdata/typedef.elf"), elfLineTests[:], "elf") +} + +func TestLineMachO(t *testing.T) { + testLine(t, machoData(t, "testdata/typedef.macho"), machoLineTests[:], "macho") +} + +func testLine(t *testing.T, d *Data, tests []lineTest, kind string) { + for _, v := range tests { + file, line, err := d.FileLine(v.pc) + if err != nil { + t.Errorf("%s: %v", kind, err) + continue + } + if file != "" { + file = filepath.Base(file) + } + if file != v.file || line != v.line { + t.Errorf("%s: for %d have %q:%d want %q:%d", + kind, v.pc, file, line, v.file, v.line) + } + } +} diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go index 9543297e189..75798925296 100644 --- a/libgo/go/debug/dwarf/open.go +++ b/libgo/go/debug/dwarf/open.go @@ -24,15 +24,15 @@ type Data struct { // parsed data abbrevCache map[uint32]abbrevTable - addrsize int order binary.ByteOrder typeCache map[Offset]Type unit []unit } // New returns a new Data object initialized from the given parameters. -// Clients should typically use [TODO(rsc): method to be named later] instead of calling -// New directly. +// Rather than calling this function directly, clients should typically use +// the DWARF method of the File type of the appropriate package debug/elf, +// debug/macho, or debug/pe. // // The []byte arguments are the data from the corresponding debug section // in the object file; for example, for an ELF object, abbrev is the contents of diff --git a/libgo/go/debug/dwarf/testdata/typedef.c b/libgo/go/debug/dwarf/testdata/typedef.c index 664d021ced5..f05f01564ff 100644 --- a/libgo/go/debug/dwarf/testdata/typedef.c +++ b/libgo/go/debug/dwarf/testdata/typedef.c @@ -28,8 +28,13 @@ typedef struct my_struct { volatile int vi; char x : 1; int y : 4; + int z[0]; long long array[40]; + int zz[0]; } t_my_struct; +typedef struct my_struct1 { + int zz [1]; +} t_my_struct1; typedef union my_union { volatile int vi; char x : 1; @@ -65,7 +70,8 @@ t_func_void_of_char *a9; t_func_void_of_void *a10; t_func_void_of_ptr_char_dots *a11; t_my_struct *a12; -t_my_union *a12a; +t_my_struct1 *a12a; +t_my_union *a12b; t_my_enum *a13; t_my_list *a14; t_my_tree *a15; diff --git a/libgo/go/debug/dwarf/testdata/typedef.elf b/libgo/go/debug/dwarf/testdata/typedef.elf Binary files differindex 44df8da9bc7..b2062d2c4bb 100755 --- a/libgo/go/debug/dwarf/testdata/typedef.elf +++ b/libgo/go/debug/dwarf/testdata/typedef.elf diff --git a/libgo/go/debug/dwarf/testdata/typedef.macho b/libgo/go/debug/dwarf/testdata/typedef.macho Binary files differindex 41019c1e146..f75afcccbfc 100644 --- a/libgo/go/debug/dwarf/testdata/typedef.macho +++ b/libgo/go/debug/dwarf/testdata/typedef.macho diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go index 9be66658fe9..2ef8ca01bf8 100644 --- a/libgo/go/debug/dwarf/type.go +++ b/libgo/go/debug/dwarf/type.go @@ -426,6 +426,8 @@ func (d *Data) Type(off Offset) (Type, error) { t.StructName, _ = e.Val(AttrName).(string) t.Incomplete = e.Val(AttrDeclaration) != nil t.Field = make([]*StructField, 0, 8) + var lastFieldType Type + var lastFieldBitOffset int64 for kid := next(); kid != nil; kid = next() { if kid.Tag == TagMember { f := new(StructField) @@ -433,7 +435,7 @@ func (d *Data) Type(off Offset) (Type, error) { goto Error } if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok { - b := makeBuf(d, "location", 0, loc, d.addrsize) + b := makeBuf(d, nil, "location", 0, loc) if b.uint8() != opPlusUconst { err = DecodeError{"info", kid.Offset, "unexpected opcode"} goto Error @@ -444,11 +446,32 @@ func (d *Data) Type(off Offset) (Type, error) { goto Error } } + + haveBitOffset := false f.Name, _ = kid.Val(AttrName).(string) f.ByteSize, _ = kid.Val(AttrByteSize).(int64) - f.BitOffset, _ = kid.Val(AttrBitOffset).(int64) + f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64) f.BitSize, _ = kid.Val(AttrBitSize).(int64) t.Field = append(t.Field, f) + + bito := f.BitOffset + if !haveBitOffset { + bito = f.ByteOffset * 8 + } + if bito == lastFieldBitOffset && t.Kind != "union" { + // Last field was zero width. Fix array length. + // (DWARF writes out 0-length arrays as if they were 1-length arrays.) + zeroArray(lastFieldType) + } + lastFieldType = f.Type + lastFieldBitOffset = bito + } + } + if t.Kind != "union" { + b, ok := e.Val(AttrByteSize).(int64) + if ok && b*8 == lastFieldBitOffset { + // Final field must be zero width. Fix array length. + zeroArray(lastFieldType) } } @@ -579,3 +602,14 @@ Error: delete(d.typeCache, off) return nil, err } + +func zeroArray(t Type) { + for { + at, ok := t.(*ArrayType) + if !ok { + break + } + at.Count = 0 + t = at.Type + } +} diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go index b9470a4fcb4..b5b255f6f4a 100644 --- a/libgo/go/debug/dwarf/type_test.go +++ b/libgo/go/debug/dwarf/type_test.go @@ -25,13 +25,22 @@ var typedefTests = map[string]string{ "t_func_void_of_char": "func(char) void", "t_func_void_of_void": "func() void", "t_func_void_of_ptr_char_dots": "func(*char, ...) void", - "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; array [40]long long int@8}", + "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}", + "t_my_struct1": "struct my_struct1 {zz [1]int@0}", "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}", "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}", "t_my_list": "struct list {val short int@0; next *t_my_list@8}", "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}", } +// As Apple converts gcc to a clang-based front end +// they keep breaking the DWARF output. This map lists the +// conversion from real answer to Apple answer. +var machoBug = map[string]string{ + "func(*char, ...) void": "func(*char) void", + "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}": "enum my_enum {e1=1; e2=2; e3=-5; e4=-1530494976}", +} + func elfData(t *testing.T, name string) *Data { f, err := elf.Open(name) if err != nil { @@ -58,13 +67,13 @@ func machoData(t *testing.T, name string) *Data { return d } -func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf")) } +func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") } func TestTypedefsMachO(t *testing.T) { - testTypedefs(t, machoData(t, "testdata/typedef.macho")) + testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho") } -func testTypedefs(t *testing.T, d *Data) { +func testTypedefs(t *testing.T, d *Data, kind string) { r := d.Reader() seen := make(map[string]bool) for { @@ -93,7 +102,7 @@ func testTypedefs(t *testing.T, d *Data) { t.Errorf("multiple definitions for %s", t1.Name) } seen[t1.Name] = true - if typstr != want { + if typstr != want && (kind != "macho" || typstr != machoBug[want]) { t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want) } } diff --git a/libgo/go/debug/dwarf/unit.go b/libgo/go/debug/dwarf/unit.go index c10d75dbdc9..b1903208715 100644 --- a/libgo/go/debug/dwarf/unit.go +++ b/libgo/go/debug/dwarf/unit.go @@ -12,17 +12,38 @@ import "strconv" type unit struct { base Offset // byte offset of header within the aggregate info off Offset // byte offset of data within the aggregate info + lineoff Offset // byte offset of data within the line info data []byte atable abbrevTable addrsize int + version int + dwarf64 bool // True for 64-bit DWARF format + dir string + pc []addrRange // PC ranges in this compilation unit + lines []mapLineInfo // PC -> line mapping +} + +// A range is an address range. +type addrRange struct { + low uint64 + high uint64 } func (d *Data) parseUnits() ([]unit, error) { // Count units. nunit := 0 - b := makeBuf(d, "info", 0, d.info, 0) + b := makeBuf(d, nil, "info", 0, d.info) for len(b.data) > 0 { - b.skip(int(b.uint32())) + len := b.uint32() + if len == 0xffffffff { + len64 := b.uint64() + if len64 != uint64(int(len64)) { + b.error("unit length overflow") + break + } + len = uint32(len64) + } + b.skip(int(len)) nunit++ } if b.err != nil { @@ -30,13 +51,18 @@ func (d *Data) parseUnits() ([]unit, error) { } // Again, this time writing them down. - b = makeBuf(d, "info", 0, d.info, 0) + b = makeBuf(d, nil, "info", 0, d.info) units := make([]unit, nunit) for i := range units { u := &units[i] u.base = b.off n := b.uint32() - if vers := b.uint16(); vers != 2 { + if n == 0xffffffff { + u.dwarf64 = true + n = uint32(b.uint64()) + } + vers := b.uint16() + if vers < 2 || vers > 4 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } @@ -47,6 +73,7 @@ func (d *Data) parseUnits() ([]unit, error) { } break } + u.version = int(vers) u.atable = atable u.addrsize = int(b.uint8()) u.off = b.off diff --git a/libgo/go/debug/elf/elf_test.go b/libgo/go/debug/elf/elf_test.go index 67b961b5c6c..b8cdbcc7e51 100644 --- a/libgo/go/debug/elf/elf_test.go +++ b/libgo/go/debug/elf/elf_test.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package elf +package elf_test import ( + . "debug/elf" "fmt" "testing" ) diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index 184ca8375b5..c2c03d2c647 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -563,7 +563,7 @@ func (f *File) DWARF() (*dwarf.Data, error) { // There are many other DWARF sections, but these // are the required ones, and the debug/dwarf package // does not use the others, so don't bother loading them. - var names = [...]string{"abbrev", "info", "str"} + var names = [...]string{"abbrev", "info", "line", "str"} var dat [len(names)][]byte for i, name := range names { name = ".debug_" + name @@ -592,8 +592,8 @@ func (f *File) DWARF() (*dwarf.Data, error) { } } - abbrev, info, str := dat[0], dat[1], dat[2] - return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) + abbrev, info, line, str := dat[0], dat[1], dat[2], dat[3] + return dwarf.New(abbrev, nil, nil, info, line, nil, nil, str) } // Symbols returns the symbol table for f. diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go index 98f2723c86e..105b697a4fb 100644 --- a/libgo/go/debug/elf/file_test.go +++ b/libgo/go/debug/elf/file_test.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package elf +package elf_test import ( "debug/dwarf" + . "debug/elf" "encoding/binary" "net" "os" diff --git a/libgo/go/debug/elf/runtime.go b/libgo/go/debug/elf/runtime.go new file mode 100644 index 00000000000..17cb6fbc99e --- /dev/null +++ b/libgo/go/debug/elf/runtime.go @@ -0,0 +1,161 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This is gccgo-specific code that uses DWARF information to fetch +// file/line information for PC values. This package registers itself +// with the runtime package. + +package elf + +import ( + "debug/dwarf" + "debug/macho" + "os" + "runtime" + "sort" + "sync" +) + +func init() { + // Register our lookup functions with the runtime package. + runtime.RegisterDebugLookup(funcFileLine, symbolValue) +} + +// The file struct holds information for a specific file that is part +// of the execution. +type file struct { + elf *File // If ELF + macho *macho.File // If Mach-O + dwarf *dwarf.Data // DWARF information + + symsByName []sym // Sorted by name + symsByAddr []sym // Sorted by address +} + +// Sort symbols by name. +type symsByName []sym + +func (s symsByName) Len() int { return len(s) } +func (s symsByName) Less(i, j int) bool { return s[i].name < s[j].name } +func (s symsByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// Sort symbols by address. +type symsByAddr []sym + +func (s symsByAddr) Len() int { return len(s) } +func (s symsByAddr) Less(i, j int) bool { return s[i].addr < s[j].addr } +func (s symsByAddr) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// The sym structure holds the information we care about for a symbol, +// namely name and address. +type sym struct { + name string + addr uintptr +} + +// Open an input file. +func open(name string) (*file, error) { + efile, err := Open(name) + var mfile *macho.File + if err != nil { + var merr error + mfile, merr = macho.Open(name) + if merr != nil { + return nil, err + } + } + + r := &file{elf: efile, macho: mfile} + + if efile != nil { + r.dwarf, err = efile.DWARF() + } else { + r.dwarf, err = mfile.DWARF() + } + if err != nil { + return nil, err + } + + var syms []sym + if efile != nil { + esyms, err := efile.Symbols() + if err != nil { + return nil, err + } + syms = make([]sym, 0, len(esyms)) + for _, s := range esyms { + if ST_TYPE(s.Info) == STT_FUNC { + syms = append(syms, sym{s.Name, uintptr(s.Value)}) + } + } + } else { + syms = make([]sym, 0, len(mfile.Symtab.Syms)) + for _, s := range mfile.Symtab.Syms { + syms = append(syms, sym{s.Name, uintptr(s.Value)}) + } + } + + r.symsByName = make([]sym, len(syms)) + copy(r.symsByName, syms) + sort.Sort(symsByName(r.symsByName)) + + r.symsByAddr = syms + sort.Sort(symsByAddr(r.symsByAddr)) + + return r, nil +} + +// The main executable +var executable *file + +// Only open the executable once. +var executableOnce sync.Once + +func openExecutable() { + executableOnce.Do(func() { + f, err := open("/proc/self/exe") + if err != nil { + f, err = open(os.Args[0]) + if err != nil { + return + } + } + executable = f + }) +} + +// The funcFileLine function looks up the function name, file name, +// and line number for a PC value. +func funcFileLine(pc uintptr, function *string, file *string, line *int) bool { + openExecutable() + if executable == nil || executable.dwarf == nil { + return false + } + f, ln, err := executable.dwarf.FileLine(uint64(pc)) + if err != nil { + return false + } + *file = f + *line = ln + + *function = "" + if len(executable.symsByAddr) > 0 && pc >= executable.symsByAddr[0].addr { + i := sort.Search(len(executable.symsByAddr), + func(i int) bool { return executable.symsByAddr[i].addr > pc }) + *function = executable.symsByAddr[i-1].name + } + + return true +} + +// The symbolValue function fetches the value of a symbol. +func symbolValue(name string, val *uintptr) bool { + i := sort.Search(len(executable.symsByName), + func(i int) bool { return executable.symsByName[i].name >= name }) + if i >= len(executable.symsByName) || executable.symsByName[i].name != name { + return false + } + *val = executable.symsByName[i].addr + return true +} diff --git a/libgo/go/debug/gosym/pclntab_test.go b/libgo/go/debug/gosym/pclntab_test.go index b90181bdc64..b2400bb3ba7 100644 --- a/libgo/go/debug/gosym/pclntab_test.go +++ b/libgo/go/debug/gosym/pclntab_test.go @@ -6,15 +6,37 @@ package gosym import ( "debug/elf" + "fmt" "os" + "os/exec" "runtime" + "strings" "testing" ) +var pclinetestBinary string + func dotest() bool { // For now, only works on ELF platforms. - // TODO: convert to work with new go tool - return false && runtime.GOOS == "linux" && runtime.GOARCH == "amd64" + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + return false + } + if pclinetestBinary != "" { + return true + } + // This command builds pclinetest from pclinetest.asm; + // the resulting binary looks like it was built from pclinetest.s, + // but we have renamed it to keep it away from the go tool. + pclinetestBinary = os.TempDir() + "/pclinetest" + command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -E main -o %s %s.6", + pclinetestBinary, pclinetestBinary, pclinetestBinary) + cmd := exec.Command("sh", "-c", command) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic(err) + } + return true } func getTable(t *testing.T) *Table { @@ -149,7 +171,7 @@ func TestPCLine(t *testing.T) { return } - f, tab := crack("_test/pclinetest", t) + f, tab := crack(pclinetestBinary, t) text := f.Section(".text") textdat, err := text.Data() if err != nil { @@ -163,10 +185,13 @@ func TestPCLine(t *testing.T) { file, line, fn := tab.PCToLine(pc) off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g wantLine += int(textdat[off]) + t.Logf("off is %d", off) if fn == nil { t.Errorf("failed to get line of PC %#x", pc) - } else if len(file) < 12 || file[len(file)-12:] != "pclinetest.s" || line != wantLine || fn != sym { - t.Errorf("expected %s:%d (%s) at PC %#x, got %s:%d (%s)", "pclinetest.s", wantLine, sym.Name, pc, file, line, fn.Name) + } else if !strings.HasSuffix(file, "pclinetest.asm") { + t.Errorf("expected %s (%s) at PC %#x, got %s (%s)", "pclinetest.asm", sym.Name, pc, file, fn.Name) + } else if line != wantLine || fn != sym { + t.Errorf("expected :%d (%s) at PC %#x, got :%d (%s)", wantLine, sym.Name, pc, line, fn.Name) } } diff --git a/libgo/go/debug/macho/file.go b/libgo/go/debug/macho/file.go index c7cb90526e8..6577803a075 100644 --- a/libgo/go/debug/macho/file.go +++ b/libgo/go/debug/macho/file.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package macho implements access to Mach-O object files, as defined by -// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html. +// Package macho implements access to Mach-O object files. package macho // High level access to low level data structures. @@ -468,7 +467,7 @@ func (f *File) DWARF() (*dwarf.Data, error) { // There are many other DWARF sections, but these // are the required ones, and the debug/dwarf package // does not use the others, so don't bother loading them. - var names = [...]string{"abbrev", "info", "str"} + var names = [...]string{"abbrev", "info", "line", "str"} var dat [len(names)][]byte for i, name := range names { name = "__debug_" + name @@ -483,8 +482,8 @@ func (f *File) DWARF() (*dwarf.Data, error) { dat[i] = b } - abbrev, info, str := dat[0], dat[1], dat[2] - return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) + abbrev, info, line, str := dat[0], dat[1], dat[2], dat[3] + return dwarf.New(abbrev, nil, nil, info, line, nil, nil, str) } // ImportedSymbols returns the names of all symbols diff --git a/libgo/go/debug/macho/file_test.go b/libgo/go/debug/macho/file_test.go index 640225b3291..ecc6f68a947 100644 --- a/libgo/go/debug/macho/file_test.go +++ b/libgo/go/debug/macho/file_test.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package macho +package macho_test import ( + . "debug/macho" "reflect" "testing" ) diff --git a/libgo/go/encoding/binary/binary.go b/libgo/go/encoding/binary/binary.go index 4be83f53bd4..02f090d53f3 100644 --- a/libgo/go/encoding/binary/binary.go +++ b/libgo/go/encoding/binary/binary.go @@ -5,6 +5,9 @@ // Package binary implements translation between // unsigned integer values and byte sequences // and the reading and writing of fixed-size values. +// A fixed-size value is either a fixed-size arithmetic +// type (int8, uint8, int16, float32, complex64, ...) +// or an array or struct containing only fixed-size values. package binary import ( @@ -26,17 +29,13 @@ type ByteOrder interface { String() string } -// This is byte instead of struct{} so that it can be compared, -// allowing, e.g., order == binary.LittleEndian. -type unused byte - // LittleEndian is the little-endian implementation of ByteOrder. var LittleEndian littleEndian // BigEndian is the big-endian implementation of ByteOrder. var BigEndian bigEndian -type littleEndian unused +type littleEndian struct{} func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 } @@ -76,7 +75,7 @@ func (littleEndian) String() string { return "LittleEndian" } func (littleEndian) GoString() string { return "binary.LittleEndian" } -type bigEndian unused +type bigEndian struct{} func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 } @@ -119,9 +118,6 @@ func (bigEndian) GoString() string { return "binary.BigEndian" } // Read reads structured binary data from r into data. // Data must be a pointer to a fixed-size value or a slice // of fixed-size values. -// A fixed-size value is either a fixed-size arithmetic -// type (int8, uint8, int16, float32, complex64, ...) -// or an array or struct containing only fixed-size values. // Bytes read from r are decoded using the specified byte order // and written to successive fields of the data. func Read(r io.Reader, order ByteOrder, data interface{}) error { @@ -176,11 +172,8 @@ func Read(r io.Reader, order ByteOrder, data interface{}) error { } // Write writes the binary representation of data into w. -// Data must be a fixed-size value or a pointer to -// a fixed-size value. -// A fixed-size value is either a fixed-size arithmetic -// type (int8, uint8, int16, float32, complex64, ...) -// or an array or struct containing only fixed-size values. +// Data must be a fixed-size value or a slice of fixed-size +// values, or a pointer to such data. // Bytes written to w are encoded using the specified byte order // and read from successive fields of the data. func Write(w io.Writer, order ByteOrder, data interface{}) error { @@ -253,6 +246,12 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error { return err } +// Size returns how many bytes Write would generate to encode the value v, which +// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. +func Size(v interface{}) int { + return dataSize(reflect.Indirect(reflect.ValueOf(v))) +} + // dataSize returns the number of bytes the actual data represented by v occupies in memory. // For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice // it returns the length of the slice times the element size and does not count the memory @@ -373,6 +372,7 @@ func (d *decoder) value(v reflect.Value) { for i := 0; i < l; i++ { d.value(v.Index(i)) } + case reflect.Struct: l := v.NumField() for i := 0; i < l; i++ { @@ -428,11 +428,13 @@ func (e *encoder) value(v reflect.Value) { for i := 0; i < l; i++ { e.value(v.Index(i)) } + case reflect.Struct: l := v.NumField() for i := 0; i < l; i++ { e.value(v.Field(i)) } + case reflect.Slice: l := v.Len() for i := 0; i < l; i++ { diff --git a/libgo/go/encoding/binary/binary_test.go b/libgo/go/encoding/binary/binary_test.go index ff361b7e379..dec47a1894f 100644 --- a/libgo/go/encoding/binary/binary_test.go +++ b/libgo/go/encoding/binary/binary_test.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package binary +package binary_test import ( "bytes" + . "encoding/binary" "io" "math" "reflect" @@ -187,7 +188,7 @@ func BenchmarkReadStruct(b *testing.B) { bsr := &byteSliceReader{} var buf bytes.Buffer Write(&buf, BigEndian, &s) - n := dataSize(reflect.ValueOf(s)) + n := DataSize(reflect.ValueOf(s)) b.SetBytes(int64(n)) t := s b.ResetTimer() diff --git a/libgo/go/encoding/binary/export_test.go b/libgo/go/encoding/binary/export_test.go new file mode 100644 index 00000000000..9eae2a961fc --- /dev/null +++ b/libgo/go/encoding/binary/export_test.go @@ -0,0 +1,15 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package binary + +import "reflect" + +// Export for testing. + +func DataSize(v reflect.Value) int { + return dataSize(v) +} + +var Overflow = overflow diff --git a/libgo/go/encoding/binary/varint_test.go b/libgo/go/encoding/binary/varint_test.go index 9476bd5fb7a..f67ca6321bd 100644 --- a/libgo/go/encoding/binary/varint_test.go +++ b/libgo/go/encoding/binary/varint_test.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package binary +package binary_test import ( "bytes" + . "encoding/binary" "io" "testing" ) @@ -134,8 +135,8 @@ func testOverflow(t *testing.T, buf []byte, n0 int, err0 error) { } func TestOverflow(t *testing.T) { - testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, -10, overflow) - testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, -13, overflow) + testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, -10, Overflow) + testOverflow(t, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, -13, Overflow) } func TestNonCanonicalZero(t *testing.T) { diff --git a/libgo/go/encoding/gob/codec_test.go b/libgo/go/encoding/gob/codec_test.go index d365f826345..ebcbb78ebe6 100644 --- a/libgo/go/encoding/gob/codec_test.go +++ b/libgo/go/encoding/gob/codec_test.go @@ -1455,11 +1455,14 @@ func TestFuzz(t *testing.T) { func TestFuzzRegressions(t *testing.T) { // An instance triggering a type name of length ~102 GB. testFuzz(t, 1328492090837718000, 100, new(float32)) + // An instance triggering a type name of 1.6 GB. + // Commented out because it takes 5m to run. + //testFuzz(t, 1330522872628565000, 100, new(int)) } func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) { - t.Logf("seed=%d n=%d\n", seed, n) for _, e := range input { + t.Logf("seed=%d n=%d e=%T", seed, n, e) rng := rand.New(rand.NewSource(seed)) for i := 0; i < n; i++ { encFuzzDec(rng, e) diff --git a/libgo/go/encoding/gob/debug.go b/libgo/go/encoding/gob/debug.go index b54ef46f52c..31d1351fc4f 100644 --- a/libgo/go/encoding/gob/debug.go +++ b/libgo/go/encoding/gob/debug.go @@ -3,14 +3,15 @@ // license that can be found in the LICENSE file. // Delete the next line to include in the gob package. -// +build gob-debug +// +build ignore package gob // This file is not normally included in the gob package. Used only for debugging the package itself. -// Add debug.go to the files listed in the Makefile to add Debug to the gob package. // Except for reading uints, it is an implementation of a reader that is independent of // the one implemented by Decoder. +// To enable the Debug function, delete the +build ignore line above and do +// go install import ( "bytes" diff --git a/libgo/go/encoding/gob/decode.go b/libgo/go/encoding/gob/decode.go index 8191062d309..0708a83c99a 100644 --- a/libgo/go/encoding/gob/decode.go +++ b/libgo/go/encoding/gob/decode.go @@ -392,12 +392,12 @@ func decUint8Slice(i *decInstr, state *decoderState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - n := int(state.decodeUint()) - if n < 0 { - errorf("negative length decoding []byte") + n := state.decodeUint() + if n > uint64(state.b.Len()) { + errorf("length of []byte exceeds input size (%d bytes)", n) } slice := (*[]uint8)(p) - if cap(*slice) < n { + if uint64(cap(*slice)) < n { *slice = make([]uint8, n) } else { *slice = (*slice)[0:n] @@ -417,7 +417,11 @@ func decString(i *decInstr, state *decoderState, p unsafe.Pointer) { } p = *(*unsafe.Pointer)(p) } - b := make([]byte, state.decodeUint()) + n := state.decodeUint() + if n > uint64(state.b.Len()) { + errorf("string length exceeds input size (%d bytes)", n) + } + b := make([]byte, n) state.b.Read(b) // It would be a shame to do the obvious thing here, // *(*string)(p) = string(b) @@ -456,7 +460,7 @@ func allocate(rtyp reflect.Type, p uintptr, indir int) uintptr { } if *(*unsafe.Pointer)(up) == nil { // Allocate object. - *(*unsafe.Pointer)(up) = unsafe.New(rtyp) + *(*unsafe.Pointer)(up) = unsafe.Pointer(reflect.New(rtyp).Pointer()) } return *(*uintptr)(up) } @@ -464,7 +468,7 @@ func allocate(rtyp reflect.Type, p uintptr, indir int) uintptr { // decodeSingle decodes a top-level value that is not a struct and stores it through p. // Such values are preceded by a zero, making them have the memory layout of a // struct field (although with an illegal field number). -func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uintptr) (err error) { +func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uintptr) { state := dec.newDecoderState(&dec.buf) state.fieldnum = singletonField delta := int(state.decodeUint()) @@ -473,7 +477,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uint } instr := &engine.instr[singletonField] if instr.indir != ut.indir { - return errors.New("gob: internal error: inconsistent indirection") + errorf("internal error: inconsistent indirection instr %d ut %d", instr.indir, ut.indir) } ptr := unsafe.Pointer(basep) // offset will be zero if instr.indir > 1 { @@ -481,10 +485,9 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uint } instr.op(instr, state, ptr) dec.freeDecoderState(state) - return nil } -// decodeSingle decodes a top-level struct and stores it through p. +// decodeStruct decodes a top-level struct and stores it through p. // Indir is for the value, not the type. At the time of the call it may // differ from ut.indir, which was computed when the engine was built. // This state cannot arise for decodeSingle, which is called directly @@ -609,7 +612,7 @@ func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, p uintptr, // Maps cannot be accessed by moving addresses around the way // that slices etc. can. We must recover a full reflection value for // the iteration. - v := reflect.ValueOf(unsafe.Unreflect(mtyp, unsafe.Pointer(p))) + v := reflect.NewAt(mtyp, unsafe.Pointer(p)).Elem() n := int(state.decodeUint()) for i := 0; i < n; i++ { key := decodeIntoValue(state, keyOp, keyIndir, allocValue(mtyp.Key()), ovfl) @@ -648,7 +651,11 @@ func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) { // decodeSlice decodes a slice and stores the slice header through p. // Slices are encoded as an unsigned length followed by the elements. func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) { - n := int(uintptr(state.decodeUint())) + nr := state.decodeUint() + if nr > uint64(state.b.Len()) { + errorf("length of slice exceeds input size (%d elements)", nr) + } + n := int(nr) if indir > 0 { up := unsafe.Pointer(p) if *(*unsafe.Pointer)(up) == nil { @@ -662,7 +669,7 @@ func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintpt // Always write a header at p. hdrp := (*reflect.SliceHeader)(unsafe.Pointer(p)) if hdrp.Cap < n { - hdrp.Data = uintptr(unsafe.NewArray(atyp.Elem(), n)) + hdrp.Data = reflect.MakeSlice(atyp, n, n).Pointer() hdrp.Cap = n } hdrp.Len = n @@ -703,6 +710,9 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p ui *(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData() return } + if len(name) > 1024 { + errorf("name too long (%d bytes): %.20q...", len(name), name) + } // The concrete type must be registered. typ, ok := nameToConcreteType[name] if !ok { @@ -839,11 +849,10 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg } case reflect.Map: - name = "element of " + name keyId := dec.wireType[wireId].MapT.Key elemId := dec.wireType[wireId].MapT.Elem - keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), name, inProgress) - elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name, inProgress) + keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress) + elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress) ovfl := overflow(name) op = func(i *decInstr, state *decoderState, p unsafe.Pointer) { up := unsafe.Pointer(p) @@ -969,16 +978,16 @@ func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) (*decOp, int) { // Caller has gotten us to within one indirection of our value. if i.indir > 0 { if *(*unsafe.Pointer)(p) == nil { - *(*unsafe.Pointer)(p) = unsafe.New(ut.base) + *(*unsafe.Pointer)(p) = unsafe.Pointer(reflect.New(ut.base).Pointer()) } } // Now p is a pointer to the base type. Do we need to climb out to // get to the receiver type? var v reflect.Value if ut.decIndir == -1 { - v = reflect.ValueOf(unsafe.Unreflect(rcvrType, unsafe.Pointer(&p))) + v = reflect.NewAt(rcvrType, unsafe.Pointer(&p)).Elem() } else { - v = reflect.ValueOf(unsafe.Unreflect(rcvrType, p)) + v = reflect.NewAt(rcvrType, p).Elem() } state.dec.decodeGobDecoder(state, v) } @@ -1151,7 +1160,7 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn // getDecEnginePtr returns the engine for the specified type. func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) { - rt := ut.base + rt := ut.user decoderMap, ok := dec.decoderCache[rt] if !ok { decoderMap = make(map[typeId]**decEngine) diff --git a/libgo/go/encoding/gob/dump.go b/libgo/go/encoding/gob/dump.go index f7d822c11e4..17238c98df0 100644 --- a/libgo/go/encoding/gob/dump.go +++ b/libgo/go/encoding/gob/dump.go @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + package main // Need to compile package gob with debug.go to build this program. +// See comments in debug.go for how to do this. import ( "encoding/gob" diff --git a/libgo/go/encoding/gob/encode.go b/libgo/go/encoding/gob/encode.go index f05b17c3096..168e08b137a 100644 --- a/libgo/go/encoding/gob/encode.go +++ b/libgo/go/encoding/gob/encode.go @@ -590,7 +590,7 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp // Maps cannot be accessed by moving addresses around the way // that slices etc. can. We must recover a full reflection value for // the iteration. - v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p))) + v := reflect.NewAt(t, unsafe.Pointer(p)).Elem() mv := reflect.Indirect(v) // We send zero-length (but non-nil) maps because the // receiver might want to use the map. (Maps don't use append.) @@ -613,7 +613,7 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp op = func(i *encInstr, state *encoderState, p unsafe.Pointer) { // Interfaces transmit the name and contents of the concrete // value they contain. - v := reflect.ValueOf(unsafe.Unreflect(t, unsafe.Pointer(p))) + v := reflect.NewAt(t, unsafe.Pointer(p)).Elem() iv := reflect.Indirect(v) if !state.sendZero && (!iv.IsValid() || iv.IsNil()) { return @@ -645,9 +645,9 @@ func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) { var v reflect.Value if ut.encIndir == -1 { // Need to climb up one level to turn value into pointer. - v = reflect.ValueOf(unsafe.Unreflect(rt, unsafe.Pointer(&p))) + v = reflect.NewAt(rt, unsafe.Pointer(&p)).Elem() } else { - v = reflect.ValueOf(unsafe.Unreflect(rt, p)) + v = reflect.NewAt(rt, p).Elem() } if !state.sendZero && isZero(v) { return diff --git a/libgo/go/encoding/gob/encoder_test.go b/libgo/go/encoding/gob/encoder_test.go index 9a62cf9c2ad..050786dfd1f 100644 --- a/libgo/go/encoding/gob/encoder_test.go +++ b/libgo/go/encoding/gob/encoder_test.go @@ -685,3 +685,54 @@ func TestSliceIncompatibility(t *testing.T) { t.Error("expected compatibility error") } } + +// Mutually recursive slices of structs caused problems. +type Bug3 struct { + Num int + Children []*Bug3 +} + +func TestGobPtrSlices(t *testing.T) { + in := []*Bug3{ + &Bug3{1, nil}, + &Bug3{2, nil}, + } + b := new(bytes.Buffer) + err := NewEncoder(b).Encode(&in) + if err != nil { + t.Fatal("encode:", err) + } + + var out []*Bug3 + err = NewDecoder(b).Decode(&out) + if err != nil { + t.Fatal("decode:", err) + } + if !reflect.DeepEqual(in, out) { + t.Fatalf("got %v; wanted %v", out, in) + } +} + +// getDecEnginePtr cached engine for ut.base instead of ut.user so we passed +// a *map and then tried to reuse its engine to decode the inner map. +func TestPtrToMapOfMap(t *testing.T) { + Register(make(map[string]interface{})) + subdata := make(map[string]interface{}) + subdata["bar"] = "baz" + data := make(map[string]interface{}) + data["foo"] = subdata + + b := new(bytes.Buffer) + err := NewEncoder(b).Encode(data) + if err != nil { + t.Fatal("encode:", err) + } + var newData map[string]interface{} + err = NewDecoder(b).Decode(&newData) + if err != nil { + t.Fatal("decode:", err) + } + if !reflect.DeepEqual(data, newData) { + t.Fatalf("expected %v got %v", data, newData) + } +} diff --git a/libgo/go/encoding/gob/type.go b/libgo/go/encoding/gob/type.go index 39006efdb2d..0dd7a0a770e 100644 --- a/libgo/go/encoding/gob/type.go +++ b/libgo/go/encoding/gob/type.go @@ -152,6 +152,10 @@ var idToType = make(map[typeId]gobType) var builtinIdToType map[typeId]gobType // set in init() after builtins are established func setTypeId(typ gobType) { + // When building recursive types, someone may get there before us. + if typ.id() != 0 { + return + } nextId++ typ.setId(nextId) idToType[nextId] = typ @@ -346,6 +350,11 @@ func newSliceType(name string) *sliceType { func (s *sliceType) init(elem gobType) { // Set our type id before evaluating the element's, in case it's our own. setTypeId(s) + // See the comments about ids in newTypeObject. Only slices and + // structs have mutual recursion. + if elem.id() == 0 { + setTypeId(elem) + } s.Elem = elem.id() } @@ -503,6 +512,13 @@ func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, err if err != nil { return nil, err } + // Some mutually recursive types can cause us to be here while + // still defining the element. Fix the element type id here. + // We could do this more neatly by setting the id at the start of + // building every type, but that would break binary compatibility. + if gt.id() == 0 { + setTypeId(gt) + } st.Field = append(st.Field, &fieldType{f.Name, gt.id()}) } return st, nil diff --git a/libgo/go/encoding/hex/hex_test.go b/libgo/go/encoding/hex/hex_test.go index 2d24fd0a146..456f9eac724 100644 --- a/libgo/go/encoding/hex/hex_test.go +++ b/libgo/go/encoding/hex/hex_test.go @@ -87,7 +87,7 @@ func TestInvalidErr(t *testing.T) { dst := make([]byte, DecodedLen(len(test.in))) _, err := Decode(dst, []byte(test.in)) if err == nil { - t.Errorf("#%d: expected error; got none") + t.Errorf("#%d: expected error; got none", i) } else if err.Error() != test.err { t.Errorf("#%d: got: %v want: %v", i, err, test.err) } @@ -98,7 +98,7 @@ func TestInvalidStringErr(t *testing.T) { for i, test := range errTests { _, err := DecodeString(test.in) if err == nil { - t.Errorf("#%d: expected error; got none") + t.Errorf("#%d: expected error; got none", i) } else if err.Error() != test.err { t.Errorf("#%d: got: %v want: %v", i, err, test.err) } diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index 87076b53dc0..110c6fd6238 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -496,6 +496,12 @@ func (d *decodeState) object(v reflect.Value) { // Pretend this field doesn't exist. continue } + if sf.Anonymous { + // Pretend this field doesn't exist, + // so that we can do a good job with + // these in a later version. + continue + } // First, tag match tagName, _ := parseTag(tag) if tagName == key { @@ -963,3 +969,11 @@ func unquoteBytes(s []byte) (t []byte, ok bool) { } return b[0:w], true } + +// The following is issue 3069. + +// BUG(rsc): This package ignores anonymous (embedded) struct fields +// during encoding and decoding. A future version may assign meaning +// to them. To force an anonymous field to be ignored in all future +// versions of this package, use an explicit `json:"-"` tag in the struct +// definition. diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 775becfa7c9..d758758d978 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -239,16 +239,6 @@ func TestEscape(t *testing.T) { } } -func TestHTMLEscape(t *testing.T) { - b, err := MarshalForHTML("foobarbaz<>&quux") - if err != nil { - t.Fatalf("MarshalForHTML error: %v", err) - } - if !bytes.Equal(b, []byte(`"foobarbaz\u003c\u003e\u0026quux"`)) { - t.Fatalf("Unexpected encoding of \"<>&\": %s", b) - } -} - // WrongString is a struct that's misusing the ,string modifier. type WrongString struct { Message string `json:"result,string"` @@ -619,3 +609,32 @@ func TestRefUnmarshal(t *testing.T) { t.Errorf("got %+v, want %+v", got, want) } } + +// Test that anonymous fields are ignored. +// We may assign meaning to them later. +func TestAnonymous(t *testing.T) { + type S struct { + T + N int + } + + data, err := Marshal(new(S)) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `{"N":0}` + if string(data) != want { + t.Fatalf("Marshal = %#q, want %#q", string(data), want) + } + + var s S + if err := Unmarshal([]byte(`{"T": 1, "T": {"Y": 1}, "N": 2}`), &s); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if s.N != 2 { + t.Fatal("Unmarshal: did not set N") + } + if s.T.Y != 0 { + t.Fatal("Unmarshal: did set T.Y") + } +} diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 83e73c09cb4..5425a3a90a1 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -123,17 +123,6 @@ func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { return buf.Bytes(), nil } -// MarshalForHTML is like Marshal but applies HTMLEscape to the output. -func MarshalForHTML(v interface{}) ([]byte, error) { - b, err := Marshal(v) - if err != nil { - return nil, err - } - var buf bytes.Buffer - HTMLEscape(&buf, b) - return buf.Bytes(), nil -} - // HTMLEscape appends to dst the JSON-encoded src with <, >, and & // characters inside string literals changed to \u003c, \u003e, \u0026 // so that the JSON will be safe to embed inside HTML <script> tags. @@ -200,11 +189,6 @@ func (e *MarshalerError) Error() string { return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error() } -type interfaceOrPtrValue interface { - IsNil() bool - Elem() reflect.Value -} - var hex = "0123456789abcdef" // An encodeState encodes JSON into a bytes.Buffer. @@ -276,7 +260,7 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) { b, err := m.MarshalJSON() if err == nil { // copy JSON into buffer, checking validity. - err = Compact(&e.Buffer, b) + err = compact(&e.Buffer, b, true) } if err != nil { e.error(&MarshalerError{v.Type(), err}) @@ -538,6 +522,11 @@ func encodeFields(t reflect.Type) []encodeField { if f.PkgPath != "" { continue } + if f.Anonymous { + // We want to do a better job with these later, + // so for now pretend they don't exist. + continue + } var ef encodeField ef.i = i ef.tag = f.Name diff --git a/libgo/go/encoding/json/encode_test.go b/libgo/go/encoding/json/encode_test.go index 7a726a91c47..cb1c77eb529 100644 --- a/libgo/go/encoding/json/encode_test.go +++ b/libgo/go/encoding/json/encode_test.go @@ -167,3 +167,22 @@ func TestRefValMarshal(t *testing.T) { t.Errorf("got %q, want %q", got, want) } } + +// C implements Marshaler and returns unescaped JSON. +type C int + +func (C) MarshalJSON() ([]byte, error) { + return []byte(`"<&>"`), nil +} + +func TestMarshalerEscaping(t *testing.T) { + var c C + const want = `"\u003c\u0026\u003e"` + b, err := Marshal(c) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if got := string(b); got != want { + t.Errorf("got %q, want %q", got, want) + } +} diff --git a/libgo/go/encoding/json/indent.go b/libgo/go/encoding/json/indent.go index 5ba19b07ac6..e8dfa4ec436 100644 --- a/libgo/go/encoding/json/indent.go +++ b/libgo/go/encoding/json/indent.go @@ -9,11 +9,24 @@ import "bytes" // Compact appends to dst the JSON-encoded src with // insignificant space characters elided. func Compact(dst *bytes.Buffer, src []byte) error { + return compact(dst, src, false) +} + +func compact(dst *bytes.Buffer, src []byte, escape bool) error { origLen := dst.Len() var scan scanner scan.reset() start := 0 for i, c := range src { + if escape && (c == '<' || c == '>' || c == '&') { + if start < i { + dst.Write(src[start:i]) + } + dst.WriteString(`\u00`) + dst.WriteByte(hex[c>>4]) + dst.WriteByte(hex[c&0xF]) + start = i + 1 + } v := scan.step(&scan, int(c)) if v >= scanSkipSpace { if v == scanError { diff --git a/libgo/go/encoding/json/stream.go b/libgo/go/encoding/json/stream.go index f2476395023..7d1cc5f119c 100644 --- a/libgo/go/encoding/json/stream.go +++ b/libgo/go/encoding/json/stream.go @@ -19,6 +19,9 @@ type Decoder struct { } // NewDecoder returns a new decoder that reads from r. +// +// The decoder introduces its own buffering and may +// read data from r beyond the JSON values requested. func NewDecoder(r io.Reader) *Decoder { return &Decoder{r: r} } diff --git a/libgo/go/encoding/xml/atom_test.go b/libgo/go/encoding/xml/atom_test.go index 8d003aade07..a71284312af 100644 --- a/libgo/go/encoding/xml/atom_test.go +++ b/libgo/go/encoding/xml/atom_test.go @@ -4,6 +4,8 @@ package xml +import "time" + var atomValue = &Feed{ XMLName: Name{"http://www.w3.org/2005/Atom", "feed"}, Title: "Example Feed", @@ -24,11 +26,10 @@ var atomValue = &Feed{ } var atomXml = `` + - `<feed xmlns="http://www.w3.org/2005/Atom">` + + `<feed xmlns="http://www.w3.org/2005/Atom" updated="2003-12-13T18:30:02Z">` + `<title>Example Feed</title>` + `<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>` + `<link href="http://example.org/"></link>` + - `<updated>2003-12-13T18:30:02Z</updated>` + `<author><name>John Doe</name><uri></uri><email></email></author>` + `<entry>` + `<title>Atom-Powered Robots Run Amok</title>` + @@ -40,8 +41,12 @@ var atomXml = `` + `</entry>` + `</feed>` -func ParseTime(str string) Time { - return Time(str) +func ParseTime(str string) time.Time { + t, err := time.Parse(time.RFC3339, str) + if err != nil { + panic(err) + } + return t } func NewText(text string) Text { diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index 7a05a1bb10e..6c3170bdda3 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -12,6 +12,7 @@ import ( "reflect" "strconv" "strings" + "time" ) const ( @@ -52,32 +53,18 @@ const ( // - a field with tag ",comment" is written as an XML comment, not // subject to the usual marshalling procedure. It must not contain // the "--" string within it. +// - a field with a tag including the "omitempty" option is omitted +// if the field value is empty. The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or +// string of length zero. +// - a non-pointer anonymous struct field is handled as if the +// fields of its value were part of the outer struct. // // If a field uses a tag "a>b>c", then the element c will be nested inside // parent elements a and b. Fields that appear next to each other that name -// the same parent will be enclosed in one XML element. For example: +// the same parent will be enclosed in one XML element. // -// type Result struct { -// XMLName xml.Name `xml:"result"` -// Id int `xml:"id,attr"` -// FirstName string `xml:"person>name>first"` -// LastName string `xml:"person>name>last"` -// Age int `xml:"person>age"` -// } -// -// xml.Marshal(&Result{Id: 13, FirstName: "John", LastName: "Doe", Age: 42}) -// -// would be marshalled as: -// -// <result> -// <person id="13"> -// <name> -// <first>John</first> -// <last>Doe</last> -// </name> -// <age>42</age> -// </person> -// </result> +// See MarshalIndent for an example. // // Marshal will return an error if asked to marshal a channel, function, or map. func Marshal(v interface{}) ([]byte, error) { @@ -88,6 +75,22 @@ func Marshal(v interface{}) ([]byte, error) { return b.Bytes(), nil } +// MarshalIndent works like Marshal, but each XML element begins on a new +// indented line that starts with prefix and is followed by one or more +// copies of indent according to the nesting depth. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + var b bytes.Buffer + enc := NewEncoder(&b) + enc.prefix = prefix + enc.indent = indent + err := enc.marshalValue(reflect.ValueOf(v), nil) + enc.Flush() + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + // An Encoder writes XML data to an output stream. type Encoder struct { printer @@ -95,7 +98,7 @@ type Encoder struct { // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { - return &Encoder{printer{bufio.NewWriter(w)}} + return &Encoder{printer{Writer: bufio.NewWriter(w)}} } // Encode writes the XML encoding of v to the stream. @@ -110,12 +113,21 @@ func (enc *Encoder) Encode(v interface{}) error { type printer struct { *bufio.Writer + indent string + prefix string + depth int + indentedIn bool } +// marshalValue writes one or more XML elements representing val. +// If val was obtained from a struct field, finfo must have its details. func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { if !val.IsValid() { return nil } + if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) { + return nil + } kind := val.Kind() typ := val.Type() @@ -166,6 +178,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { } } + p.writeIndent(1) p.WriteByte('<') p.WriteString(name) @@ -183,12 +196,8 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { continue } fv := val.FieldByIndex(finfo.idx) - switch fv.Kind() { - case reflect.String, reflect.Array, reflect.Slice: - // TODO: Should we really do this once ,omitempty is in? - if fv.Len() == 0 { - continue - } + if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + continue } p.WriteByte(' ') p.WriteString(finfo.name) @@ -209,6 +218,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { return err } + p.writeIndent(-1) p.WriteByte('<') p.WriteByte('/') p.WriteString(name) @@ -217,7 +227,14 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { return nil } +var timeType = reflect.TypeOf(time.Time{}) + func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) error { + // Normally we don't see structs, but this can happen for an attribute. + if val.Type() == timeType { + p.WriteString(val.Interface().(time.Time).Format(time.RFC3339Nano)) + return nil + } switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.WriteString(strconv.FormatInt(val.Int(), 10)) @@ -249,6 +266,10 @@ func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) error { var ddBytes = []byte("--") func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { + if val.Type() == timeType { + p.WriteString(val.Interface().(time.Time).Format(time.RFC3339Nano)) + return nil + } s := parentStack{printer: p} for i := range tinfo.fields { finfo := &tinfo.fields[i] @@ -276,6 +297,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { if vf.Len() == 0 { continue } + p.writeIndent(0) p.WriteString("<!--") dashDash := false dashLast := false @@ -334,6 +356,33 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { return nil } +func (p *printer) writeIndent(depthDelta int) { + if len(p.prefix) == 0 && len(p.indent) == 0 { + return + } + if depthDelta < 0 { + p.depth-- + if p.indentedIn { + p.indentedIn = false + return + } + p.indentedIn = false + } + p.WriteByte('\n') + if len(p.prefix) > 0 { + p.WriteString(p.prefix) + } + if len(p.indent) > 0 { + for i := 0; i < p.depth; i++ { + p.WriteString(p.indent) + } + } + if depthDelta > 0 { + p.depth++ + p.indentedIn = true + } +} + type parentStack struct { *printer stack []string @@ -349,20 +398,20 @@ func (s *parentStack) trim(parents []string) { break } } - for i := len(s.stack) - 1; i >= split; i-- { + s.writeIndent(-1) s.WriteString("</") s.WriteString(s.stack[i]) s.WriteByte('>') } - s.stack = parents[:split] } // push adds parent elements to the stack and writes open tags. func (s *parentStack) push(parents []string) { for i := 0; i < len(parents); i++ { - s.WriteString("<") + s.writeIndent(1) + s.WriteByte('<') s.WriteString(parents[i]) s.WriteByte('>') } @@ -378,3 +427,21 @@ type UnsupportedTypeError struct { func (e *UnsupportedTypeError) Error() string { return "xml: unsupported type: " + e.Type.String() } + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index 0f6c0f0795d..b6978a1e65b 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "testing" + "time" ) type DriveType int @@ -38,14 +39,14 @@ type NamedType string type Port struct { XMLName struct{} `xml:"port"` - Type string `xml:"type,attr"` + Type string `xml:"type,attr,omitempty"` Comment string `xml:",comment"` Number string `xml:",chardata"` } type Domain struct { XMLName struct{} `xml:"domain"` - Country string `xml:",attr"` + Country string `xml:",attr,omitempty"` Name []byte `xml:",chardata"` Comment []byte `xml:",comment"` } @@ -135,12 +136,12 @@ type NamePrecedence struct { type XMLNameWithTag struct { XMLName Name `xml:"InXMLNameTag"` - Value string ",chardata" + Value string `xml:",chardata"` } type XMLNameWithoutTag struct { XMLName Name - Value string ",chardata" + Value string `xml:",chardata"` } type NameInField struct { @@ -149,11 +150,33 @@ type NameInField struct { type AttrTest struct { Int int `xml:",attr"` - Lower int `xml:"int,attr"` + Named int `xml:"int,attr"` Float float64 `xml:",attr"` Uint8 uint8 `xml:",attr"` Bool bool `xml:",attr"` Str string `xml:",attr"` + Bytes []byte `xml:",attr"` +} + +type OmitAttrTest struct { + Int int `xml:",attr,omitempty"` + Named int `xml:"int,attr,omitempty"` + Float float64 `xml:",attr,omitempty"` + Uint8 uint8 `xml:",attr,omitempty"` + Bool bool `xml:",attr,omitempty"` + Str string `xml:",attr,omitempty"` + Bytes []byte `xml:",attr,omitempty"` +} + +type OmitFieldTest struct { + Int int `xml:",omitempty"` + Named int `xml:"int,omitempty"` + Float float64 `xml:",omitempty"` + Uint8 uint8 `xml:",omitempty"` + Bool bool `xml:",omitempty"` + Str string `xml:",omitempty"` + Bytes []byte `xml:",omitempty"` + Ptr *PresenceTest `xml:",omitempty"` } type AnyTest struct { @@ -234,6 +257,12 @@ var marshalTests = []struct { {Value: &Plain{[]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`}, {Value: &Plain{[3]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`}, + // Test time. + { + Value: &Plain{time.Unix(1e9, 123456789).UTC()}, + ExpectXML: `<Plain><V>2001-09-09T01:46:40.123456789Z</V></Plain>`, + }, + // A pointer to struct{} may be used to test for an element's presence. { Value: &PresenceTest{new(struct{})}, @@ -503,9 +532,9 @@ var marshalTests = []struct { InFieldName: "D", }, ExpectXML: `<Parent>` + - `<InTag><Value>A</Value></InTag>` + - `<InXMLName><Value>B</Value></InXMLName>` + - `<InXMLNameTag><Value>C</Value></InXMLNameTag>` + + `<InTag>A</InTag>` + + `<InXMLName>B</InXMLName>` + + `<InXMLNameTag>C</InXMLNameTag>` + `<InFieldName>D</InFieldName>` + `</Parent>`, MarshalOnly: true, @@ -519,9 +548,9 @@ var marshalTests = []struct { InFieldName: "D", }, ExpectXML: `<Parent>` + - `<InTag><Value>A</Value></InTag>` + - `<FromNameVal><Value>B</Value></FromNameVal>` + - `<InXMLNameTag><Value>C</Value></InXMLNameTag>` + + `<InTag>A</InTag>` + + `<FromNameVal>B</FromNameVal>` + + `<InXMLNameTag>C</InXMLNameTag>` + `<InFieldName>D</InFieldName>` + `</Parent>`, UnmarshalOnly: true, @@ -549,13 +578,65 @@ var marshalTests = []struct { { Value: &AttrTest{ Int: 8, - Lower: 9, + Named: 9, + Float: 23.5, + Uint8: 255, + Bool: true, + Str: "str", + Bytes: []byte("byt"), + }, + ExpectXML: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255"` + + ` Bool="true" Str="str" Bytes="byt"></AttrTest>`, + }, + { + Value: &AttrTest{Bytes: []byte{}}, + ExpectXML: `<AttrTest Int="0" int="0" Float="0" Uint8="0"` + + ` Bool="false" Str="" Bytes=""></AttrTest>`, + }, + { + Value: &OmitAttrTest{ + Int: 8, + Named: 9, + Float: 23.5, + Uint8: 255, + Bool: true, + Str: "str", + Bytes: []byte("byt"), + }, + ExpectXML: `<OmitAttrTest Int="8" int="9" Float="23.5" Uint8="255"` + + ` Bool="true" Str="str" Bytes="byt"></OmitAttrTest>`, + }, + { + Value: &OmitAttrTest{}, + ExpectXML: `<OmitAttrTest></OmitAttrTest>`, + }, + + // omitempty on fields + { + Value: &OmitFieldTest{ + Int: 8, + Named: 9, Float: 23.5, Uint8: 255, Bool: true, - Str: "s", + Str: "str", + Bytes: []byte("byt"), + Ptr: &PresenceTest{}, }, - ExpectXML: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="s"></AttrTest>`, + ExpectXML: `<OmitFieldTest>` + + `<Int>8</Int>` + + `<int>9</int>` + + `<Float>23.5</Float>` + + `<Uint8>255</Uint8>` + + `<Bool>true</Bool>` + + `<Str>str</Str>` + + `<Bytes>byt</Bytes>` + + `<Ptr></Ptr>` + + `</OmitFieldTest>`, + }, + { + Value: &OmitFieldTest{}, + ExpectXML: `<OmitFieldTest></OmitFieldTest>`, }, // Test ",any" diff --git a/libgo/go/encoding/xml/read.go b/libgo/go/encoding/xml/read.go index bde875a0123..c2168242091 100644 --- a/libgo/go/encoding/xml/read.go +++ b/libgo/go/encoding/xml/read.go @@ -10,6 +10,7 @@ import ( "reflect" "strconv" "strings" + "time" ) // BUG(rsc): Mapping between XML elements and data structures is inherently flawed: @@ -24,58 +25,6 @@ import ( // slice, or string. Well-formed data that does not fit into v is // discarded. // -// For example, given these definitions: -// -// type Email struct { -// Where string `xml:",attr"` -// Addr string -// } -// -// type Result struct { -// XMLName xml.Name `xml:"result"` -// Name string -// Phone string -// Email []Email -// Groups []string `xml:"group>value"` -// } -// -// result := Result{Name: "name", Phone: "phone", Email: nil} -// -// unmarshalling the XML input -// -// <result> -// <email where="home"> -// <addr>gre@example.com</addr> -// </email> -// <email where='work'> -// <addr>gre@work.com</addr> -// </email> -// <name>Grace R. Emlin</name> -// <group> -// <value>Friends</value> -// <value>Squash</value> -// </group> -// <address>123 Main Street</address> -// </result> -// -// via Unmarshal(data, &result) is equivalent to assigning -// -// r = Result{ -// xml.Name{Local: "result"}, -// "Grace R. Emlin", // name -// "phone", // no phone given -// []Email{ -// Email{"home", "gre@example.com"}, -// Email{"work", "gre@work.com"}, -// }, -// []string{"Friends", "Squash"}, -// } -// -// Note that the field r.Phone has not been modified and -// that the XML <address> element was discarded. Also, the field -// Groups was assigned considering the element path provided in the -// field tag. -// // Because Unmarshal uses the reflect package, it can only assign // to exported (upper case) fields. Unmarshal uses a case-sensitive // comparison to match XML element names to tag values and struct @@ -132,6 +81,9 @@ import ( // of the above rules and the struct has a field with tag ",any", // unmarshal maps the sub-element to that struct field. // +// * A non-pointer anonymous struct field is handled as if the +// fields of its value were part of the outer struct. +// // * A struct field with tag "-" is never unmarshalled into. // // Unmarshal maps an XML element to a string or []byte by saving the @@ -270,6 +222,10 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error { v.Set(reflect.ValueOf(start.Name)) break } + if typ == timeType { + saveData = v + break + } sv = v tinfo, err = getTypeInfo(typ) @@ -473,6 +429,14 @@ func copyValue(dst reflect.Value, src []byte) (err error) { src = []byte{} } t.SetBytes(src) + case reflect.Struct: + if t.Type() == timeType { + tv, err := time.Parse(time.RFC3339, string(src)) + if err != nil { + return err + } + t.Set(reflect.ValueOf(tv)) + } } return nil } diff --git a/libgo/go/encoding/xml/read_test.go b/libgo/go/encoding/xml/read_test.go index 833eafc9a58..8df09b3ccee 100644 --- a/libgo/go/encoding/xml/read_test.go +++ b/libgo/go/encoding/xml/read_test.go @@ -7,6 +7,7 @@ package xml import ( "reflect" "testing" + "time" ) // Stripped down Atom feed data structures. @@ -24,7 +25,7 @@ func TestUnmarshalFeed(t *testing.T) { // hget http://codereview.appspot.com/rss/mine/rsc const atomFeedString = ` <?xml version="1.0" encoding="utf-8"?> -<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><title>Code Review - My issues</title><link href="http://codereview.appspot.com/" rel="alternate"></link><link href="http://codereview.appspot.com/rss/mine/rsc" rel="self"></link><id>http://codereview.appspot.com/</id><updated>2009-10-04T01:35:58+00:00</updated><author><name>rietveld<></name></author><entry><title>rietveld: an attempt at pubsubhubbub +<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us" updated="2009-10-04T01:35:58+00:00"><title>Code Review - My issues</title><link href="http://codereview.appspot.com/" rel="alternate"></link><link href="http://codereview.appspot.com/rss/mine/rsc" rel="self"></link><id>http://codereview.appspot.com/</id><author><name>rietveld<></name></author><entry><title>rietveld: an attempt at pubsubhubbub </title><link href="http://codereview.appspot.com/126085" rel="alternate"></link><updated>2009-10-04T01:35:58+00:00</updated><author><name>email-address-removed</name></author><id>urn:md5:134d9179c41f806be79b3a5f7877d19a</id><summary type="html"> An attempt at adding pubsubhubbub support to Rietveld. http://code.google.com/p/pubsubhubbub @@ -78,26 +79,26 @@ not being used from outside intra_region_diff.py. </summary></entry></feed> ` type Feed struct { - XMLName Name `xml:"http://www.w3.org/2005/Atom feed"` - Title string `xml:"title"` - Id string `xml:"id"` - Link []Link `xml:"link"` - Updated Time `xml:"updated"` - Author Person `xml:"author"` - Entry []Entry `xml:"entry"` + XMLName Name `xml:"http://www.w3.org/2005/Atom feed"` + Title string `xml:"title"` + Id string `xml:"id"` + Link []Link `xml:"link"` + Updated time.Time `xml:"updated,attr"` + Author Person `xml:"author"` + Entry []Entry `xml:"entry"` } type Entry struct { - Title string `xml:"title"` - Id string `xml:"id"` - Link []Link `xml:"link"` - Updated Time `xml:"updated"` - Author Person `xml:"author"` - Summary Text `xml:"summary"` + Title string `xml:"title"` + Id string `xml:"id"` + Link []Link `xml:"link"` + Updated time.Time `xml:"updated"` + Author Person `xml:"author"` + Summary Text `xml:"summary"` } type Link struct { - Rel string `xml:"rel,attr"` + Rel string `xml:"rel,attr,omitempty"` Href string `xml:"href,attr"` } @@ -109,12 +110,10 @@ type Person struct { } type Text struct { - Type string `xml:"type,attr"` + Type string `xml:"type,attr,omitempty"` Body string `xml:",chardata"` } -type Time string - var atomFeed = Feed{ XMLName: Name{"http://www.w3.org/2005/Atom", "feed"}, Title: "Code Review - My issues", @@ -123,7 +122,7 @@ var atomFeed = Feed{ {Rel: "self", Href: "http://codereview.appspot.com/rss/mine/rsc"}, }, Id: "http://codereview.appspot.com/", - Updated: "2009-10-04T01:35:58+00:00", + Updated: ParseTime("2009-10-04T01:35:58+00:00"), Author: Person{ Name: "rietveld<>", InnerXML: "<name>rietveld<></name>", @@ -134,7 +133,7 @@ var atomFeed = Feed{ Link: []Link{ {Rel: "alternate", Href: "http://codereview.appspot.com/126085"}, }, - Updated: "2009-10-04T01:35:58+00:00", + Updated: ParseTime("2009-10-04T01:35:58+00:00"), Author: Person{ Name: "email-address-removed", InnerXML: "<name>email-address-removed</name>", @@ -181,7 +180,7 @@ the top of feeds.py marked NOTE(rsc). Link: []Link{ {Rel: "alternate", Href: "http://codereview.appspot.com/124106"}, }, - Updated: "2009-10-03T23:02:17+00:00", + Updated: ParseTime("2009-10-03T23:02:17+00:00"), Author: Person{ Name: "email-address-removed", InnerXML: "<name>email-address-removed</name>", diff --git a/libgo/go/encoding/xml/typeinfo.go b/libgo/go/encoding/xml/typeinfo.go index 5475f290d18..8e2e4508b10 100644 --- a/libgo/go/encoding/xml/typeinfo.go +++ b/libgo/go/encoding/xml/typeinfo.go @@ -36,8 +36,7 @@ const ( fComment fAny - // TODO: - //fOmitEmpty + fOmitEmpty fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny ) @@ -133,20 +132,28 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro finfo.flags |= fComment case "any": finfo.flags |= fAny + case "omitempty": + finfo.flags |= fOmitEmpty } } // Validate the flags used. + valid := true switch mode := finfo.flags & fMode; mode { case 0: finfo.flags |= fElement case fAttr, fCharData, fInnerXml, fComment, fAny: - if f.Name != "XMLName" && (tag == "" || mode == fAttr) { - break + if f.Name == "XMLName" || tag != "" && mode != fAttr { + valid = false } - fallthrough default: // This will also catch multiple modes in a single field. + valid = false + } + if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 { + valid = false + } + if !valid { return nil, fmt.Errorf("xml: invalid tag in field %s of type %s: %q", f.Name, typ, f.Tag.Get("xml")) } diff --git a/libgo/go/errors/errors_test.go b/libgo/go/errors/errors_test.go index c537eeb6251..63c05d7185b 100644 --- a/libgo/go/errors/errors_test.go +++ b/libgo/go/errors/errors_test.go @@ -5,29 +5,49 @@ package errors_test import ( - . "errors" + "errors" + "fmt" "testing" ) func TestNewEqual(t *testing.T) { // Different allocations should not be equal. - if New("abc") == New("abc") { + if errors.New("abc") == errors.New("abc") { t.Errorf(`New("abc") == New("abc")`) } - if New("abc") == New("xyz") { + if errors.New("abc") == errors.New("xyz") { t.Errorf(`New("abc") == New("xyz")`) } // Same allocation should be equal to itself (not crash). - err := New("jkl") + err := errors.New("jkl") if err != err { t.Errorf(`err != err`) } } func TestErrorMethod(t *testing.T) { - err := New("abc") + err := errors.New("abc") if err.Error() != "abc" { t.Errorf(`New("abc").Error() = %q, want %q`, err.Error(), "abc") } } + +func ExampleNew() { + err := errors.New("emit macho dwarf: elf header corrupted") + if err != nil { + fmt.Print(err) + } + // Output: emit macho dwarf: elf header corrupted +} + +// The fmt package's Errorf function lets us use the package's formatting +// features to create descriptive error messages. +func ExampleNew_errorf() { + const name, id = "bimmler", 17 + err := fmt.Errorf("user %q (id %d) not found", name, id) + if err != nil { + fmt.Print(err) + } + // Output: user "bimmler" (id 17) not found +} diff --git a/libgo/go/exp/gotype/doc.go b/libgo/go/exp/gotype/doc.go index 1aa0faa751a..1168086771f 100644 --- a/libgo/go/exp/gotype/doc.go +++ b/libgo/go/exp/gotype/doc.go @@ -34,6 +34,8 @@ The flags are: Verbose mode. Debugging flags: + -comments + Parse comments (ignored if -ast not set). -ast Print AST (disables concurrent parsing). -trace diff --git a/libgo/go/exp/gotype/gotype.go b/libgo/go/exp/gotype/gotype.go index a2a9361866d..30eaf22fca6 100644 --- a/libgo/go/exp/gotype/gotype.go +++ b/libgo/go/exp/gotype/gotype.go @@ -27,8 +27,9 @@ var ( allErrors = flag.Bool("e", false, "print all (including spurious) errors") // debugging support - printTrace = flag.Bool("trace", false, "print parse trace") - printAST = flag.Bool("ast", false, "print AST") + parseComments = flag.Bool("comments", false, "parse comments (ignored if -ast not set)") + printTrace = flag.Bool("trace", false, "print parse trace") + printAST = flag.Bool("ast", false, "print AST") ) var exitCode = 0 @@ -73,6 +74,9 @@ func parse(fset *token.FileSet, filename string, src []byte) *ast.File { if *allErrors { mode |= parser.SpuriousErrors } + if *parseComments && *printAST { + mode |= parser.ParseComments + } if *printTrace { mode |= parser.Trace } diff --git a/libgo/go/exp/html/node.go b/libgo/go/exp/html/node.go index 83f17308b18..c105a4e709a 100644 --- a/libgo/go/exp/html/node.go +++ b/libgo/go/exp/html/node.go @@ -110,7 +110,7 @@ func (s *nodeStack) top() *Node { return nil } -// index returns the index of the top-most occurence of n in the stack, or -1 +// index returns the index of the top-most occurrence of n in the stack, or -1 // if n is not present. func (s *nodeStack) index(n *Node) int { for i := len(*s) - 1; i >= 0; i-- { diff --git a/libgo/go/exp/inotify/inotify_linux_test.go b/libgo/go/exp/inotify/inotify_linux_test.go index c2160fc6537..d41d66bfacd 100644 --- a/libgo/go/exp/inotify/inotify_linux_test.go +++ b/libgo/go/exp/inotify/inotify_linux_test.go @@ -7,6 +7,7 @@ package inotify import ( + "io/ioutil" "os" "testing" "time" @@ -16,16 +17,19 @@ func TestInotifyEvents(t *testing.T) { // Create an inotify watcher instance and initialize it watcher, err := NewWatcher() if err != nil { - t.Fatalf("NewWatcher() failed: %s", err) + t.Fatalf("NewWatcher failed: %s", err) } - t.Logf("NEEDS TO BE CONVERTED TO NEW GO TOOL") // TODO - return + dir, err := ioutil.TempDir("", "inotify") + if err != nil { + t.Fatalf("TempDir failed: %s", err) + } + defer os.RemoveAll(dir) // Add a watch for "_test" - err = watcher.Watch("_test") + err = watcher.Watch(dir) if err != nil { - t.Fatalf("Watcher.Watch() failed: %s", err) + t.Fatalf("Watch failed: %s", err) } // Receive errors on the error channel on a separate goroutine @@ -35,7 +39,7 @@ func TestInotifyEvents(t *testing.T) { } }() - const testFile string = "_test/TestInotifyEvents.testfile" + testFile := dir + "/TestInotifyEvents.testfile" // Receive events on the event channel on a separate goroutine eventstream := watcher.Event @@ -58,7 +62,7 @@ func TestInotifyEvents(t *testing.T) { // This should add at least one event to the inotify event queue _, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { - t.Fatalf("creating test file failed: %s", err) + t.Fatalf("creating test file: %s", err) } // We expect this event to be received almost immediately, but let's wait 1 s to be sure @@ -95,7 +99,7 @@ func TestInotifyClose(t *testing.T) { t.Fatal("double Close() test failed: second Close() call didn't return") } - err := watcher.Watch("_test") + err := watcher.Watch(os.TempDir()) if err == nil { t.Fatal("expected error on Watch() after Close(), got nil") } diff --git a/libgo/go/exp/norm/composition.go b/libgo/go/exp/norm/composition.go index 5b48292cc3b..2cbe1ac730e 100644 --- a/libgo/go/exp/norm/composition.go +++ b/libgo/go/exp/norm/composition.go @@ -66,6 +66,18 @@ func (rb *reorderBuffer) flush(out []byte) []byte { return out } +// flushCopy copies the normalized segment to buf and resets rb. +// It returns the number of bytes written to buf. +func (rb *reorderBuffer) flushCopy(buf []byte) int { + p := 0 + for i := 0; i < rb.nrune; i++ { + runep := rb.rune[i] + p += copy(buf[p:], rb.byte[runep.pos:runep.pos+runep.size]) + } + rb.reset() + return p +} + // insertOrdered inserts a rune in the buffer, ordered by Canonical Combining Class. // It returns false if the buffer is not large enough to hold the rune. // It is used internally by insert and insertString only. @@ -96,32 +108,41 @@ func (rb *reorderBuffer) insertOrdered(info runeInfo) bool { // insert inserts the given rune in the buffer ordered by CCC. // It returns true if the buffer was large enough to hold the decomposed rune. func (rb *reorderBuffer) insert(src input, i int, info runeInfo) bool { - if info.size == 3 { - if rune := src.hangul(i); rune != 0 { - return rb.decomposeHangul(rune) - } + if rune := src.hangul(i); rune != 0 { + return rb.decomposeHangul(rune) } if info.hasDecomposition() { - dcomp := rb.f.decompose(src, i) - rb.tmpBytes = inputBytes(dcomp) - for i := 0; i < len(dcomp); { - info = rb.f.info(&rb.tmpBytes, i) - pos := rb.nbyte - if !rb.insertOrdered(info) { - return false - } - end := i + int(info.size) - copy(rb.byte[pos:], dcomp[i:end]) - i = end - } - } else { - // insertOrder changes nbyte + return rb.insertDecomposed(info.decomposition()) + } + return rb.insertSingle(src, i, info) +} + +// insertDecomposed inserts an entry in to the reorderBuffer for each rune +// in dcomp. dcomp must be a sequence of decomposed UTF-8-encoded runes. +func (rb *reorderBuffer) insertDecomposed(dcomp []byte) bool { + saveNrune, saveNbyte := rb.nrune, rb.nbyte + rb.tmpBytes = inputBytes(dcomp) + for i := 0; i < len(dcomp); { + info := rb.f.info(&rb.tmpBytes, i) pos := rb.nbyte if !rb.insertOrdered(info) { + rb.nrune, rb.nbyte = saveNrune, saveNbyte return false } - src.copySlice(rb.byte[pos:], i, i+int(info.size)) + i += copy(rb.byte[pos:], dcomp[i:i+int(info.size)]) + } + return true +} + +// insertSingle inserts an entry in the reorderBuffer for the rune at +// position i. info is the runeInfo for the rune at position i. +func (rb *reorderBuffer) insertSingle(src input, i int, info runeInfo) bool { + // insertOrder changes nbyte + pos := rb.nbyte + if !rb.insertOrdered(info) { + return false } + src.copySlice(rb.byte[pos:], i, i+int(info.size)) return true } @@ -182,8 +203,12 @@ const ( jamoLVTCount = 19 * 21 * 28 ) -// Caller must verify that len(b) >= 3. +const hangulUTF8Size = 3 + func isHangul(b []byte) bool { + if len(b) < hangulUTF8Size { + return false + } b0 := b[0] if b0 < hangulBase0 { return false @@ -202,8 +227,10 @@ func isHangul(b []byte) bool { return b1 == hangulEnd1 && b[2] < hangulEnd2 } -// Caller must verify that len(b) >= 3. func isHangulString(b string) bool { + if len(b) < hangulUTF8Size { + return false + } b0 := b[0] if b0 < hangulBase0 { return false @@ -234,6 +261,22 @@ func isHangulWithoutJamoT(b []byte) bool { return c < jamoLVTCount && c%jamoTCount == 0 } +// decomposeHangul writes the decomposed Hangul to buf and returns the number +// of bytes written. len(buf) should be at least 9. +func decomposeHangul(buf []byte, r rune) int { + const JamoUTF8Len = 3 + r -= hangulBase + x := r % jamoTCount + r /= jamoTCount + utf8.EncodeRune(buf, jamoLBase+r/jamoVCount) + utf8.EncodeRune(buf[JamoUTF8Len:], jamoVBase+r%jamoVCount) + if x != 0 { + utf8.EncodeRune(buf[2*JamoUTF8Len:], jamoTBase+x) + return 3 * JamoUTF8Len + } + return 2 * JamoUTF8Len +} + // decomposeHangul algorithmically decomposes a Hangul rune into // its Jamo components. // See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. diff --git a/libgo/go/exp/norm/composition_test.go b/libgo/go/exp/norm/composition_test.go index e32380d7afa..9de9eacfd65 100644 --- a/libgo/go/exp/norm/composition_test.go +++ b/libgo/go/exp/norm/composition_test.go @@ -47,14 +47,14 @@ func runTests(t *testing.T, name string, fm Form, f insertFunc, tests []TestCase } } -func TestFlush(t *testing.T) { +type flushFunc func(rb *reorderBuffer) []byte + +func testFlush(t *testing.T, name string, fn flushFunc) { rb := reorderBuffer{} rb.init(NFC, nil) - out := make([]byte, 0) - - out = rb.flush(out) + out := fn(&rb) if len(out) != 0 { - t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", len(out)) + t.Errorf("%s: wrote bytes on flush of empty buffer. (len(out) = %d)", name, len(out)) } for _, r := range []rune("world!") { @@ -65,16 +65,32 @@ func TestFlush(t *testing.T) { out = rb.flush(out) want := "Hello world!" if string(out) != want { - t.Errorf(`output after flush was "%s"; want "%s"`, string(out), want) + t.Errorf(`%s: output after flush was "%s"; want "%s"`, name, string(out), want) } if rb.nrune != 0 { - t.Errorf("flush: non-null size of info buffer (rb.nrune == %d)", rb.nrune) + t.Errorf("%s: non-null size of info buffer (rb.nrune == %d)", name, rb.nrune) } if rb.nbyte != 0 { - t.Errorf("flush: non-null size of byte buffer (rb.nbyte == %d)", rb.nbyte) + t.Errorf("%s: non-null size of byte buffer (rb.nbyte == %d)", name, rb.nbyte) } } +func flushF(rb *reorderBuffer) []byte { + out := make([]byte, 0) + return rb.flush(out) +} + +func flushCopyF(rb *reorderBuffer) []byte { + out := make([]byte, MaxSegmentSize) + n := rb.flushCopy(out) + return out[:n] +} + +func TestFlush(t *testing.T) { + testFlush(t, "flush", flushF) + testFlush(t, "flushCopy", flushCopyF) +} + var insertTests = []TestCase{ {[]rune{'a'}, []rune{'a'}}, {[]rune{0x300}, []rune{0x300}}, diff --git a/libgo/go/exp/norm/forminfo.go b/libgo/go/exp/norm/forminfo.go index bf4443c9916..c443b78d825 100644 --- a/libgo/go/exp/norm/forminfo.go +++ b/libgo/go/exp/norm/forminfo.go @@ -6,25 +6,50 @@ package norm // This file contains Form-specific logic and wrappers for data in tables.go. +// Rune info is stored in a separate trie per composing form. A composing form +// and its corresponding decomposing form share the same trie. Each trie maps +// a rune to a uint16. The values take two forms. For v >= 0x8000: +// bits +// 0..8: ccc +// 9..12: qcInfo (see below). isYesD is always true (no decompostion). +// 16: 1 +// For v < 0x8000, the respective rune has a decomposition and v is an index +// into a byte array of UTF-8 decomposition sequences and additional info and +// has the form: +// <header> <decomp_byte>* [<tccc> [<lccc>]] +// The header contains the number of bytes in the decomposition (excluding this +// length byte). The two most significant bits of this length byte correspond +// to bit 2 and 3 of qcIfo (see below). The byte sequence itself starts at v+1. +// The byte sequence is followed by a trailing and leading CCC if the values +// for these are not zero. The value of v determines which ccc are appended +// to the sequences. For v < firstCCC, there are none, for v >= firstCCC, +// the sequence is followed by a trailing ccc, and for v >= firstLeadingCC +// there is an additional leading ccc. + +const ( + qcInfoMask = 0xF // to clear all but the relevant bits in a qcInfo + headerLenMask = 0x3F // extract the length value from the header byte + headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte +) + +// runeInfo is a representation for the data stored in charinfoTrie. type runeInfo struct { pos uint8 // start position in reorderBuffer; used in composition.go size uint8 // length of UTF-8 encoding of this rune - ccc uint8 // canonical combining class + ccc uint8 // leading canonical combining class (ccc if not decomposition) + tccc uint8 // trailing canonical combining class (ccc if not decomposition) flags qcInfo // quick check flags + index uint16 } // functions dispatchable per form type lookupFunc func(b input, i int) runeInfo -type decompFunc func(b input, i int) []byte // formInfo holds Form-specific functions and tables. type formInfo struct { - form Form - + form Form composing, compatibility bool // form type - - decompose decompFunc - info lookupFunc + info lookupFunc } var formTable []*formInfo @@ -38,10 +63,8 @@ func init() { f.form = Form(i) if Form(i) == NFKD || Form(i) == NFKC { f.compatibility = true - f.decompose = decomposeNFKC f.info = lookupInfoNFKC } else { - f.decompose = decomposeNFC f.info = lookupInfoNFC } if Form(i) == NFC || Form(i) == NFKC { @@ -76,8 +99,6 @@ func (i runeInfo) boundaryAfter() bool { // // When all 4 bits are zero, the character is inert, meaning it is never // influenced by normalization. -// -// We pack the bits for both NFC/D and NFKC/D in one byte. type qcInfo uint8 func (i runeInfo) isYesC() bool { return i.flags&0x4 == 0 } @@ -91,22 +112,12 @@ func (r runeInfo) isInert() bool { return r.flags&0xf == 0 && r.ccc == 0 } -// Wrappers for tables.go - -// The 16-bit value of the decomposition tries is an index into a byte -// array of UTF-8 decomposition sequences. The first byte is the number -// of bytes in the decomposition (excluding this length byte). The actual -// sequence starts at the offset+1. -func decomposeNFC(s input, i int) []byte { - p := s.decomposeNFC(i) - n := decomps[p] - p++ - return decomps[p : p+uint16(n)] -} - -func decomposeNFKC(s input, i int) []byte { - p := s.decomposeNFKC(i) - n := decomps[p] +func (r runeInfo) decomposition() []byte { + if r.index == 0 { + return nil + } + p := r.index + n := decomps[p] & 0x3F p++ return decomps[p : p+uint16(n)] } @@ -124,16 +135,40 @@ func combine(a, b rune) rune { return recompMap[key] } -// The 16-bit character info has the following bit layout: -// 0..7 CCC value. -// 8..11 qcInfo for NFC/NFD -// 12..15 qcInfo for NFKC/NFKD func lookupInfoNFC(b input, i int) runeInfo { - v, sz := b.charinfo(i) - return runeInfo{size: uint8(sz), ccc: uint8(v), flags: qcInfo(v >> 8)} + v, sz := b.charinfoNFC(i) + return compInfo(v, sz) } func lookupInfoNFKC(b input, i int) runeInfo { - v, sz := b.charinfo(i) - return runeInfo{size: uint8(sz), ccc: uint8(v), flags: qcInfo(v >> 12)} + v, sz := b.charinfoNFKC(i) + return compInfo(v, sz) +} + +// compInfo converts the information contained in v and sz +// to a runeInfo. See the comment at the top of the file +// for more information on the format. +func compInfo(v uint16, sz int) runeInfo { + if v == 0 { + return runeInfo{size: uint8(sz)} + } else if v >= 0x8000 { + return runeInfo{ + size: uint8(sz), + ccc: uint8(v), + tccc: uint8(v), + flags: qcInfo(v>>8) & qcInfoMask, + } + } + // has decomposition + h := decomps[v] + f := (qcInfo(h&headerFlagsMask) >> 4) | 0x1 + ri := runeInfo{size: uint8(sz), flags: f, index: v} + if v >= firstCCC { + v += uint16(h&headerLenMask) + 1 + ri.tccc = decomps[v] + if v >= firstLeadingCCC { + ri.ccc = decomps[v+1] + } + } + return ri } diff --git a/libgo/go/exp/norm/input.go b/libgo/go/exp/norm/input.go index 7276c66cc12..9c564d67718 100644 --- a/libgo/go/exp/norm/input.go +++ b/libgo/go/exp/norm/input.go @@ -7,20 +7,19 @@ package norm import "unicode/utf8" type input interface { - skipASCII(p int) int + skipASCII(p, max int) int skipNonStarter(p int) int appendSlice(buf []byte, s, e int) []byte copySlice(buf []byte, s, e int) - charinfo(p int) (uint16, int) - decomposeNFC(p int) uint16 - decomposeNFKC(p int) uint16 + charinfoNFC(p int) (uint16, int) + charinfoNFKC(p int) (uint16, int) hangul(p int) rune } type inputString string -func (s inputString) skipASCII(p int) int { - for ; p < len(s) && s[p] < utf8.RuneSelf; p++ { +func (s inputString) skipASCII(p, max int) int { + for ; p < max && s[p] < utf8.RuneSelf; p++ { } return p } @@ -42,16 +41,12 @@ func (s inputString) copySlice(buf []byte, b, e int) { copy(buf, s[b:e]) } -func (s inputString) charinfo(p int) (uint16, int) { - return charInfoTrie.lookupString(string(s[p:])) +func (s inputString) charinfoNFC(p int) (uint16, int) { + return nfcTrie.lookupString(string(s[p:])) } -func (s inputString) decomposeNFC(p int) uint16 { - return nfcDecompTrie.lookupStringUnsafe(string(s[p:])) -} - -func (s inputString) decomposeNFKC(p int) uint16 { - return nfkcDecompTrie.lookupStringUnsafe(string(s[p:])) +func (s inputString) charinfoNFKC(p int) (uint16, int) { + return nfkcTrie.lookupString(string(s[p:])) } func (s inputString) hangul(p int) rune { @@ -64,8 +59,8 @@ func (s inputString) hangul(p int) rune { type inputBytes []byte -func (s inputBytes) skipASCII(p int) int { - for ; p < len(s) && s[p] < utf8.RuneSelf; p++ { +func (s inputBytes) skipASCII(p, max int) int { + for ; p < max && s[p] < utf8.RuneSelf; p++ { } return p } @@ -84,16 +79,12 @@ func (s inputBytes) copySlice(buf []byte, b, e int) { copy(buf, s[b:e]) } -func (s inputBytes) charinfo(p int) (uint16, int) { - return charInfoTrie.lookup(s[p:]) -} - -func (s inputBytes) decomposeNFC(p int) uint16 { - return nfcDecompTrie.lookupUnsafe(s[p:]) +func (s inputBytes) charinfoNFC(p int) (uint16, int) { + return nfcTrie.lookup(s[p:]) } -func (s inputBytes) decomposeNFKC(p int) uint16 { - return nfkcDecompTrie.lookupUnsafe(s[p:]) +func (s inputBytes) charinfoNFKC(p int) (uint16, int) { + return nfkcTrie.lookup(s[p:]) } func (s inputBytes) hangul(p int) rune { diff --git a/libgo/go/exp/norm/iter.go b/libgo/go/exp/norm/iter.go new file mode 100644 index 00000000000..761ba90cdd4 --- /dev/null +++ b/libgo/go/exp/norm/iter.go @@ -0,0 +1,286 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +const MaxSegmentSize = maxByteBufferSize + +// An Iter iterates over a string or byte slice, while normalizing it +// to a given Form. +type Iter struct { + rb reorderBuffer + info runeInfo // first character saved from previous iteration + next iterFunc // implementation of next depends on form + + p int // current position in input source + outStart int // start of current segment in output buffer + inStart int // start of current segment in input source + maxp int // position in output buffer after which not to start a new segment + maxseg int // for tracking an excess of combining characters + + tccc uint8 + done bool +} + +type iterFunc func(*Iter, []byte) int + +// SetInput initializes i to iterate over src after normalizing it to Form f. +func (i *Iter) SetInput(f Form, src []byte) { + i.rb.init(f, src) + if i.rb.f.composing { + i.next = nextComposed + } else { + i.next = nextDecomposed + } + i.p = 0 + if i.done = len(src) == 0; !i.done { + i.info = i.rb.f.info(i.rb.src, i.p) + } +} + +// SetInputString initializes i to iterate over src after normalizing it to Form f. +func (i *Iter) SetInputString(f Form, src string) { + i.rb.initString(f, src) + if i.rb.f.composing { + i.next = nextComposed + } else { + i.next = nextDecomposed + } + i.p = 0 + if i.done = len(src) == 0; !i.done { + i.info = i.rb.f.info(i.rb.src, i.p) + } +} + +// Pos returns the byte position at which the next call to Next will commence processing. +func (i *Iter) Pos() int { + return i.p +} + +// Done returns true if there is no more input to process. +func (i *Iter) Done() bool { + return i.done +} + +// Next writes f(i.input[i.Pos():n]...) to buffer buf, where n is the +// largest boundary of i.input such that the result fits in buf. +// It returns the number of bytes written to buf. +// len(buf) should be at least MaxSegmentSize. +// Done must be false before calling Next. +func (i *Iter) Next(buf []byte) int { + return i.next(i, buf) +} + +func (i *Iter) initNext(outn, inStart int) { + i.outStart = 0 + i.inStart = inStart + i.maxp = outn - MaxSegmentSize + i.maxseg = MaxSegmentSize +} + +// setStart resets the start of the new segment to the given position. +// It returns true if there is not enough room for the new segment. +func (i *Iter) setStart(outp, inp int) bool { + if outp > i.maxp { + return true + } + i.outStart = outp + i.inStart = inp + i.maxseg = outp + MaxSegmentSize + return false +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// nextDecomposed is the implementation of Next for forms NFD and NFKD. +func nextDecomposed(i *Iter, out []byte) int { + var outp int + i.initNext(len(out), i.p) +doFast: + inCopyStart, outCopyStart := i.p, outp // invariant xCopyStart <= i.xStart + for { + if sz := int(i.info.size); sz <= 1 { + // ASCII or illegal byte. Either way, advance by 1. + i.p++ + outp++ + max := min(i.rb.nsrc, len(out)-outp+i.p) + if np := i.rb.src.skipASCII(i.p, max); np > i.p { + outp += np - i.p + i.p = np + if i.p >= i.rb.nsrc { + break + } + // ASCII may combine with consecutive runes. + if i.setStart(outp-1, i.p-1) { + i.p-- + outp-- + i.info.size = 1 + break + } + } + } else if d := i.info.decomposition(); d != nil { + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) + p := outp + len(d) + if p > i.maxseg && i.setStart(outp, i.p) { + return outp + } + copy(out[outp:], d) + outp = p + i.p += sz + inCopyStart, outCopyStart = i.p, outp + } else if r := i.rb.src.hangul(i.p); r != 0 { + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) + for { + outp += decomposeHangul(out[outp:], r) + i.p += hangulUTF8Size + if r = i.rb.src.hangul(i.p); r == 0 { + break + } + if i.setStart(outp, i.p) { + return outp + } + } + inCopyStart, outCopyStart = i.p, outp + } else { + p := outp + sz + if p > i.maxseg && i.setStart(outp, i.p) { + break + } + outp = p + i.p += sz + } + if i.p >= i.rb.nsrc { + break + } + prevCC := i.info.tccc + i.info = i.rb.f.info(i.rb.src, i.p) + if cc := i.info.ccc; cc == 0 { + if i.setStart(outp, i.p) { + break + } + } else if cc < prevCC { + goto doNorm + } + } + if inCopyStart != i.p { + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) + } + i.done = i.p >= i.rb.nsrc + return outp +doNorm: + // Insert what we have decomposed so far in the reorderBuffer. + // As we will only reorder, there will always be enough room. + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) + if !i.rb.insertDecomposed(out[i.outStart:outp]) { + // Start over to prevent decompositions from crossing segment boundaries. + // This is a rare occurance. + i.p = i.inStart + i.info = i.rb.f.info(i.rb.src, i.p) + } + outp = i.outStart + for { + if !i.rb.insert(i.rb.src, i.p, i.info) { + break + } + if i.p += int(i.info.size); i.p >= i.rb.nsrc { + outp += i.rb.flushCopy(out[outp:]) + i.done = true + return outp + } + i.info = i.rb.f.info(i.rb.src, i.p) + if i.info.ccc == 0 { + break + } + } + // new segment or too many combining characters: exit normalization + if outp += i.rb.flushCopy(out[outp:]); i.setStart(outp, i.p) { + return outp + } + goto doFast +} + +// nextComposed is the implementation of Next for forms NFC and NFKC. +func nextComposed(i *Iter, out []byte) int { + var outp int + i.initNext(len(out), i.p) +doFast: + inCopyStart, outCopyStart := i.p, outp // invariant xCopyStart <= i.xStart + var prevCC uint8 + for { + if !i.info.isYesC() { + goto doNorm + } + if cc := i.info.ccc; cc == 0 { + if i.setStart(outp, i.p) { + break + } + } else if cc < prevCC { + goto doNorm + } + prevCC = i.info.tccc + sz := int(i.info.size) + if sz == 0 { + sz = 1 // illegal rune: copy byte-by-byte + } + p := outp + sz + if p > i.maxseg && i.setStart(outp, i.p) { + break + } + outp = p + i.p += sz + max := min(i.rb.nsrc, len(out)-outp+i.p) + if np := i.rb.src.skipASCII(i.p, max); np > i.p { + outp += np - i.p + i.p = np + if i.p >= i.rb.nsrc { + break + } + // ASCII may combine with consecutive runes. + if i.setStart(outp-1, i.p-1) { + i.p-- + outp-- + i.info = runeInfo{size: 1} + break + } + } + if i.p >= i.rb.nsrc { + break + } + i.info = i.rb.f.info(i.rb.src, i.p) + } + if inCopyStart != i.p { + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) + } + i.done = i.p >= i.rb.nsrc + return outp +doNorm: + i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.inStart) + outp, i.p = i.outStart, i.inStart + i.info = i.rb.f.info(i.rb.src, i.p) + for { + if !i.rb.insert(i.rb.src, i.p, i.info) { + break + } + if i.p += int(i.info.size); i.p >= i.rb.nsrc { + i.rb.compose() + outp += i.rb.flushCopy(out[outp:]) + i.done = true + return outp + } + i.info = i.rb.f.info(i.rb.src, i.p) + if i.info.boundaryBefore() { + break + } + } + i.rb.compose() + if outp += i.rb.flushCopy(out[outp:]); i.setStart(outp, i.p) { + return outp + } + goto doFast +} diff --git a/libgo/go/exp/norm/iter_test.go b/libgo/go/exp/norm/iter_test.go new file mode 100644 index 00000000000..f6e8d817251 --- /dev/null +++ b/libgo/go/exp/norm/iter_test.go @@ -0,0 +1,186 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import ( + "strings" + "testing" +) + +var iterBufSizes = []int{ + MaxSegmentSize, + 1.5 * MaxSegmentSize, + 2 * MaxSegmentSize, + 3 * MaxSegmentSize, + 100 * MaxSegmentSize, +} + +func doIterNorm(f Form, buf []byte, s string) []byte { + acc := []byte{} + i := Iter{} + i.SetInputString(f, s) + for !i.Done() { + n := i.Next(buf) + acc = append(acc, buf[:n]...) + } + return acc +} + +func runIterTests(t *testing.T, name string, f Form, tests []AppendTest, norm bool) { + for i, test := range tests { + in := test.left + test.right + gold := test.out + if norm { + gold = string(f.AppendString(nil, test.out)) + } + for _, sz := range iterBufSizes { + buf := make([]byte, sz) + out := string(doIterNorm(f, buf, in)) + if len(out) != len(gold) { + const msg = "%s:%d:%d: length is %d; want %d" + t.Errorf(msg, name, i, sz, len(out), len(gold)) + } + if out != gold { + // Find first rune that differs and show context. + ir := []rune(out) + ig := []rune(gold) + for j := 0; j < len(ir) && j < len(ig); j++ { + if ir[j] == ig[j] { + continue + } + if j -= 3; j < 0 { + j = 0 + } + for e := j + 7; j < e && j < len(ir) && j < len(ig); j++ { + const msg = "%s:%d:%d: runeAt(%d) = %U; want %U" + t.Errorf(msg, name, i, sz, j, ir[j], ig[j]) + } + break + } + } + } + } +} + +func rep(r rune, n int) string { + return strings.Repeat(string(r), n) +} + +var iterTests = []AppendTest{ + {"", ascii, ascii}, + {"", txt_all, txt_all}, + {"", "a" + rep(0x0300, MaxSegmentSize/2), "a" + rep(0x0300, MaxSegmentSize/2)}, +} + +var iterTestsD = []AppendTest{ + { // segment overflow on unchanged character + "", + "a" + rep(0x0300, MaxSegmentSize/2) + "\u0316", + "a" + rep(0x0300, MaxSegmentSize/2-1) + "\u0316\u0300", + }, + { // segment overflow on unchanged character + start value + "", + "a" + rep(0x0300, MaxSegmentSize/2+maxCombiningChars+4) + "\u0316", + "a" + rep(0x0300, MaxSegmentSize/2+maxCombiningChars) + "\u0316" + rep(0x300, 4), + }, + { // segment overflow on decomposition + "", + "a" + rep(0x0300, MaxSegmentSize/2-1) + "\u0340", + "a" + rep(0x0300, MaxSegmentSize/2), + }, + { // segment overflow on decomposition + start value + "", + "a" + rep(0x0300, MaxSegmentSize/2-1) + "\u0340" + rep(0x300, maxCombiningChars+4) + "\u0320", + "a" + rep(0x0300, MaxSegmentSize/2-1) + rep(0x300, maxCombiningChars+1) + "\u0320" + rep(0x300, 4), + }, + { // start value after ASCII overflow + "", + rep('a', MaxSegmentSize) + rep(0x300, maxCombiningChars+2) + "\u0320", + rep('a', MaxSegmentSize) + rep(0x300, maxCombiningChars) + "\u0320\u0300\u0300", + }, + { // start value after Hangul overflow + "", + rep(0xAC00, MaxSegmentSize/6) + rep(0x300, maxCombiningChars+2) + "\u0320", + strings.Repeat("\u1100\u1161", MaxSegmentSize/6) + rep(0x300, maxCombiningChars-1) + "\u0320" + rep(0x300, 3), + }, + { // start value after cc=0 + "", + "您您" + rep(0x300, maxCombiningChars+4) + "\u0320", + "您您" + rep(0x300, maxCombiningChars) + "\u0320" + rep(0x300, 4), + }, + { // start value after normalization + "", + "\u0300\u0320a" + rep(0x300, maxCombiningChars+4) + "\u0320", + "\u0320\u0300a" + rep(0x300, maxCombiningChars) + "\u0320" + rep(0x300, 4), + }, +} + +var iterTestsC = []AppendTest{ + { // ordering of non-composing combining characters + "", + "\u0305\u0316", + "\u0316\u0305", + }, + { // segment overflow + "", + "a" + rep(0x0305, MaxSegmentSize/2+4) + "\u0316", + "a" + rep(0x0305, MaxSegmentSize/2-1) + "\u0316" + rep(0x305, 5), + }, +} + +func TestIterNextD(t *testing.T) { + runIterTests(t, "IterNextD1", NFKD, appendTests, true) + runIterTests(t, "IterNextD2", NFKD, iterTests, true) + runIterTests(t, "IterNextD3", NFKD, iterTestsD, false) +} + +func TestIterNextC(t *testing.T) { + runIterTests(t, "IterNextC1", NFKC, appendTests, true) + runIterTests(t, "IterNextC2", NFKC, iterTests, true) + runIterTests(t, "IterNextC3", NFKC, iterTestsC, false) +} + +type SegmentTest struct { + in string + out []string +} + +var segmentTests = []SegmentTest{ + {rep('a', MaxSegmentSize), []string{rep('a', MaxSegmentSize), ""}}, + {rep('a', MaxSegmentSize+2), []string{rep('a', MaxSegmentSize-1), "aaa", ""}}, + {rep('a', MaxSegmentSize) + "\u0300aa", []string{rep('a', MaxSegmentSize-1), "a\u0300", "aa", ""}}, +} + +// Note that, by design, segmentation is equal for composing and decomposing forms. +func TestIterSegmentation(t *testing.T) { + segmentTest(t, "SegmentTestD", NFD, segmentTests) + segmentTest(t, "SegmentTestC", NFC, segmentTests) +} + +func segmentTest(t *testing.T, name string, f Form, tests []SegmentTest) { + iter := Iter{} + for i, tt := range segmentTests { + buf := make([]byte, MaxSegmentSize) + iter.SetInputString(f, tt.in) + for j, seg := range tt.out { + if seg == "" { + if !iter.Done() { + n := iter.Next(buf) + res := string(buf[:n]) + t.Errorf(`%s:%d:%d: expected Done()==true, found segment "%s"`, name, i, j, res) + } + continue + } + if iter.Done() { + t.Errorf("%s:%d:%d: Done()==true, want false", name, i, j) + } + n := iter.Next(buf) + seg = f.String(seg) + if res := string(buf[:n]); res != seg { + t.Errorf(`%s:%d:%d" segment was "%s" (%d); want "%s" (%d)`, name, i, j, res, len(res), seg, len(seg)) + } + } + } +} diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go index 43e1429c1b1..bb21bb58109 100644 --- a/libgo/go/exp/norm/maketables.go +++ b/libgo/go/exp/norm/maketables.go @@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + // Normalization table generator. // Data read from the web. +// See forminfo.go for a description of the trie values associated with each rune. package main @@ -17,6 +20,7 @@ import ( "net/http" "os" "regexp" + "sort" "strconv" "strings" ) @@ -187,18 +191,14 @@ func (f FormInfo) String() string { fmt.Fprintf(buf, " cmbBackward: %v\n", f.combinesBackward) fmt.Fprintf(buf, " isOneWay: %v\n", f.isOneWay) fmt.Fprintf(buf, " inDecomp: %v\n", f.inDecomp) - fmt.Fprintf(buf, " decomposition: %v\n", f.decomp) - fmt.Fprintf(buf, " expandedDecomp: %v\n", f.expandedDecomp) + fmt.Fprintf(buf, " decomposition: %X\n", f.decomp) + fmt.Fprintf(buf, " expandedDecomp: %X\n", f.expandedDecomp) return buf.String() } type Decomposition []rune -func (d Decomposition) String() string { - return fmt.Sprintf("%.4X", d) -} - func openReader(file string) (input io.ReadCloser) { if *localFiles { f, err := os.Open(file) @@ -571,80 +571,121 @@ func makeEntry(f *FormInfo) uint16 { return e } -// Bits -// 0..8: CCC -// 9..12: NF(C|D) qc bits. -// 13..16: NFK(C|D) qc bits. -func makeCharInfo(c Char) uint16 { - e := makeEntry(&c.forms[FCompatibility]) - e = e<<4 | makeEntry(&c.forms[FCanonical]) - e = e<<8 | uint16(c.ccc) - return e +// decompSet keeps track of unique decompositions, grouped by whether +// the decomposition is followed by a trailing and/or leading CCC. +type decompSet [4]map[string]bool + +func makeDecompSet() decompSet { + m := decompSet{} + for i, _ := range m { + m[i] = make(map[string]bool) + } + return m +} +func (m *decompSet) insert(key int, s string) { + m[key][s] = true } func printCharInfoTables() int { - // Quick Check + CCC trie. - t := newNode() - for i, char := range chars { - v := makeCharInfo(char) - if v != 0 { - t.insert(rune(i), v) + mkstr := func(r rune, f *FormInfo) (int, string) { + d := f.expandedDecomp + s := string([]rune(d)) + if max := 1 << 6; len(s) >= max { + const msg = "%U: too many bytes in decomposition: %d >= %d" + logger.Fatalf(msg, r, len(s), max) + } + head := uint8(len(s)) + if f.quickCheck[MComposed] != QCYes { + head |= 0x40 + } + if f.combinesForward { + head |= 0x80 + } + s = string([]byte{head}) + s + + lccc := ccc(d[0]) + tccc := ccc(d[len(d)-1]) + if tccc < lccc && lccc != 0 { + const msg = "%U: lccc (%d) must be <= tcc (%d)" + logger.Fatalf(msg, r, lccc, tccc) + } + index := 0 + if tccc > 0 || lccc > 0 { + s += string([]byte{tccc}) + index = 1 + if lccc > 0 { + s += string([]byte{lccc}) + index |= 2 + } } + return index, s } - return t.printTables("charInfo") -} -func printDecompositionTables() int { - decompositions := bytes.NewBuffer(make([]byte, 0, 10000)) - size := 0 - - // Map decompositions - positionMap := make(map[string]uint16) + decompSet := makeDecompSet() // Store the uniqued decompositions in a byte buffer, // preceded by their byte length. for _, c := range chars { - for f := 0; f < 2; f++ { - d := c.forms[f].expandedDecomp - s := string([]rune(d)) - if _, ok := positionMap[s]; !ok { - p := decompositions.Len() - decompositions.WriteByte(uint8(len(s))) - decompositions.WriteString(s) - positionMap[s] = uint16(p) + for _, f := range c.forms { + if len(f.expandedDecomp) == 0 { + continue } + if f.combinesBackward { + logger.Fatalf("%U: combinesBackward and decompose", c.codePoint) + } + index, s := mkstr(c.codePoint, &f) + decompSet.insert(index, s) } } + + decompositions := bytes.NewBuffer(make([]byte, 0, 10000)) + size := 0 + positionMap := make(map[string]uint16) + decompositions.WriteString("\000") + cname := []string{"firstCCC", "firstLeadingCCC", "", "lastDecomp"} + fmt.Println("const (") + for i, m := range decompSet { + sa := []string{} + for s, _ := range m { + sa = append(sa, s) + } + sort.Strings(sa) + for _, s := range sa { + p := decompositions.Len() + decompositions.WriteString(s) + positionMap[s] = uint16(p) + } + if cname[i] != "" { + fmt.Printf("%s = 0x%X\n", cname[i], decompositions.Len()) + } + } + fmt.Println("maxDecomp = 0x8000") + fmt.Println(")") b := decompositions.Bytes() printBytes(b, "decomps") size += len(b) - nfcT := newNode() - nfkcT := newNode() - for i, c := range chars { - d := c.forms[FCanonical].expandedDecomp - if len(d) != 0 { - nfcT.insert(rune(i), positionMap[string([]rune(d))]) - if ccc(c.codePoint) != ccc(d[0]) { - // We assume the lead ccc of a decomposition is !=0 in this case. - if ccc(d[0]) == 0 { - logger.Fatal("Expected differing CCC to be non-zero.") - } - } - } - d = c.forms[FCompatibility].expandedDecomp - if len(d) != 0 { - nfkcT.insert(rune(i), positionMap[string([]rune(d))]) - if ccc(c.codePoint) != ccc(d[0]) { - // We assume the lead ccc of a decomposition is !=0 in this case. - if ccc(d[0]) == 0 { - logger.Fatal("Expected differing CCC to be non-zero.") + varnames := []string{"nfc", "nfkc"} + for i := 0; i < FNumberOfFormTypes; i++ { + trie := newNode() + for r, c := range chars { + f := c.forms[i] + d := f.expandedDecomp + if len(d) != 0 { + _, key := mkstr(c.codePoint, &f) + trie.insert(rune(r), positionMap[key]) + if c.ccc != ccc(d[0]) { + // We assume the lead ccc of a decomposition !=0 in this case. + if ccc(d[0]) == 0 { + logger.Fatalf("Expected leading CCC to be non-zero; ccc is %d", c.ccc) + } } + } else if v := makeEntry(&f)<<8 | uint16(c.ccc); v != 0 { + trie.insert(c.codePoint, 0x8000|v) } } + size += trie.printTables(varnames[i]) } - size += nfcT.printTables("nfcDecomp") - size += nfkcT.printTables("nfkcDecomp") return size } @@ -687,15 +728,15 @@ func makeTables() { } list := strings.Split(*tablelist, ",") if *tablelist == "all" { - list = []string{"decomp", "recomp", "info"} + list = []string{"recomp", "info"} } fmt.Printf(fileHeader, *tablelist, *url) fmt.Println("// Version is the Unicode edition from which the tables are derived.") fmt.Printf("const Version = %q\n\n", version()) - if contains(list, "decomp") { - size += printDecompositionTables() + if contains(list, "info") { + size += printCharInfoTables() } if contains(list, "recomp") { @@ -730,9 +771,6 @@ func makeTables() { fmt.Printf("}\n\n") } - if contains(list, "info") { - size += printCharInfoTables() - } fmt.Printf("// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size) } @@ -761,6 +799,11 @@ func verifyComputed() { log.Fatalf("%U: NF*C must be maybe if combinesBackward", i) } } + nfc := c.forms[FCanonical] + nfkc := c.forms[FCompatibility] + if nfc.combinesBackward != nfkc.combinesBackward { + logger.Fatalf("%U: Cannot combine combinesBackward\n", c.codePoint) + } } } diff --git a/libgo/go/exp/norm/maketesttables.go b/libgo/go/exp/norm/maketesttables.go index 20eb889ddef..d3112b4041c 100644 --- a/libgo/go/exp/norm/maketesttables.go +++ b/libgo/go/exp/norm/maketesttables.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + // Generate test data for trie code. package main diff --git a/libgo/go/exp/norm/normalize.go b/libgo/go/exp/norm/normalize.go index 26bb4a0dc47..b5cd44abfa0 100644 --- a/libgo/go/exp/norm/normalize.go +++ b/libgo/go/exp/norm/normalize.go @@ -243,7 +243,7 @@ func quickSpan(rb *reorderBuffer, i int) int { lastSegStart := i src, n := rb.src, rb.nsrc for i < n { - if j := src.skipASCII(i); i != j { + if j := src.skipASCII(i, n); i != j { i = j lastSegStart = i - 1 lastCC = 0 @@ -448,11 +448,16 @@ func decomposeToLastBoundary(rb *reorderBuffer, buf []byte) []byte { } // Check that decomposition doesn't result in overflow. if info.hasDecomposition() { - dcomp := rb.f.decompose(inputBytes(buf), p-int(info.size)) - for i := 0; i < len(dcomp); { - inf := rb.f.info(inputBytes(dcomp), i) - i += int(inf.size) + if isHangul(buf) { + i += int(info.size) n++ + } else { + dcomp := info.decomposition() + for i := 0; i < len(dcomp); { + inf := rb.f.info(inputBytes(dcomp), i) + i += int(inf.size) + n++ + } } } else { n++ diff --git a/libgo/go/exp/norm/normalize_test.go b/libgo/go/exp/norm/normalize_test.go index c7d5e08fca0..8b970598b4d 100644 --- a/libgo/go/exp/norm/normalize_test.go +++ b/libgo/go/exp/norm/normalize_test.go @@ -5,6 +5,7 @@ package norm import ( + "bytes" "strings" "testing" ) @@ -495,15 +496,40 @@ func TestAppend(t *testing.T) { runAppendTests(t, "TestString", NFKC, stringF, appendTests) } +func appendBench(f Form, in []byte) func() { + buf := make([]byte, 0, 4*len(in)) + return func() { + f.Append(buf, in...) + } +} + +func iterBench(f Form, in []byte) func() { + buf := make([]byte, 4*len(in)) + iter := Iter{} + return func() { + iter.SetInput(f, in) + for !iter.Done() { + iter.Next(buf) + } + } +} + +func appendBenchmarks(bm []func(), f Form, in []byte) []func() { + //bm = append(bm, appendBench(f, in)) + bm = append(bm, iterBench(f, in)) + return bm +} + func doFormBenchmark(b *testing.B, inf, f Form, s string) { b.StopTimer() in := inf.Bytes([]byte(s)) - buf := make([]byte, 2*len(in)) - b.SetBytes(int64(len(in))) + bm := appendBenchmarks(nil, f, in) + b.SetBytes(int64(len(in) * len(bm))) b.StartTimer() for i := 0; i < b.N; i++ { - buf = f.Append(buf[0:0], in...) - buf = buf[0:0] + for _, fn := range bm { + fn() + } } } @@ -549,17 +575,21 @@ func BenchmarkNormalizeHangulNFD2NFD(b *testing.B) { doFormBenchmark(b, NFD, NFD, txt_kr) } +var forms = []Form{NFC, NFD, NFKC, NFKD} + func doTextBenchmark(b *testing.B, s string) { b.StopTimer() - b.SetBytes(int64(len(s)) * 4) in := []byte(s) - var buf = make([]byte, 0, 2*len(in)) + bm := []func(){} + for _, f := range forms { + bm = appendBenchmarks(bm, f, in) + } + b.SetBytes(int64(len(s) * len(bm))) b.StartTimer() for i := 0; i < b.N; i++ { - NFC.Append(buf, in...) - NFD.Append(buf, in...) - NFKC.Append(buf, in...) - NFKD.Append(buf, in...) + for _, f := range bm { + f() + } } } @@ -584,6 +614,11 @@ func BenchmarkJapanese(b *testing.B) { func BenchmarkChinese(b *testing.B) { doTextBenchmark(b, txt_cn) } +func BenchmarkOverflow(b *testing.B) { + doTextBenchmark(b, overflow) +} + +var overflow = string(bytes.Repeat([]byte("\u035D"), 4096)) + "\u035B" // Tests sampled from the Canonical ordering tests (Part 2) of // http://unicode.org/Public/UNIDATA/NormalizationTest.txt diff --git a/libgo/go/exp/norm/normregtest.go b/libgo/go/exp/norm/normregtest.go index 57ba7032981..507de1ae834 100644 --- a/libgo/go/exp/norm/normregtest.go +++ b/libgo/go/exp/norm/normregtest.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + package main import ( @@ -218,6 +220,17 @@ func cmpIsNormal(t *Test, name string, f norm.Form, test string, result, want bo func doTest(t *Test, f norm.Form, gold, test string) { result := f.Bytes([]byte(test)) cmpResult(t, "Bytes", f, gold, test, string(result)) + sresult := f.String(test) + cmpResult(t, "String", f, gold, test, sresult) + buf := make([]byte, norm.MaxSegmentSize) + acc := []byte{} + i := norm.Iter{} + i.SetInputString(f, test) + for !i.Done() { + n := i.Next(buf) + acc = append(acc, buf[:n]...) + } + cmpResult(t, "Iter.Next", f, gold, test, string(acc)) for i := range test { out := f.Append(f.Bytes([]byte(test[:i])), []byte(test[i:])...) cmpResult(t, fmt.Sprintf(":Append:%d", i), f, gold, test, string(out)) diff --git a/libgo/go/exp/norm/tables.go b/libgo/go/exp/norm/tables.go index 02a481b3b3d..e97b1710722 100644 --- a/libgo/go/exp/norm/tables.go +++ b/libgo/go/exp/norm/tables.go @@ -7,4658 +7,5718 @@ package norm // Version is the Unicode edition from which the tables are derived. const Version = "6.0.0" -// decomps: 17618 bytes +const ( + firstCCC = 0x2E45 + firstLeadingCCC = 0x4965 + lastDecomp = 0x49A2 + maxDecomp = 0x8000 +) + +// decomps: 18850 bytes var decomps = [...]byte{ // Bytes 0 - 3f - 0x00, 0x01, 0x20, 0x03, 0x20, 0xCC, 0x88, 0x01, - 0x61, 0x03, 0x20, 0xCC, 0x84, 0x01, 0x32, 0x01, - 0x33, 0x03, 0x20, 0xCC, 0x81, 0x02, 0xCE, 0xBC, - 0x03, 0x20, 0xCC, 0xA7, 0x01, 0x31, 0x01, 0x6F, - 0x05, 0x31, 0xE2, 0x81, 0x84, 0x34, 0x05, 0x31, - 0xE2, 0x81, 0x84, 0x32, 0x05, 0x33, 0xE2, 0x81, - 0x84, 0x34, 0x03, 0x41, 0xCC, 0x80, 0x03, 0x41, - 0xCC, 0x81, 0x03, 0x41, 0xCC, 0x82, 0x03, 0x41, + 0x00, 0x06, 0xE0, 0xA7, 0x87, 0xE0, 0xA6, 0xBE, + 0x06, 0xE0, 0xA7, 0x87, 0xE0, 0xA7, 0x97, 0x06, + 0xE0, 0xAD, 0x87, 0xE0, 0xAC, 0xBE, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAD, 0x96, 0x06, 0xE0, 0xAD, + 0x87, 0xE0, 0xAD, 0x97, 0x06, 0xE0, 0xAE, 0x92, + 0xE0, 0xAF, 0x97, 0x06, 0xE0, 0xAF, 0x86, 0xE0, + 0xAE, 0xBE, 0x06, 0xE0, 0xAF, 0x86, 0xE0, 0xAF, + 0x97, 0x06, 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xBE, // Bytes 40 - 7f - 0xCC, 0x83, 0x03, 0x41, 0xCC, 0x88, 0x03, 0x41, - 0xCC, 0x8A, 0x03, 0x43, 0xCC, 0xA7, 0x03, 0x45, - 0xCC, 0x80, 0x03, 0x45, 0xCC, 0x81, 0x03, 0x45, - 0xCC, 0x82, 0x03, 0x45, 0xCC, 0x88, 0x03, 0x49, - 0xCC, 0x80, 0x03, 0x49, 0xCC, 0x81, 0x03, 0x49, - 0xCC, 0x82, 0x03, 0x49, 0xCC, 0x88, 0x03, 0x4E, - 0xCC, 0x83, 0x03, 0x4F, 0xCC, 0x80, 0x03, 0x4F, - 0xCC, 0x81, 0x03, 0x4F, 0xCC, 0x82, 0x03, 0x4F, + 0x06, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0x06, + 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x06, 0xE0, 0xB5, + 0x86, 0xE0, 0xB4, 0xBE, 0x06, 0xE0, 0xB5, 0x86, + 0xE0, 0xB5, 0x97, 0x06, 0xE0, 0xB5, 0x87, 0xE0, + 0xB4, 0xBE, 0x06, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, + 0x9F, 0x06, 0xE1, 0x80, 0xA5, 0xE1, 0x80, 0xAE, + 0x06, 0xE1, 0xAC, 0x85, 0xE1, 0xAC, 0xB5, 0x06, // Bytes 80 - bf - 0xCC, 0x83, 0x03, 0x4F, 0xCC, 0x88, 0x03, 0x55, - 0xCC, 0x80, 0x03, 0x55, 0xCC, 0x81, 0x03, 0x55, - 0xCC, 0x82, 0x03, 0x55, 0xCC, 0x88, 0x03, 0x59, - 0xCC, 0x81, 0x03, 0x61, 0xCC, 0x80, 0x03, 0x61, - 0xCC, 0x81, 0x03, 0x61, 0xCC, 0x82, 0x03, 0x61, - 0xCC, 0x83, 0x03, 0x61, 0xCC, 0x88, 0x03, 0x61, - 0xCC, 0x8A, 0x03, 0x63, 0xCC, 0xA7, 0x03, 0x65, - 0xCC, 0x80, 0x03, 0x65, 0xCC, 0x81, 0x03, 0x65, + 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, + 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, + 0x8B, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0x8D, + 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0x91, 0xE1, + 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0xBA, 0xE1, 0xAC, + 0xB5, 0x06, 0xE1, 0xAC, 0xBC, 0xE1, 0xAC, 0xB5, + 0x06, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, 0x06, + 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, // Bytes c0 - ff - 0xCC, 0x82, 0x03, 0x65, 0xCC, 0x88, 0x03, 0x69, - 0xCC, 0x80, 0x03, 0x69, 0xCC, 0x81, 0x03, 0x69, - 0xCC, 0x82, 0x03, 0x69, 0xCC, 0x88, 0x03, 0x6E, - 0xCC, 0x83, 0x03, 0x6F, 0xCC, 0x80, 0x03, 0x6F, - 0xCC, 0x81, 0x03, 0x6F, 0xCC, 0x82, 0x03, 0x6F, - 0xCC, 0x83, 0x03, 0x6F, 0xCC, 0x88, 0x03, 0x75, - 0xCC, 0x80, 0x03, 0x75, 0xCC, 0x81, 0x03, 0x75, - 0xCC, 0x82, 0x03, 0x75, 0xCC, 0x88, 0x03, 0x79, + 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x09, 0xE0, 0xB3, + 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0x41, + 0x20, 0x41, 0x21, 0x41, 0x22, 0x41, 0x23, 0x41, + 0x24, 0x41, 0x25, 0x41, 0x26, 0x41, 0x27, 0x41, + 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41, 0x2B, 0x41, + 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41, 0x2F, 0x41, + 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, 0x33, 0x41, + 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, 0x37, 0x41, // Bytes 100 - 13f - 0xCC, 0x81, 0x03, 0x79, 0xCC, 0x88, 0x03, 0x41, - 0xCC, 0x84, 0x03, 0x61, 0xCC, 0x84, 0x03, 0x41, - 0xCC, 0x86, 0x03, 0x61, 0xCC, 0x86, 0x03, 0x41, - 0xCC, 0xA8, 0x03, 0x61, 0xCC, 0xA8, 0x03, 0x43, - 0xCC, 0x81, 0x03, 0x63, 0xCC, 0x81, 0x03, 0x43, - 0xCC, 0x82, 0x03, 0x63, 0xCC, 0x82, 0x03, 0x43, - 0xCC, 0x87, 0x03, 0x63, 0xCC, 0x87, 0x03, 0x43, - 0xCC, 0x8C, 0x03, 0x63, 0xCC, 0x8C, 0x03, 0x44, + 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41, 0x3B, 0x41, + 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41, 0x3F, 0x41, + 0x40, 0x41, 0x41, 0x41, 0x42, 0x41, 0x43, 0x41, + 0x44, 0x41, 0x45, 0x41, 0x46, 0x41, 0x47, 0x41, + 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41, 0x4B, 0x41, + 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41, 0x4F, 0x41, + 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, + 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x41, // Bytes 140 - 17f - 0xCC, 0x8C, 0x03, 0x64, 0xCC, 0x8C, 0x03, 0x45, - 0xCC, 0x84, 0x03, 0x65, 0xCC, 0x84, 0x03, 0x45, - 0xCC, 0x86, 0x03, 0x65, 0xCC, 0x86, 0x03, 0x45, - 0xCC, 0x87, 0x03, 0x65, 0xCC, 0x87, 0x03, 0x45, - 0xCC, 0xA8, 0x03, 0x65, 0xCC, 0xA8, 0x03, 0x45, - 0xCC, 0x8C, 0x03, 0x65, 0xCC, 0x8C, 0x03, 0x47, - 0xCC, 0x82, 0x03, 0x67, 0xCC, 0x82, 0x03, 0x47, - 0xCC, 0x86, 0x03, 0x67, 0xCC, 0x86, 0x03, 0x47, + 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, 0x5B, 0x41, + 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, 0x5F, 0x41, + 0x60, 0x41, 0x61, 0x41, 0x62, 0x41, 0x63, 0x41, + 0x64, 0x41, 0x65, 0x41, 0x66, 0x41, 0x67, 0x41, + 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41, 0x6B, 0x41, + 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41, 0x6F, 0x41, + 0x70, 0x41, 0x71, 0x41, 0x72, 0x41, 0x73, 0x41, + 0x74, 0x41, 0x75, 0x41, 0x76, 0x41, 0x77, 0x41, // Bytes 180 - 1bf - 0xCC, 0x87, 0x03, 0x67, 0xCC, 0x87, 0x03, 0x47, - 0xCC, 0xA7, 0x03, 0x67, 0xCC, 0xA7, 0x03, 0x48, - 0xCC, 0x82, 0x03, 0x68, 0xCC, 0x82, 0x03, 0x49, - 0xCC, 0x83, 0x03, 0x69, 0xCC, 0x83, 0x03, 0x49, - 0xCC, 0x84, 0x03, 0x69, 0xCC, 0x84, 0x03, 0x49, - 0xCC, 0x86, 0x03, 0x69, 0xCC, 0x86, 0x03, 0x49, - 0xCC, 0xA8, 0x03, 0x69, 0xCC, 0xA8, 0x03, 0x49, - 0xCC, 0x87, 0x02, 0x49, 0x4A, 0x02, 0x69, 0x6A, + 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41, 0x7B, 0x41, + 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42, 0x21, 0x21, + 0x42, 0x21, 0x3F, 0x42, 0x2E, 0x2E, 0x42, 0x30, + 0x2C, 0x42, 0x30, 0x2E, 0x42, 0x31, 0x2C, 0x42, + 0x31, 0x2E, 0x42, 0x31, 0x30, 0x42, 0x31, 0x31, + 0x42, 0x31, 0x32, 0x42, 0x31, 0x33, 0x42, 0x31, + 0x34, 0x42, 0x31, 0x35, 0x42, 0x31, 0x36, 0x42, + 0x31, 0x37, 0x42, 0x31, 0x38, 0x42, 0x31, 0x39, // Bytes 1c0 - 1ff - 0x03, 0x4A, 0xCC, 0x82, 0x03, 0x6A, 0xCC, 0x82, - 0x03, 0x4B, 0xCC, 0xA7, 0x03, 0x6B, 0xCC, 0xA7, - 0x03, 0x4C, 0xCC, 0x81, 0x03, 0x6C, 0xCC, 0x81, - 0x03, 0x4C, 0xCC, 0xA7, 0x03, 0x6C, 0xCC, 0xA7, - 0x03, 0x4C, 0xCC, 0x8C, 0x03, 0x6C, 0xCC, 0x8C, - 0x03, 0x4C, 0xC2, 0xB7, 0x03, 0x6C, 0xC2, 0xB7, - 0x03, 0x4E, 0xCC, 0x81, 0x03, 0x6E, 0xCC, 0x81, - 0x03, 0x4E, 0xCC, 0xA7, 0x03, 0x6E, 0xCC, 0xA7, + 0x42, 0x32, 0x2C, 0x42, 0x32, 0x2E, 0x42, 0x32, + 0x30, 0x42, 0x32, 0x31, 0x42, 0x32, 0x32, 0x42, + 0x32, 0x33, 0x42, 0x32, 0x34, 0x42, 0x32, 0x35, + 0x42, 0x32, 0x36, 0x42, 0x32, 0x37, 0x42, 0x32, + 0x38, 0x42, 0x32, 0x39, 0x42, 0x33, 0x2C, 0x42, + 0x33, 0x2E, 0x42, 0x33, 0x30, 0x42, 0x33, 0x31, + 0x42, 0x33, 0x32, 0x42, 0x33, 0x33, 0x42, 0x33, + 0x34, 0x42, 0x33, 0x35, 0x42, 0x33, 0x36, 0x42, // Bytes 200 - 23f - 0x03, 0x4E, 0xCC, 0x8C, 0x03, 0x6E, 0xCC, 0x8C, - 0x03, 0xCA, 0xBC, 0x6E, 0x03, 0x4F, 0xCC, 0x84, - 0x03, 0x6F, 0xCC, 0x84, 0x03, 0x4F, 0xCC, 0x86, - 0x03, 0x6F, 0xCC, 0x86, 0x03, 0x4F, 0xCC, 0x8B, - 0x03, 0x6F, 0xCC, 0x8B, 0x03, 0x52, 0xCC, 0x81, - 0x03, 0x72, 0xCC, 0x81, 0x03, 0x52, 0xCC, 0xA7, - 0x03, 0x72, 0xCC, 0xA7, 0x03, 0x52, 0xCC, 0x8C, - 0x03, 0x72, 0xCC, 0x8C, 0x03, 0x53, 0xCC, 0x81, + 0x33, 0x37, 0x42, 0x33, 0x38, 0x42, 0x33, 0x39, + 0x42, 0x34, 0x2C, 0x42, 0x34, 0x2E, 0x42, 0x34, + 0x30, 0x42, 0x34, 0x31, 0x42, 0x34, 0x32, 0x42, + 0x34, 0x33, 0x42, 0x34, 0x34, 0x42, 0x34, 0x35, + 0x42, 0x34, 0x36, 0x42, 0x34, 0x37, 0x42, 0x34, + 0x38, 0x42, 0x34, 0x39, 0x42, 0x35, 0x2C, 0x42, + 0x35, 0x2E, 0x42, 0x35, 0x30, 0x42, 0x36, 0x2C, + 0x42, 0x36, 0x2E, 0x42, 0x37, 0x2C, 0x42, 0x37, // Bytes 240 - 27f - 0x03, 0x73, 0xCC, 0x81, 0x03, 0x53, 0xCC, 0x82, - 0x03, 0x73, 0xCC, 0x82, 0x03, 0x53, 0xCC, 0xA7, - 0x03, 0x73, 0xCC, 0xA7, 0x03, 0x53, 0xCC, 0x8C, - 0x03, 0x73, 0xCC, 0x8C, 0x03, 0x54, 0xCC, 0xA7, - 0x03, 0x74, 0xCC, 0xA7, 0x03, 0x54, 0xCC, 0x8C, - 0x03, 0x74, 0xCC, 0x8C, 0x03, 0x55, 0xCC, 0x83, - 0x03, 0x75, 0xCC, 0x83, 0x03, 0x55, 0xCC, 0x84, - 0x03, 0x75, 0xCC, 0x84, 0x03, 0x55, 0xCC, 0x86, + 0x2E, 0x42, 0x38, 0x2C, 0x42, 0x38, 0x2E, 0x42, + 0x39, 0x2C, 0x42, 0x39, 0x2E, 0x42, 0x3D, 0x3D, + 0x42, 0x3F, 0x21, 0x42, 0x3F, 0x3F, 0x42, 0x41, + 0x55, 0x42, 0x42, 0x71, 0x42, 0x43, 0x44, 0x42, + 0x44, 0x4A, 0x42, 0x44, 0x5A, 0x42, 0x44, 0x7A, + 0x42, 0x47, 0x42, 0x42, 0x47, 0x79, 0x42, 0x48, + 0x50, 0x42, 0x48, 0x56, 0x42, 0x48, 0x67, 0x42, + 0x48, 0x7A, 0x42, 0x49, 0x49, 0x42, 0x49, 0x4A, // Bytes 280 - 2bf - 0x03, 0x75, 0xCC, 0x86, 0x03, 0x55, 0xCC, 0x8A, - 0x03, 0x75, 0xCC, 0x8A, 0x03, 0x55, 0xCC, 0x8B, - 0x03, 0x75, 0xCC, 0x8B, 0x03, 0x55, 0xCC, 0xA8, - 0x03, 0x75, 0xCC, 0xA8, 0x03, 0x57, 0xCC, 0x82, - 0x03, 0x77, 0xCC, 0x82, 0x03, 0x59, 0xCC, 0x82, - 0x03, 0x79, 0xCC, 0x82, 0x03, 0x59, 0xCC, 0x88, - 0x03, 0x5A, 0xCC, 0x81, 0x03, 0x7A, 0xCC, 0x81, - 0x03, 0x5A, 0xCC, 0x87, 0x03, 0x7A, 0xCC, 0x87, + 0x42, 0x49, 0x55, 0x42, 0x49, 0x56, 0x42, 0x49, + 0x58, 0x42, 0x4B, 0x42, 0x42, 0x4B, 0x4B, 0x42, + 0x4B, 0x4D, 0x42, 0x4C, 0x4A, 0x42, 0x4C, 0x6A, + 0x42, 0x4D, 0x42, 0x42, 0x4D, 0x56, 0x42, 0x4D, + 0x57, 0x42, 0x4E, 0x4A, 0x42, 0x4E, 0x6A, 0x42, + 0x4E, 0x6F, 0x42, 0x50, 0x48, 0x42, 0x50, 0x52, + 0x42, 0x50, 0x61, 0x42, 0x52, 0x73, 0x42, 0x53, + 0x44, 0x42, 0x53, 0x4D, 0x42, 0x53, 0x53, 0x42, // Bytes 2c0 - 2ff - 0x03, 0x5A, 0xCC, 0x8C, 0x03, 0x7A, 0xCC, 0x8C, - 0x01, 0x73, 0x03, 0x4F, 0xCC, 0x9B, 0x03, 0x6F, - 0xCC, 0x9B, 0x03, 0x55, 0xCC, 0x9B, 0x03, 0x75, - 0xCC, 0x9B, 0x04, 0x44, 0x5A, 0xCC, 0x8C, 0x04, - 0x44, 0x7A, 0xCC, 0x8C, 0x04, 0x64, 0x7A, 0xCC, - 0x8C, 0x02, 0x4C, 0x4A, 0x02, 0x4C, 0x6A, 0x02, - 0x6C, 0x6A, 0x02, 0x4E, 0x4A, 0x02, 0x4E, 0x6A, - 0x02, 0x6E, 0x6A, 0x03, 0x41, 0xCC, 0x8C, 0x03, + 0x53, 0x76, 0x42, 0x54, 0x4D, 0x42, 0x56, 0x49, + 0x42, 0x57, 0x43, 0x42, 0x57, 0x5A, 0x42, 0x57, + 0x62, 0x42, 0x58, 0x49, 0x42, 0x63, 0x63, 0x42, + 0x63, 0x64, 0x42, 0x63, 0x6D, 0x42, 0x64, 0x42, + 0x42, 0x64, 0x61, 0x42, 0x64, 0x6C, 0x42, 0x64, + 0x6D, 0x42, 0x64, 0x7A, 0x42, 0x65, 0x56, 0x42, + 0x66, 0x66, 0x42, 0x66, 0x69, 0x42, 0x66, 0x6C, + 0x42, 0x66, 0x6D, 0x42, 0x68, 0x61, 0x42, 0x69, // Bytes 300 - 33f - 0x61, 0xCC, 0x8C, 0x03, 0x49, 0xCC, 0x8C, 0x03, - 0x69, 0xCC, 0x8C, 0x03, 0x4F, 0xCC, 0x8C, 0x03, - 0x6F, 0xCC, 0x8C, 0x03, 0x55, 0xCC, 0x8C, 0x03, - 0x75, 0xCC, 0x8C, 0x05, 0x55, 0xCC, 0x88, 0xCC, - 0x84, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x84, 0x05, - 0x55, 0xCC, 0x88, 0xCC, 0x81, 0x05, 0x75, 0xCC, - 0x88, 0xCC, 0x81, 0x05, 0x55, 0xCC, 0x88, 0xCC, - 0x8C, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x8C, 0x05, + 0x69, 0x42, 0x69, 0x6A, 0x42, 0x69, 0x6E, 0x42, + 0x69, 0x76, 0x42, 0x69, 0x78, 0x42, 0x6B, 0x41, + 0x42, 0x6B, 0x56, 0x42, 0x6B, 0x57, 0x42, 0x6B, + 0x67, 0x42, 0x6B, 0x6C, 0x42, 0x6B, 0x6D, 0x42, + 0x6B, 0x74, 0x42, 0x6C, 0x6A, 0x42, 0x6C, 0x6D, + 0x42, 0x6C, 0x6E, 0x42, 0x6C, 0x78, 0x42, 0x6D, + 0x32, 0x42, 0x6D, 0x33, 0x42, 0x6D, 0x41, 0x42, + 0x6D, 0x56, 0x42, 0x6D, 0x57, 0x42, 0x6D, 0x62, // Bytes 340 - 37f - 0x55, 0xCC, 0x88, 0xCC, 0x80, 0x05, 0x75, 0xCC, - 0x88, 0xCC, 0x80, 0x05, 0x41, 0xCC, 0x88, 0xCC, - 0x84, 0x05, 0x61, 0xCC, 0x88, 0xCC, 0x84, 0x05, - 0x41, 0xCC, 0x87, 0xCC, 0x84, 0x05, 0x61, 0xCC, - 0x87, 0xCC, 0x84, 0x04, 0xC3, 0x86, 0xCC, 0x84, - 0x04, 0xC3, 0xA6, 0xCC, 0x84, 0x03, 0x47, 0xCC, - 0x8C, 0x03, 0x67, 0xCC, 0x8C, 0x03, 0x4B, 0xCC, - 0x8C, 0x03, 0x6B, 0xCC, 0x8C, 0x03, 0x4F, 0xCC, + 0x42, 0x6D, 0x67, 0x42, 0x6D, 0x6C, 0x42, 0x6D, + 0x6D, 0x42, 0x6D, 0x73, 0x42, 0x6E, 0x41, 0x42, + 0x6E, 0x46, 0x42, 0x6E, 0x56, 0x42, 0x6E, 0x57, + 0x42, 0x6E, 0x6A, 0x42, 0x6E, 0x6D, 0x42, 0x6E, + 0x73, 0x42, 0x6F, 0x56, 0x42, 0x70, 0x41, 0x42, + 0x70, 0x46, 0x42, 0x70, 0x56, 0x42, 0x70, 0x57, + 0x42, 0x70, 0x63, 0x42, 0x70, 0x73, 0x42, 0x73, + 0x72, 0x42, 0x73, 0x74, 0x42, 0x76, 0x69, 0x42, // Bytes 380 - 3bf - 0xA8, 0x03, 0x6F, 0xCC, 0xA8, 0x05, 0x4F, 0xCC, - 0xA8, 0xCC, 0x84, 0x05, 0x6F, 0xCC, 0xA8, 0xCC, - 0x84, 0x04, 0xC6, 0xB7, 0xCC, 0x8C, 0x04, 0xCA, - 0x92, 0xCC, 0x8C, 0x03, 0x6A, 0xCC, 0x8C, 0x02, - 0x44, 0x5A, 0x02, 0x44, 0x7A, 0x02, 0x64, 0x7A, - 0x03, 0x47, 0xCC, 0x81, 0x03, 0x67, 0xCC, 0x81, - 0x03, 0x4E, 0xCC, 0x80, 0x03, 0x6E, 0xCC, 0x80, - 0x05, 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0x05, 0x61, + 0x78, 0x69, 0x42, 0xC2, 0xA2, 0x42, 0xC2, 0xA3, + 0x42, 0xC2, 0xA5, 0x42, 0xC2, 0xA6, 0x42, 0xC2, + 0xAC, 0x42, 0xC2, 0xB4, 0x42, 0xC2, 0xB7, 0x42, + 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42, 0xC4, 0xA7, + 0x42, 0xC4, 0xB1, 0x42, 0xC5, 0x8B, 0x42, 0xC6, + 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42, + 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90, + 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9, // Bytes 3c0 - 3ff - 0xCC, 0x8A, 0xCC, 0x81, 0x04, 0xC3, 0x86, 0xCC, - 0x81, 0x04, 0xC3, 0xA6, 0xCC, 0x81, 0x04, 0xC3, - 0x98, 0xCC, 0x81, 0x04, 0xC3, 0xB8, 0xCC, 0x81, - 0x03, 0x41, 0xCC, 0x8F, 0x03, 0x61, 0xCC, 0x8F, - 0x03, 0x41, 0xCC, 0x91, 0x03, 0x61, 0xCC, 0x91, - 0x03, 0x45, 0xCC, 0x8F, 0x03, 0x65, 0xCC, 0x8F, - 0x03, 0x45, 0xCC, 0x91, 0x03, 0x65, 0xCC, 0x91, - 0x03, 0x49, 0xCC, 0x8F, 0x03, 0x69, 0xCC, 0x8F, + 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42, + 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F, + 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9, + 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42, + 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAD, + 0x42, 0xC9, 0xAF, 0x42, 0xC9, 0xB0, 0x42, 0xC9, + 0xB1, 0x42, 0xC9, 0xB2, 0x42, 0xC9, 0xB3, 0x42, + 0xC9, 0xB4, 0x42, 0xC9, 0xB5, 0x42, 0xC9, 0xB8, // Bytes 400 - 43f - 0x03, 0x49, 0xCC, 0x91, 0x03, 0x69, 0xCC, 0x91, - 0x03, 0x4F, 0xCC, 0x8F, 0x03, 0x6F, 0xCC, 0x8F, - 0x03, 0x4F, 0xCC, 0x91, 0x03, 0x6F, 0xCC, 0x91, - 0x03, 0x52, 0xCC, 0x8F, 0x03, 0x72, 0xCC, 0x8F, - 0x03, 0x52, 0xCC, 0x91, 0x03, 0x72, 0xCC, 0x91, - 0x03, 0x55, 0xCC, 0x8F, 0x03, 0x75, 0xCC, 0x8F, - 0x03, 0x55, 0xCC, 0x91, 0x03, 0x75, 0xCC, 0x91, - 0x03, 0x53, 0xCC, 0xA6, 0x03, 0x73, 0xCC, 0xA6, + 0x42, 0xC9, 0xB9, 0x42, 0xC9, 0xBB, 0x42, 0xCA, + 0x81, 0x42, 0xCA, 0x82, 0x42, 0xCA, 0x83, 0x42, + 0xCA, 0x89, 0x42, 0xCA, 0x8A, 0x42, 0xCA, 0x8B, + 0x42, 0xCA, 0x8C, 0x42, 0xCA, 0x90, 0x42, 0xCA, + 0x91, 0x42, 0xCA, 0x92, 0x42, 0xCA, 0x95, 0x42, + 0xCA, 0x9D, 0x42, 0xCA, 0x9F, 0x42, 0xCA, 0xB9, + 0x42, 0xCE, 0x91, 0x42, 0xCE, 0x92, 0x42, 0xCE, + 0x93, 0x42, 0xCE, 0x94, 0x42, 0xCE, 0x95, 0x42, // Bytes 440 - 47f - 0x03, 0x54, 0xCC, 0xA6, 0x03, 0x74, 0xCC, 0xA6, - 0x03, 0x48, 0xCC, 0x8C, 0x03, 0x68, 0xCC, 0x8C, - 0x03, 0x41, 0xCC, 0x87, 0x03, 0x61, 0xCC, 0x87, - 0x03, 0x45, 0xCC, 0xA7, 0x03, 0x65, 0xCC, 0xA7, - 0x05, 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0x05, 0x6F, - 0xCC, 0x88, 0xCC, 0x84, 0x05, 0x4F, 0xCC, 0x83, - 0xCC, 0x84, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84, - 0x03, 0x4F, 0xCC, 0x87, 0x03, 0x6F, 0xCC, 0x87, + 0xCE, 0x96, 0x42, 0xCE, 0x97, 0x42, 0xCE, 0x98, + 0x42, 0xCE, 0x99, 0x42, 0xCE, 0x9A, 0x42, 0xCE, + 0x9B, 0x42, 0xCE, 0x9C, 0x42, 0xCE, 0x9D, 0x42, + 0xCE, 0x9E, 0x42, 0xCE, 0x9F, 0x42, 0xCE, 0xA0, + 0x42, 0xCE, 0xA1, 0x42, 0xCE, 0xA3, 0x42, 0xCE, + 0xA4, 0x42, 0xCE, 0xA5, 0x42, 0xCE, 0xA6, 0x42, + 0xCE, 0xA7, 0x42, 0xCE, 0xA8, 0x42, 0xCE, 0xA9, + 0x42, 0xCE, 0xB1, 0x42, 0xCE, 0xB2, 0x42, 0xCE, // Bytes 480 - 4bf - 0x05, 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0x05, 0x6F, - 0xCC, 0x87, 0xCC, 0x84, 0x03, 0x59, 0xCC, 0x84, - 0x03, 0x79, 0xCC, 0x84, 0x01, 0x68, 0x02, 0xC9, - 0xA6, 0x01, 0x6A, 0x01, 0x72, 0x02, 0xC9, 0xB9, - 0x02, 0xC9, 0xBB, 0x02, 0xCA, 0x81, 0x01, 0x77, - 0x01, 0x79, 0x03, 0x20, 0xCC, 0x86, 0x03, 0x20, - 0xCC, 0x87, 0x03, 0x20, 0xCC, 0x8A, 0x03, 0x20, - 0xCC, 0xA8, 0x03, 0x20, 0xCC, 0x83, 0x03, 0x20, + 0xB3, 0x42, 0xCE, 0xB4, 0x42, 0xCE, 0xB5, 0x42, + 0xCE, 0xB6, 0x42, 0xCE, 0xB7, 0x42, 0xCE, 0xB8, + 0x42, 0xCE, 0xB9, 0x42, 0xCE, 0xBA, 0x42, 0xCE, + 0xBB, 0x42, 0xCE, 0xBC, 0x42, 0xCE, 0xBD, 0x42, + 0xCE, 0xBE, 0x42, 0xCE, 0xBF, 0x42, 0xCF, 0x80, + 0x42, 0xCF, 0x81, 0x42, 0xCF, 0x82, 0x42, 0xCF, + 0x83, 0x42, 0xCF, 0x84, 0x42, 0xCF, 0x85, 0x42, + 0xCF, 0x86, 0x42, 0xCF, 0x87, 0x42, 0xCF, 0x88, // Bytes 4c0 - 4ff - 0xCC, 0x8B, 0x02, 0xC9, 0xA3, 0x01, 0x6C, 0x01, - 0x78, 0x02, 0xCA, 0x95, 0x02, 0xCC, 0x80, 0x02, - 0xCC, 0x81, 0x02, 0xCC, 0x93, 0x04, 0xCC, 0x88, - 0xCC, 0x81, 0x02, 0xCA, 0xB9, 0x03, 0x20, 0xCD, - 0x85, 0x01, 0x3B, 0x04, 0xC2, 0xA8, 0xCC, 0x81, - 0x05, 0x20, 0xCC, 0x88, 0xCC, 0x81, 0x04, 0xCE, - 0x91, 0xCC, 0x81, 0x02, 0xC2, 0xB7, 0x04, 0xCE, - 0x95, 0xCC, 0x81, 0x04, 0xCE, 0x97, 0xCC, 0x81, + 0x42, 0xCF, 0x89, 0x42, 0xCF, 0x9C, 0x42, 0xCF, + 0x9D, 0x42, 0xD0, 0xBD, 0x42, 0xD7, 0x90, 0x42, + 0xD7, 0x91, 0x42, 0xD7, 0x92, 0x42, 0xD7, 0x93, + 0x42, 0xD7, 0x94, 0x42, 0xD7, 0x9B, 0x42, 0xD7, + 0x9C, 0x42, 0xD7, 0x9D, 0x42, 0xD7, 0xA2, 0x42, + 0xD7, 0xA8, 0x42, 0xD7, 0xAA, 0x42, 0xD8, 0xA1, + 0x42, 0xD8, 0xA7, 0x42, 0xD8, 0xA8, 0x42, 0xD8, + 0xA9, 0x42, 0xD8, 0xAA, 0x42, 0xD8, 0xAB, 0x42, // Bytes 500 - 53f - 0x04, 0xCE, 0x99, 0xCC, 0x81, 0x04, 0xCE, 0x9F, - 0xCC, 0x81, 0x04, 0xCE, 0xA5, 0xCC, 0x81, 0x04, - 0xCE, 0xA9, 0xCC, 0x81, 0x06, 0xCE, 0xB9, 0xCC, - 0x88, 0xCC, 0x81, 0x04, 0xCE, 0x99, 0xCC, 0x88, - 0x04, 0xCE, 0xA5, 0xCC, 0x88, 0x04, 0xCE, 0xB1, - 0xCC, 0x81, 0x04, 0xCE, 0xB5, 0xCC, 0x81, 0x04, - 0xCE, 0xB7, 0xCC, 0x81, 0x04, 0xCE, 0xB9, 0xCC, - 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, + 0xD8, 0xAC, 0x42, 0xD8, 0xAD, 0x42, 0xD8, 0xAE, + 0x42, 0xD8, 0xAF, 0x42, 0xD8, 0xB0, 0x42, 0xD8, + 0xB1, 0x42, 0xD8, 0xB2, 0x42, 0xD8, 0xB3, 0x42, + 0xD8, 0xB4, 0x42, 0xD8, 0xB5, 0x42, 0xD8, 0xB6, + 0x42, 0xD8, 0xB7, 0x42, 0xD8, 0xB8, 0x42, 0xD8, + 0xB9, 0x42, 0xD8, 0xBA, 0x42, 0xD9, 0x81, 0x42, + 0xD9, 0x82, 0x42, 0xD9, 0x83, 0x42, 0xD9, 0x84, + 0x42, 0xD9, 0x85, 0x42, 0xD9, 0x86, 0x42, 0xD9, // Bytes 540 - 57f - 0x04, 0xCE, 0xB9, 0xCC, 0x88, 0x04, 0xCF, 0x85, - 0xCC, 0x88, 0x04, 0xCE, 0xBF, 0xCC, 0x81, 0x04, - 0xCF, 0x85, 0xCC, 0x81, 0x04, 0xCF, 0x89, 0xCC, - 0x81, 0x02, 0xCE, 0xB2, 0x02, 0xCE, 0xB8, 0x02, - 0xCE, 0xA5, 0x04, 0xCF, 0x92, 0xCC, 0x81, 0x04, - 0xCF, 0x92, 0xCC, 0x88, 0x02, 0xCF, 0x86, 0x02, - 0xCF, 0x80, 0x02, 0xCE, 0xBA, 0x02, 0xCF, 0x81, - 0x02, 0xCF, 0x82, 0x02, 0xCE, 0x98, 0x02, 0xCE, + 0x87, 0x42, 0xD9, 0x88, 0x42, 0xD9, 0x89, 0x42, + 0xD9, 0x8A, 0x42, 0xD9, 0xB1, 0x42, 0xD9, 0xB9, + 0x42, 0xD9, 0xBA, 0x42, 0xD9, 0xBB, 0x42, 0xD9, + 0xBE, 0x42, 0xD9, 0xBF, 0x42, 0xDA, 0x80, 0x42, + 0xDA, 0x83, 0x42, 0xDA, 0x84, 0x42, 0xDA, 0x86, + 0x42, 0xDA, 0x87, 0x42, 0xDA, 0x88, 0x42, 0xDA, + 0x8C, 0x42, 0xDA, 0x8D, 0x42, 0xDA, 0x8E, 0x42, + 0xDA, 0x91, 0x42, 0xDA, 0x98, 0x42, 0xDA, 0xA4, // Bytes 580 - 5bf - 0xB5, 0x02, 0xCE, 0xA3, 0x04, 0xD0, 0x95, 0xCC, - 0x80, 0x04, 0xD0, 0x95, 0xCC, 0x88, 0x04, 0xD0, - 0x93, 0xCC, 0x81, 0x04, 0xD0, 0x86, 0xCC, 0x88, - 0x04, 0xD0, 0x9A, 0xCC, 0x81, 0x04, 0xD0, 0x98, - 0xCC, 0x80, 0x04, 0xD0, 0xA3, 0xCC, 0x86, 0x04, - 0xD0, 0x98, 0xCC, 0x86, 0x04, 0xD0, 0xB8, 0xCC, - 0x86, 0x04, 0xD0, 0xB5, 0xCC, 0x80, 0x04, 0xD0, - 0xB5, 0xCC, 0x88, 0x04, 0xD0, 0xB3, 0xCC, 0x81, + 0x42, 0xDA, 0xA6, 0x42, 0xDA, 0xA9, 0x42, 0xDA, + 0xAD, 0x42, 0xDA, 0xAF, 0x42, 0xDA, 0xB1, 0x42, + 0xDA, 0xB3, 0x42, 0xDA, 0xBA, 0x42, 0xDA, 0xBB, + 0x42, 0xDA, 0xBE, 0x42, 0xDB, 0x81, 0x42, 0xDB, + 0x85, 0x42, 0xDB, 0x86, 0x42, 0xDB, 0x87, 0x42, + 0xDB, 0x88, 0x42, 0xDB, 0x89, 0x42, 0xDB, 0x8B, + 0x42, 0xDB, 0x8C, 0x42, 0xDB, 0x90, 0x42, 0xDB, + 0x92, 0x43, 0x28, 0x31, 0x29, 0x43, 0x28, 0x32, // Bytes 5c0 - 5ff - 0x04, 0xD1, 0x96, 0xCC, 0x88, 0x04, 0xD0, 0xBA, - 0xCC, 0x81, 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0x04, - 0xD1, 0x83, 0xCC, 0x86, 0x04, 0xD1, 0xB4, 0xCC, - 0x8F, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0x04, 0xD0, - 0x96, 0xCC, 0x86, 0x04, 0xD0, 0xB6, 0xCC, 0x86, - 0x04, 0xD0, 0x90, 0xCC, 0x86, 0x04, 0xD0, 0xB0, - 0xCC, 0x86, 0x04, 0xD0, 0x90, 0xCC, 0x88, 0x04, - 0xD0, 0xB0, 0xCC, 0x88, 0x04, 0xD0, 0x95, 0xCC, + 0x29, 0x43, 0x28, 0x33, 0x29, 0x43, 0x28, 0x34, + 0x29, 0x43, 0x28, 0x35, 0x29, 0x43, 0x28, 0x36, + 0x29, 0x43, 0x28, 0x37, 0x29, 0x43, 0x28, 0x38, + 0x29, 0x43, 0x28, 0x39, 0x29, 0x43, 0x28, 0x41, + 0x29, 0x43, 0x28, 0x42, 0x29, 0x43, 0x28, 0x43, + 0x29, 0x43, 0x28, 0x44, 0x29, 0x43, 0x28, 0x45, + 0x29, 0x43, 0x28, 0x46, 0x29, 0x43, 0x28, 0x47, + 0x29, 0x43, 0x28, 0x48, 0x29, 0x43, 0x28, 0x49, // Bytes 600 - 63f - 0x86, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0x04, 0xD3, - 0x98, 0xCC, 0x88, 0x04, 0xD3, 0x99, 0xCC, 0x88, - 0x04, 0xD0, 0x96, 0xCC, 0x88, 0x04, 0xD0, 0xB6, - 0xCC, 0x88, 0x04, 0xD0, 0x97, 0xCC, 0x88, 0x04, - 0xD0, 0xB7, 0xCC, 0x88, 0x04, 0xD0, 0x98, 0xCC, - 0x84, 0x04, 0xD0, 0xB8, 0xCC, 0x84, 0x04, 0xD0, - 0x98, 0xCC, 0x88, 0x04, 0xD0, 0xB8, 0xCC, 0x88, - 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0x04, 0xD0, 0xBE, + 0x29, 0x43, 0x28, 0x4A, 0x29, 0x43, 0x28, 0x4B, + 0x29, 0x43, 0x28, 0x4C, 0x29, 0x43, 0x28, 0x4D, + 0x29, 0x43, 0x28, 0x4E, 0x29, 0x43, 0x28, 0x4F, + 0x29, 0x43, 0x28, 0x50, 0x29, 0x43, 0x28, 0x51, + 0x29, 0x43, 0x28, 0x52, 0x29, 0x43, 0x28, 0x53, + 0x29, 0x43, 0x28, 0x54, 0x29, 0x43, 0x28, 0x55, + 0x29, 0x43, 0x28, 0x56, 0x29, 0x43, 0x28, 0x57, + 0x29, 0x43, 0x28, 0x58, 0x29, 0x43, 0x28, 0x59, // Bytes 640 - 67f - 0xCC, 0x88, 0x04, 0xD3, 0xA8, 0xCC, 0x88, 0x04, - 0xD3, 0xA9, 0xCC, 0x88, 0x04, 0xD0, 0xAD, 0xCC, - 0x88, 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0x04, 0xD0, - 0xA3, 0xCC, 0x84, 0x04, 0xD1, 0x83, 0xCC, 0x84, - 0x04, 0xD0, 0xA3, 0xCC, 0x88, 0x04, 0xD1, 0x83, - 0xCC, 0x88, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0x04, - 0xD1, 0x83, 0xCC, 0x8B, 0x04, 0xD0, 0xA7, 0xCC, - 0x88, 0x04, 0xD1, 0x87, 0xCC, 0x88, 0x04, 0xD0, + 0x29, 0x43, 0x28, 0x5A, 0x29, 0x43, 0x28, 0x61, + 0x29, 0x43, 0x28, 0x62, 0x29, 0x43, 0x28, 0x63, + 0x29, 0x43, 0x28, 0x64, 0x29, 0x43, 0x28, 0x65, + 0x29, 0x43, 0x28, 0x66, 0x29, 0x43, 0x28, 0x67, + 0x29, 0x43, 0x28, 0x68, 0x29, 0x43, 0x28, 0x69, + 0x29, 0x43, 0x28, 0x6A, 0x29, 0x43, 0x28, 0x6B, + 0x29, 0x43, 0x28, 0x6C, 0x29, 0x43, 0x28, 0x6D, + 0x29, 0x43, 0x28, 0x6E, 0x29, 0x43, 0x28, 0x6F, // Bytes 680 - 6bf - 0xAB, 0xCC, 0x88, 0x04, 0xD1, 0x8B, 0xCC, 0x88, - 0x04, 0xD5, 0xA5, 0xD6, 0x82, 0x04, 0xD8, 0xA7, - 0xD9, 0x93, 0x04, 0xD8, 0xA7, 0xD9, 0x94, 0x04, - 0xD9, 0x88, 0xD9, 0x94, 0x04, 0xD8, 0xA7, 0xD9, - 0x95, 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0x04, 0xD8, - 0xA7, 0xD9, 0xB4, 0x04, 0xD9, 0x88, 0xD9, 0xB4, - 0x04, 0xDB, 0x87, 0xD9, 0xB4, 0x04, 0xD9, 0x8A, - 0xD9, 0xB4, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0x04, + 0x29, 0x43, 0x28, 0x70, 0x29, 0x43, 0x28, 0x71, + 0x29, 0x43, 0x28, 0x72, 0x29, 0x43, 0x28, 0x73, + 0x29, 0x43, 0x28, 0x74, 0x29, 0x43, 0x28, 0x75, + 0x29, 0x43, 0x28, 0x76, 0x29, 0x43, 0x28, 0x77, + 0x29, 0x43, 0x28, 0x78, 0x29, 0x43, 0x28, 0x79, + 0x29, 0x43, 0x28, 0x7A, 0x29, 0x43, 0x2E, 0x2E, + 0x2E, 0x43, 0x31, 0x30, 0x2E, 0x43, 0x31, 0x31, + 0x2E, 0x43, 0x31, 0x32, 0x2E, 0x43, 0x31, 0x33, // Bytes 6c0 - 6ff - 0xDB, 0x81, 0xD9, 0x94, 0x04, 0xDB, 0x92, 0xD9, - 0x94, 0x06, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, - 0x06, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x06, - 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, - 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, - 0x96, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0x97, - 0xE0, 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0x9C, 0xE0, - 0xA4, 0xBC, 0x06, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, + 0x2E, 0x43, 0x31, 0x34, 0x2E, 0x43, 0x31, 0x35, + 0x2E, 0x43, 0x31, 0x36, 0x2E, 0x43, 0x31, 0x37, + 0x2E, 0x43, 0x31, 0x38, 0x2E, 0x43, 0x31, 0x39, + 0x2E, 0x43, 0x32, 0x30, 0x2E, 0x43, 0x3A, 0x3A, + 0x3D, 0x43, 0x3D, 0x3D, 0x3D, 0x43, 0x43, 0x6F, + 0x2E, 0x43, 0x46, 0x41, 0x58, 0x43, 0x47, 0x48, + 0x7A, 0x43, 0x47, 0x50, 0x61, 0x43, 0x49, 0x49, + 0x49, 0x43, 0x4C, 0x54, 0x44, 0x43, 0x4C, 0xC2, // Bytes 700 - 73f - 0xBC, 0x06, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC, - 0x06, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0x06, - 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0x06, 0xE0, - 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0x06, 0xE0, 0xA7, - 0x87, 0xE0, 0xA7, 0x97, 0x06, 0xE0, 0xA6, 0xA1, - 0xE0, 0xA6, 0xBC, 0x06, 0xE0, 0xA6, 0xA2, 0xE0, - 0xA6, 0xBC, 0x06, 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, - 0xBC, 0x06, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, + 0xB7, 0x43, 0x4D, 0x48, 0x7A, 0x43, 0x4D, 0x50, + 0x61, 0x43, 0x4D, 0xCE, 0xA9, 0x43, 0x50, 0x50, + 0x4D, 0x43, 0x50, 0x50, 0x56, 0x43, 0x50, 0x54, + 0x45, 0x43, 0x54, 0x45, 0x4C, 0x43, 0x54, 0x48, + 0x7A, 0x43, 0x56, 0x49, 0x49, 0x43, 0x58, 0x49, + 0x49, 0x43, 0x61, 0x2F, 0x63, 0x43, 0x61, 0x2F, + 0x73, 0x43, 0x61, 0xCA, 0xBE, 0x43, 0x62, 0x61, + 0x72, 0x43, 0x63, 0x2F, 0x6F, 0x43, 0x63, 0x2F, // Bytes 740 - 77f - 0x06, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, 0x06, - 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, - 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xA8, - 0x9C, 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xA8, 0xAB, - 0xE0, 0xA8, 0xBC, 0x06, 0xE0, 0xAD, 0x87, 0xE0, - 0xAD, 0x96, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAC, - 0xBE, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x97, - 0x06, 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, 0x06, + 0x75, 0x43, 0x63, 0x61, 0x6C, 0x43, 0x63, 0x6D, + 0x32, 0x43, 0x63, 0x6D, 0x33, 0x43, 0x64, 0x6D, + 0x32, 0x43, 0x64, 0x6D, 0x33, 0x43, 0x65, 0x72, + 0x67, 0x43, 0x66, 0x66, 0x69, 0x43, 0x66, 0x66, + 0x6C, 0x43, 0x67, 0x61, 0x6C, 0x43, 0x68, 0x50, + 0x61, 0x43, 0x69, 0x69, 0x69, 0x43, 0x6B, 0x48, + 0x7A, 0x43, 0x6B, 0x50, 0x61, 0x43, 0x6B, 0x6D, + 0x32, 0x43, 0x6B, 0x6D, 0x33, 0x43, 0x6B, 0xCE, // Bytes 780 - 7bf - 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0x06, 0xE0, - 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0x06, 0xE0, 0xAF, - 0x86, 0xE0, 0xAE, 0xBE, 0x06, 0xE0, 0xAF, 0x87, - 0xE0, 0xAE, 0xBE, 0x06, 0xE0, 0xAF, 0x86, 0xE0, - 0xAF, 0x97, 0x06, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, - 0x96, 0x06, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, - 0x06, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x06, - 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x06, 0xE0, + 0xA9, 0x43, 0x6C, 0x6F, 0x67, 0x43, 0x6C, 0xC2, + 0xB7, 0x43, 0x6D, 0x69, 0x6C, 0x43, 0x6D, 0x6D, + 0x32, 0x43, 0x6D, 0x6D, 0x33, 0x43, 0x6D, 0x6F, + 0x6C, 0x43, 0x72, 0x61, 0x64, 0x43, 0x76, 0x69, + 0x69, 0x43, 0x78, 0x69, 0x69, 0x43, 0xC2, 0xB0, + 0x43, 0x43, 0xC2, 0xB0, 0x46, 0x43, 0xCA, 0xBC, + 0x6E, 0x43, 0xCE, 0xBC, 0x41, 0x43, 0xCE, 0xBC, + 0x46, 0x43, 0xCE, 0xBC, 0x56, 0x43, 0xCE, 0xBC, // Bytes 7c0 - 7ff - 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x09, 0xE0, 0xB3, - 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0x06, - 0xE0, 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0x06, 0xE0, - 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0x06, 0xE0, 0xB5, - 0x86, 0xE0, 0xB5, 0x97, 0x06, 0xE0, 0xB7, 0x99, - 0xE0, 0xB7, 0x8A, 0x06, 0xE0, 0xB7, 0x99, 0xE0, - 0xB7, 0x8F, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, - 0x8F, 0xE0, 0xB7, 0x8A, 0x06, 0xE0, 0xB7, 0x99, + 0x57, 0x43, 0xCE, 0xBC, 0x67, 0x43, 0xCE, 0xBC, + 0x6C, 0x43, 0xCE, 0xBC, 0x6D, 0x43, 0xCE, 0xBC, + 0x73, 0x43, 0xE0, 0xBC, 0x8B, 0x43, 0xE1, 0x83, + 0x9C, 0x43, 0xE1, 0x84, 0x80, 0x43, 0xE1, 0x84, + 0x81, 0x43, 0xE1, 0x84, 0x82, 0x43, 0xE1, 0x84, + 0x83, 0x43, 0xE1, 0x84, 0x84, 0x43, 0xE1, 0x84, + 0x85, 0x43, 0xE1, 0x84, 0x86, 0x43, 0xE1, 0x84, + 0x87, 0x43, 0xE1, 0x84, 0x88, 0x43, 0xE1, 0x84, // Bytes 800 - 83f - 0xE0, 0xB7, 0x9F, 0x06, 0xE0, 0xB9, 0x8D, 0xE0, - 0xB8, 0xB2, 0x06, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, - 0xB2, 0x06, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, - 0x06, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x03, - 0xE0, 0xBC, 0x8B, 0x06, 0xE0, 0xBD, 0x82, 0xE0, - 0xBE, 0xB7, 0x06, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, - 0xB7, 0x06, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7, - 0x06, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x06, + 0x89, 0x43, 0xE1, 0x84, 0x8A, 0x43, 0xE1, 0x84, + 0x8B, 0x43, 0xE1, 0x84, 0x8C, 0x43, 0xE1, 0x84, + 0x8D, 0x43, 0xE1, 0x84, 0x8E, 0x43, 0xE1, 0x84, + 0x8F, 0x43, 0xE1, 0x84, 0x90, 0x43, 0xE1, 0x84, + 0x91, 0x43, 0xE1, 0x84, 0x92, 0x43, 0xE1, 0x84, + 0x94, 0x43, 0xE1, 0x84, 0x95, 0x43, 0xE1, 0x84, + 0x9A, 0x43, 0xE1, 0x84, 0x9C, 0x43, 0xE1, 0x84, + 0x9D, 0x43, 0xE1, 0x84, 0x9E, 0x43, 0xE1, 0x84, // Bytes 840 - 87f - 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x06, 0xE0, - 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0x06, 0xE0, 0xBD, - 0xB1, 0xE0, 0xBD, 0xB2, 0x06, 0xE0, 0xBD, 0xB1, - 0xE0, 0xBD, 0xB4, 0x06, 0xE0, 0xBE, 0xB2, 0xE0, - 0xBE, 0x80, 0x09, 0xE0, 0xBE, 0xB2, 0xE0, 0xBD, - 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBE, 0xB3, - 0xE0, 0xBE, 0x80, 0x09, 0xE0, 0xBE, 0xB3, 0xE0, - 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBD, + 0xA0, 0x43, 0xE1, 0x84, 0xA1, 0x43, 0xE1, 0x84, + 0xA2, 0x43, 0xE1, 0x84, 0xA3, 0x43, 0xE1, 0x84, + 0xA7, 0x43, 0xE1, 0x84, 0xA9, 0x43, 0xE1, 0x84, + 0xAB, 0x43, 0xE1, 0x84, 0xAC, 0x43, 0xE1, 0x84, + 0xAD, 0x43, 0xE1, 0x84, 0xAE, 0x43, 0xE1, 0x84, + 0xAF, 0x43, 0xE1, 0x84, 0xB2, 0x43, 0xE1, 0x84, + 0xB6, 0x43, 0xE1, 0x85, 0x80, 0x43, 0xE1, 0x85, + 0x87, 0x43, 0xE1, 0x85, 0x8C, 0x43, 0xE1, 0x85, // Bytes 880 - 8bf - 0xB1, 0xE0, 0xBE, 0x80, 0x06, 0xE0, 0xBE, 0x92, - 0xE0, 0xBE, 0xB7, 0x06, 0xE0, 0xBE, 0x9C, 0xE0, - 0xBE, 0xB7, 0x06, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE, - 0xB7, 0x06, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, - 0x06, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x06, - 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x06, 0xE1, - 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0x03, 0xE1, 0x83, - 0x9C, 0x06, 0xE1, 0xAC, 0x85, 0xE1, 0xAC, 0xB5, + 0x97, 0x43, 0xE1, 0x85, 0x98, 0x43, 0xE1, 0x85, + 0x99, 0x43, 0xE1, 0x85, 0xA0, 0x43, 0xE1, 0x85, + 0xA1, 0x43, 0xE1, 0x85, 0xA2, 0x43, 0xE1, 0x85, + 0xA3, 0x43, 0xE1, 0x85, 0xA4, 0x43, 0xE1, 0x85, + 0xA5, 0x43, 0xE1, 0x85, 0xA6, 0x43, 0xE1, 0x85, + 0xA7, 0x43, 0xE1, 0x85, 0xA8, 0x43, 0xE1, 0x85, + 0xA9, 0x43, 0xE1, 0x85, 0xAA, 0x43, 0xE1, 0x85, + 0xAB, 0x43, 0xE1, 0x85, 0xAC, 0x43, 0xE1, 0x85, // Bytes 8c0 - 8ff - 0x06, 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x06, - 0xE1, 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, - 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, - 0x8D, 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0x91, - 0xE1, 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0xBA, 0xE1, - 0xAC, 0xB5, 0x06, 0xE1, 0xAC, 0xBC, 0xE1, 0xAC, - 0xB5, 0x06, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, - 0x06, 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x06, + 0xAD, 0x43, 0xE1, 0x85, 0xAE, 0x43, 0xE1, 0x85, + 0xAF, 0x43, 0xE1, 0x85, 0xB0, 0x43, 0xE1, 0x85, + 0xB1, 0x43, 0xE1, 0x85, 0xB2, 0x43, 0xE1, 0x85, + 0xB3, 0x43, 0xE1, 0x85, 0xB4, 0x43, 0xE1, 0x85, + 0xB5, 0x43, 0xE1, 0x86, 0x84, 0x43, 0xE1, 0x86, + 0x85, 0x43, 0xE1, 0x86, 0x88, 0x43, 0xE1, 0x86, + 0x91, 0x43, 0xE1, 0x86, 0x92, 0x43, 0xE1, 0x86, + 0x94, 0x43, 0xE1, 0x86, 0x9E, 0x43, 0xE1, 0x86, // Bytes 900 - 93f - 0xE1, 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x01, 0x41, - 0x02, 0xC3, 0x86, 0x01, 0x42, 0x01, 0x44, 0x01, - 0x45, 0x02, 0xC6, 0x8E, 0x01, 0x47, 0x01, 0x48, - 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4B, 0x01, 0x4C, - 0x01, 0x4D, 0x01, 0x4E, 0x01, 0x4F, 0x02, 0xC8, - 0xA2, 0x01, 0x50, 0x01, 0x52, 0x01, 0x54, 0x01, - 0x55, 0x01, 0x57, 0x02, 0xC9, 0x90, 0x02, 0xC9, - 0x91, 0x03, 0xE1, 0xB4, 0x82, 0x01, 0x62, 0x01, + 0xA1, 0x43, 0xE1, 0x86, 0xAA, 0x43, 0xE1, 0x86, + 0xAC, 0x43, 0xE1, 0x86, 0xAD, 0x43, 0xE1, 0x86, + 0xB0, 0x43, 0xE1, 0x86, 0xB1, 0x43, 0xE1, 0x86, + 0xB2, 0x43, 0xE1, 0x86, 0xB3, 0x43, 0xE1, 0x86, + 0xB4, 0x43, 0xE1, 0x86, 0xB5, 0x43, 0xE1, 0x87, + 0x87, 0x43, 0xE1, 0x87, 0x88, 0x43, 0xE1, 0x87, + 0x8C, 0x43, 0xE1, 0x87, 0x8E, 0x43, 0xE1, 0x87, + 0x93, 0x43, 0xE1, 0x87, 0x97, 0x43, 0xE1, 0x87, // Bytes 940 - 97f - 0x64, 0x01, 0x65, 0x02, 0xC9, 0x99, 0x02, 0xC9, - 0x9B, 0x02, 0xC9, 0x9C, 0x01, 0x67, 0x01, 0x6B, - 0x01, 0x6D, 0x02, 0xC5, 0x8B, 0x02, 0xC9, 0x94, - 0x03, 0xE1, 0xB4, 0x96, 0x03, 0xE1, 0xB4, 0x97, - 0x01, 0x70, 0x01, 0x74, 0x01, 0x75, 0x03, 0xE1, - 0xB4, 0x9D, 0x02, 0xC9, 0xAF, 0x01, 0x76, 0x03, - 0xE1, 0xB4, 0xA5, 0x02, 0xCE, 0xB3, 0x02, 0xCE, - 0xB4, 0x02, 0xCF, 0x87, 0x01, 0x69, 0x02, 0xD0, + 0x99, 0x43, 0xE1, 0x87, 0x9D, 0x43, 0xE1, 0x87, + 0x9F, 0x43, 0xE1, 0x87, 0xB1, 0x43, 0xE1, 0x87, + 0xB2, 0x43, 0xE1, 0xB4, 0x82, 0x43, 0xE1, 0xB4, + 0x96, 0x43, 0xE1, 0xB4, 0x97, 0x43, 0xE1, 0xB4, + 0x9C, 0x43, 0xE1, 0xB4, 0x9D, 0x43, 0xE1, 0xB4, + 0xA5, 0x43, 0xE1, 0xB5, 0xBB, 0x43, 0xE1, 0xB6, + 0x85, 0x43, 0xE2, 0x80, 0x82, 0x43, 0xE2, 0x80, + 0x83, 0x43, 0xE2, 0x80, 0x90, 0x43, 0xE2, 0x80, // Bytes 980 - 9bf - 0xBD, 0x02, 0xC9, 0x92, 0x01, 0x63, 0x02, 0xC9, - 0x95, 0x02, 0xC3, 0xB0, 0x01, 0x66, 0x02, 0xC9, - 0x9F, 0x02, 0xC9, 0xA1, 0x02, 0xC9, 0xA5, 0x02, - 0xC9, 0xA8, 0x02, 0xC9, 0xA9, 0x02, 0xC9, 0xAA, - 0x03, 0xE1, 0xB5, 0xBB, 0x02, 0xCA, 0x9D, 0x02, - 0xC9, 0xAD, 0x03, 0xE1, 0xB6, 0x85, 0x02, 0xCA, - 0x9F, 0x02, 0xC9, 0xB1, 0x02, 0xC9, 0xB0, 0x02, - 0xC9, 0xB2, 0x02, 0xC9, 0xB3, 0x02, 0xC9, 0xB4, + 0x93, 0x43, 0xE2, 0x80, 0x94, 0x43, 0xE2, 0x82, + 0xA9, 0x43, 0xE2, 0x86, 0x90, 0x43, 0xE2, 0x86, + 0x91, 0x43, 0xE2, 0x86, 0x92, 0x43, 0xE2, 0x86, + 0x93, 0x43, 0xE2, 0x88, 0x82, 0x43, 0xE2, 0x88, + 0x87, 0x43, 0xE2, 0x88, 0x91, 0x43, 0xE2, 0x88, + 0x92, 0x43, 0xE2, 0x94, 0x82, 0x43, 0xE2, 0x96, + 0xA0, 0x43, 0xE2, 0x97, 0x8B, 0x43, 0xE2, 0xA6, + 0x85, 0x43, 0xE2, 0xA6, 0x86, 0x43, 0xE2, 0xB5, // Bytes 9c0 - 9ff - 0x02, 0xC9, 0xB5, 0x02, 0xC9, 0xB8, 0x02, 0xCA, - 0x82, 0x02, 0xCA, 0x83, 0x02, 0xC6, 0xAB, 0x02, - 0xCA, 0x89, 0x02, 0xCA, 0x8A, 0x03, 0xE1, 0xB4, - 0x9C, 0x02, 0xCA, 0x8B, 0x02, 0xCA, 0x8C, 0x01, - 0x7A, 0x02, 0xCA, 0x90, 0x02, 0xCA, 0x91, 0x02, - 0xCA, 0x92, 0x03, 0x41, 0xCC, 0xA5, 0x03, 0x61, - 0xCC, 0xA5, 0x03, 0x42, 0xCC, 0x87, 0x03, 0x62, - 0xCC, 0x87, 0x03, 0x42, 0xCC, 0xA3, 0x03, 0x62, + 0xA1, 0x43, 0xE3, 0x80, 0x81, 0x43, 0xE3, 0x80, + 0x82, 0x43, 0xE3, 0x80, 0x88, 0x43, 0xE3, 0x80, + 0x89, 0x43, 0xE3, 0x80, 0x8A, 0x43, 0xE3, 0x80, + 0x8B, 0x43, 0xE3, 0x80, 0x8C, 0x43, 0xE3, 0x80, + 0x8D, 0x43, 0xE3, 0x80, 0x8E, 0x43, 0xE3, 0x80, + 0x8F, 0x43, 0xE3, 0x80, 0x90, 0x43, 0xE3, 0x80, + 0x91, 0x43, 0xE3, 0x80, 0x92, 0x43, 0xE3, 0x80, + 0x94, 0x43, 0xE3, 0x80, 0x95, 0x43, 0xE3, 0x80, // Bytes a00 - a3f - 0xCC, 0xA3, 0x03, 0x42, 0xCC, 0xB1, 0x03, 0x62, - 0xCC, 0xB1, 0x05, 0x43, 0xCC, 0xA7, 0xCC, 0x81, - 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81, 0x03, 0x44, - 0xCC, 0x87, 0x03, 0x64, 0xCC, 0x87, 0x03, 0x44, - 0xCC, 0xA3, 0x03, 0x64, 0xCC, 0xA3, 0x03, 0x44, - 0xCC, 0xB1, 0x03, 0x64, 0xCC, 0xB1, 0x03, 0x44, - 0xCC, 0xA7, 0x03, 0x64, 0xCC, 0xA7, 0x03, 0x44, - 0xCC, 0xAD, 0x03, 0x64, 0xCC, 0xAD, 0x05, 0x45, + 0x96, 0x43, 0xE3, 0x80, 0x97, 0x43, 0xE3, 0x82, + 0xA1, 0x43, 0xE3, 0x82, 0xA2, 0x43, 0xE3, 0x82, + 0xA3, 0x43, 0xE3, 0x82, 0xA4, 0x43, 0xE3, 0x82, + 0xA5, 0x43, 0xE3, 0x82, 0xA6, 0x43, 0xE3, 0x82, + 0xA7, 0x43, 0xE3, 0x82, 0xA8, 0x43, 0xE3, 0x82, + 0xA9, 0x43, 0xE3, 0x82, 0xAA, 0x43, 0xE3, 0x82, + 0xAB, 0x43, 0xE3, 0x82, 0xAD, 0x43, 0xE3, 0x82, + 0xAF, 0x43, 0xE3, 0x82, 0xB1, 0x43, 0xE3, 0x82, // Bytes a40 - a7f - 0xCC, 0x84, 0xCC, 0x80, 0x05, 0x65, 0xCC, 0x84, - 0xCC, 0x80, 0x05, 0x45, 0xCC, 0x84, 0xCC, 0x81, - 0x05, 0x65, 0xCC, 0x84, 0xCC, 0x81, 0x03, 0x45, - 0xCC, 0xAD, 0x03, 0x65, 0xCC, 0xAD, 0x03, 0x45, - 0xCC, 0xB0, 0x03, 0x65, 0xCC, 0xB0, 0x05, 0x45, - 0xCC, 0xA7, 0xCC, 0x86, 0x05, 0x65, 0xCC, 0xA7, - 0xCC, 0x86, 0x03, 0x46, 0xCC, 0x87, 0x03, 0x66, - 0xCC, 0x87, 0x03, 0x47, 0xCC, 0x84, 0x03, 0x67, + 0xB3, 0x43, 0xE3, 0x82, 0xB5, 0x43, 0xE3, 0x82, + 0xB7, 0x43, 0xE3, 0x82, 0xB9, 0x43, 0xE3, 0x82, + 0xBB, 0x43, 0xE3, 0x82, 0xBD, 0x43, 0xE3, 0x82, + 0xBF, 0x43, 0xE3, 0x83, 0x81, 0x43, 0xE3, 0x83, + 0x83, 0x43, 0xE3, 0x83, 0x84, 0x43, 0xE3, 0x83, + 0x86, 0x43, 0xE3, 0x83, 0x88, 0x43, 0xE3, 0x83, + 0x8A, 0x43, 0xE3, 0x83, 0x8B, 0x43, 0xE3, 0x83, + 0x8C, 0x43, 0xE3, 0x83, 0x8D, 0x43, 0xE3, 0x83, // Bytes a80 - abf - 0xCC, 0x84, 0x03, 0x48, 0xCC, 0x87, 0x03, 0x68, - 0xCC, 0x87, 0x03, 0x48, 0xCC, 0xA3, 0x03, 0x68, - 0xCC, 0xA3, 0x03, 0x48, 0xCC, 0x88, 0x03, 0x68, - 0xCC, 0x88, 0x03, 0x48, 0xCC, 0xA7, 0x03, 0x68, - 0xCC, 0xA7, 0x03, 0x48, 0xCC, 0xAE, 0x03, 0x68, - 0xCC, 0xAE, 0x03, 0x49, 0xCC, 0xB0, 0x03, 0x69, - 0xCC, 0xB0, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81, - 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0x03, 0x4B, + 0x8E, 0x43, 0xE3, 0x83, 0x8F, 0x43, 0xE3, 0x83, + 0x92, 0x43, 0xE3, 0x83, 0x95, 0x43, 0xE3, 0x83, + 0x98, 0x43, 0xE3, 0x83, 0x9B, 0x43, 0xE3, 0x83, + 0x9E, 0x43, 0xE3, 0x83, 0x9F, 0x43, 0xE3, 0x83, + 0xA0, 0x43, 0xE3, 0x83, 0xA1, 0x43, 0xE3, 0x83, + 0xA2, 0x43, 0xE3, 0x83, 0xA3, 0x43, 0xE3, 0x83, + 0xA4, 0x43, 0xE3, 0x83, 0xA5, 0x43, 0xE3, 0x83, + 0xA6, 0x43, 0xE3, 0x83, 0xA7, 0x43, 0xE3, 0x83, // Bytes ac0 - aff - 0xCC, 0x81, 0x03, 0x6B, 0xCC, 0x81, 0x03, 0x4B, - 0xCC, 0xA3, 0x03, 0x6B, 0xCC, 0xA3, 0x03, 0x4B, - 0xCC, 0xB1, 0x03, 0x6B, 0xCC, 0xB1, 0x03, 0x4C, - 0xCC, 0xA3, 0x03, 0x6C, 0xCC, 0xA3, 0x05, 0x4C, - 0xCC, 0xA3, 0xCC, 0x84, 0x05, 0x6C, 0xCC, 0xA3, - 0xCC, 0x84, 0x03, 0x4C, 0xCC, 0xB1, 0x03, 0x6C, - 0xCC, 0xB1, 0x03, 0x4C, 0xCC, 0xAD, 0x03, 0x6C, - 0xCC, 0xAD, 0x03, 0x4D, 0xCC, 0x81, 0x03, 0x6D, + 0xA8, 0x43, 0xE3, 0x83, 0xA9, 0x43, 0xE3, 0x83, + 0xAA, 0x43, 0xE3, 0x83, 0xAB, 0x43, 0xE3, 0x83, + 0xAC, 0x43, 0xE3, 0x83, 0xAD, 0x43, 0xE3, 0x83, + 0xAF, 0x43, 0xE3, 0x83, 0xB0, 0x43, 0xE3, 0x83, + 0xB1, 0x43, 0xE3, 0x83, 0xB2, 0x43, 0xE3, 0x83, + 0xB3, 0x43, 0xE3, 0x83, 0xBB, 0x43, 0xE3, 0x83, + 0xBC, 0x43, 0xE3, 0x92, 0x9E, 0x43, 0xE3, 0x92, + 0xB9, 0x43, 0xE3, 0x92, 0xBB, 0x43, 0xE3, 0x93, // Bytes b00 - b3f - 0xCC, 0x81, 0x03, 0x4D, 0xCC, 0x87, 0x03, 0x6D, - 0xCC, 0x87, 0x03, 0x4D, 0xCC, 0xA3, 0x03, 0x6D, - 0xCC, 0xA3, 0x03, 0x4E, 0xCC, 0x87, 0x03, 0x6E, - 0xCC, 0x87, 0x03, 0x4E, 0xCC, 0xA3, 0x03, 0x6E, - 0xCC, 0xA3, 0x03, 0x4E, 0xCC, 0xB1, 0x03, 0x6E, - 0xCC, 0xB1, 0x03, 0x4E, 0xCC, 0xAD, 0x03, 0x6E, - 0xCC, 0xAD, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x81, - 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x81, 0x05, 0x4F, + 0x9F, 0x43, 0xE3, 0x94, 0x95, 0x43, 0xE3, 0x9B, + 0xAE, 0x43, 0xE3, 0x9B, 0xBC, 0x43, 0xE3, 0x9E, + 0x81, 0x43, 0xE3, 0xA0, 0xAF, 0x43, 0xE3, 0xA1, + 0xA2, 0x43, 0xE3, 0xA1, 0xBC, 0x43, 0xE3, 0xA3, + 0x87, 0x43, 0xE3, 0xA3, 0xA3, 0x43, 0xE3, 0xA4, + 0x9C, 0x43, 0xE3, 0xA4, 0xBA, 0x43, 0xE3, 0xA8, + 0xAE, 0x43, 0xE3, 0xA9, 0xAC, 0x43, 0xE3, 0xAB, + 0xA4, 0x43, 0xE3, 0xAC, 0x88, 0x43, 0xE3, 0xAC, // Bytes b40 - b7f - 0xCC, 0x83, 0xCC, 0x88, 0x05, 0x6F, 0xCC, 0x83, - 0xCC, 0x88, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, - 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0x05, 0x4F, - 0xCC, 0x84, 0xCC, 0x81, 0x05, 0x6F, 0xCC, 0x84, - 0xCC, 0x81, 0x03, 0x50, 0xCC, 0x81, 0x03, 0x70, - 0xCC, 0x81, 0x03, 0x50, 0xCC, 0x87, 0x03, 0x70, - 0xCC, 0x87, 0x03, 0x52, 0xCC, 0x87, 0x03, 0x72, - 0xCC, 0x87, 0x03, 0x52, 0xCC, 0xA3, 0x03, 0x72, + 0x99, 0x43, 0xE3, 0xAD, 0x89, 0x43, 0xE3, 0xAE, + 0x9D, 0x43, 0xE3, 0xB0, 0x98, 0x43, 0xE3, 0xB1, + 0x8E, 0x43, 0xE3, 0xB4, 0xB3, 0x43, 0xE3, 0xB6, + 0x96, 0x43, 0xE3, 0xBA, 0xAC, 0x43, 0xE3, 0xBA, + 0xB8, 0x43, 0xE3, 0xBC, 0x9B, 0x43, 0xE3, 0xBF, + 0xBC, 0x43, 0xE4, 0x80, 0x88, 0x43, 0xE4, 0x80, + 0x98, 0x43, 0xE4, 0x80, 0xB9, 0x43, 0xE4, 0x81, + 0x86, 0x43, 0xE4, 0x82, 0x96, 0x43, 0xE4, 0x83, // Bytes b80 - bbf - 0xCC, 0xA3, 0x05, 0x52, 0xCC, 0xA3, 0xCC, 0x84, - 0x05, 0x72, 0xCC, 0xA3, 0xCC, 0x84, 0x03, 0x52, - 0xCC, 0xB1, 0x03, 0x72, 0xCC, 0xB1, 0x03, 0x53, - 0xCC, 0x87, 0x03, 0x73, 0xCC, 0x87, 0x03, 0x53, - 0xCC, 0xA3, 0x03, 0x73, 0xCC, 0xA3, 0x05, 0x53, - 0xCC, 0x81, 0xCC, 0x87, 0x05, 0x73, 0xCC, 0x81, - 0xCC, 0x87, 0x05, 0x53, 0xCC, 0x8C, 0xCC, 0x87, - 0x05, 0x73, 0xCC, 0x8C, 0xCC, 0x87, 0x05, 0x53, + 0xA3, 0x43, 0xE4, 0x84, 0xAF, 0x43, 0xE4, 0x88, + 0x82, 0x43, 0xE4, 0x88, 0xA7, 0x43, 0xE4, 0x8A, + 0xA0, 0x43, 0xE4, 0x8C, 0x81, 0x43, 0xE4, 0x8C, + 0xB4, 0x43, 0xE4, 0x8D, 0x99, 0x43, 0xE4, 0x8F, + 0x95, 0x43, 0xE4, 0x8F, 0x99, 0x43, 0xE4, 0x90, + 0x8B, 0x43, 0xE4, 0x91, 0xAB, 0x43, 0xE4, 0x94, + 0xAB, 0x43, 0xE4, 0x95, 0x9D, 0x43, 0xE4, 0x95, + 0xA1, 0x43, 0xE4, 0x95, 0xAB, 0x43, 0xE4, 0x97, // Bytes bc0 - bff - 0xCC, 0xA3, 0xCC, 0x87, 0x05, 0x73, 0xCC, 0xA3, - 0xCC, 0x87, 0x03, 0x54, 0xCC, 0x87, 0x03, 0x74, - 0xCC, 0x87, 0x03, 0x54, 0xCC, 0xA3, 0x03, 0x74, - 0xCC, 0xA3, 0x03, 0x54, 0xCC, 0xB1, 0x03, 0x74, - 0xCC, 0xB1, 0x03, 0x54, 0xCC, 0xAD, 0x03, 0x74, - 0xCC, 0xAD, 0x03, 0x55, 0xCC, 0xA4, 0x03, 0x75, - 0xCC, 0xA4, 0x03, 0x55, 0xCC, 0xB0, 0x03, 0x75, - 0xCC, 0xB0, 0x03, 0x55, 0xCC, 0xAD, 0x03, 0x75, + 0x97, 0x43, 0xE4, 0x97, 0xB9, 0x43, 0xE4, 0x98, + 0xB5, 0x43, 0xE4, 0x9A, 0xBE, 0x43, 0xE4, 0x9B, + 0x87, 0x43, 0xE4, 0xA6, 0x95, 0x43, 0xE4, 0xA7, + 0xA6, 0x43, 0xE4, 0xA9, 0xAE, 0x43, 0xE4, 0xA9, + 0xB6, 0x43, 0xE4, 0xAA, 0xB2, 0x43, 0xE4, 0xAC, + 0xB3, 0x43, 0xE4, 0xAF, 0x8E, 0x43, 0xE4, 0xB3, + 0x8E, 0x43, 0xE4, 0xB3, 0xAD, 0x43, 0xE4, 0xB3, + 0xB8, 0x43, 0xE4, 0xB5, 0x96, 0x43, 0xE4, 0xB8, // Bytes c00 - c3f - 0xCC, 0xAD, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81, - 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0x05, 0x55, - 0xCC, 0x84, 0xCC, 0x88, 0x05, 0x75, 0xCC, 0x84, - 0xCC, 0x88, 0x03, 0x56, 0xCC, 0x83, 0x03, 0x76, - 0xCC, 0x83, 0x03, 0x56, 0xCC, 0xA3, 0x03, 0x76, - 0xCC, 0xA3, 0x03, 0x57, 0xCC, 0x80, 0x03, 0x77, - 0xCC, 0x80, 0x03, 0x57, 0xCC, 0x81, 0x03, 0x77, - 0xCC, 0x81, 0x03, 0x57, 0xCC, 0x88, 0x03, 0x77, + 0x80, 0x43, 0xE4, 0xB8, 0x81, 0x43, 0xE4, 0xB8, + 0x83, 0x43, 0xE4, 0xB8, 0x89, 0x43, 0xE4, 0xB8, + 0x8A, 0x43, 0xE4, 0xB8, 0x8B, 0x43, 0xE4, 0xB8, + 0x8D, 0x43, 0xE4, 0xB8, 0x99, 0x43, 0xE4, 0xB8, + 0xA6, 0x43, 0xE4, 0xB8, 0xA8, 0x43, 0xE4, 0xB8, + 0xAD, 0x43, 0xE4, 0xB8, 0xB2, 0x43, 0xE4, 0xB8, + 0xB6, 0x43, 0xE4, 0xB8, 0xB8, 0x43, 0xE4, 0xB8, + 0xB9, 0x43, 0xE4, 0xB8, 0xBD, 0x43, 0xE4, 0xB8, // Bytes c40 - c7f - 0xCC, 0x88, 0x03, 0x57, 0xCC, 0x87, 0x03, 0x77, - 0xCC, 0x87, 0x03, 0x57, 0xCC, 0xA3, 0x03, 0x77, - 0xCC, 0xA3, 0x03, 0x58, 0xCC, 0x87, 0x03, 0x78, - 0xCC, 0x87, 0x03, 0x58, 0xCC, 0x88, 0x03, 0x78, - 0xCC, 0x88, 0x03, 0x59, 0xCC, 0x87, 0x03, 0x79, - 0xCC, 0x87, 0x03, 0x5A, 0xCC, 0x82, 0x03, 0x7A, - 0xCC, 0x82, 0x03, 0x5A, 0xCC, 0xA3, 0x03, 0x7A, - 0xCC, 0xA3, 0x03, 0x5A, 0xCC, 0xB1, 0x03, 0x7A, + 0xBF, 0x43, 0xE4, 0xB9, 0x81, 0x43, 0xE4, 0xB9, + 0x99, 0x43, 0xE4, 0xB9, 0x9D, 0x43, 0xE4, 0xBA, + 0x82, 0x43, 0xE4, 0xBA, 0x85, 0x43, 0xE4, 0xBA, + 0x86, 0x43, 0xE4, 0xBA, 0x8C, 0x43, 0xE4, 0xBA, + 0x94, 0x43, 0xE4, 0xBA, 0xA0, 0x43, 0xE4, 0xBA, + 0xA4, 0x43, 0xE4, 0xBA, 0xAE, 0x43, 0xE4, 0xBA, + 0xBA, 0x43, 0xE4, 0xBB, 0x80, 0x43, 0xE4, 0xBB, + 0x8C, 0x43, 0xE4, 0xBB, 0xA4, 0x43, 0xE4, 0xBC, // Bytes c80 - cbf - 0xCC, 0xB1, 0x03, 0x68, 0xCC, 0xB1, 0x03, 0x74, - 0xCC, 0x88, 0x03, 0x77, 0xCC, 0x8A, 0x03, 0x79, - 0xCC, 0x8A, 0x03, 0x61, 0xCA, 0xBE, 0x04, 0xC5, - 0xBF, 0xCC, 0x87, 0x03, 0x41, 0xCC, 0xA3, 0x03, - 0x61, 0xCC, 0xA3, 0x03, 0x41, 0xCC, 0x89, 0x03, - 0x61, 0xCC, 0x89, 0x05, 0x41, 0xCC, 0x82, 0xCC, - 0x81, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x81, 0x05, - 0x41, 0xCC, 0x82, 0xCC, 0x80, 0x05, 0x61, 0xCC, + 0x81, 0x43, 0xE4, 0xBC, 0x91, 0x43, 0xE4, 0xBD, + 0xA0, 0x43, 0xE4, 0xBE, 0x80, 0x43, 0xE4, 0xBE, + 0x86, 0x43, 0xE4, 0xBE, 0x8B, 0x43, 0xE4, 0xBE, + 0xAE, 0x43, 0xE4, 0xBE, 0xBB, 0x43, 0xE4, 0xBE, + 0xBF, 0x43, 0xE5, 0x80, 0x82, 0x43, 0xE5, 0x80, + 0xAB, 0x43, 0xE5, 0x81, 0xBA, 0x43, 0xE5, 0x82, + 0x99, 0x43, 0xE5, 0x83, 0x8F, 0x43, 0xE5, 0x83, + 0x9A, 0x43, 0xE5, 0x83, 0xA7, 0x43, 0xE5, 0x84, // Bytes cc0 - cff - 0x82, 0xCC, 0x80, 0x05, 0x41, 0xCC, 0x82, 0xCC, - 0x89, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x89, 0x05, - 0x41, 0xCC, 0x82, 0xCC, 0x83, 0x05, 0x61, 0xCC, - 0x82, 0xCC, 0x83, 0x05, 0x41, 0xCC, 0xA3, 0xCC, - 0x82, 0x05, 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0x05, - 0x41, 0xCC, 0x86, 0xCC, 0x81, 0x05, 0x61, 0xCC, - 0x86, 0xCC, 0x81, 0x05, 0x41, 0xCC, 0x86, 0xCC, - 0x80, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x80, 0x05, + 0xAA, 0x43, 0xE5, 0x84, 0xBF, 0x43, 0xE5, 0x85, + 0x80, 0x43, 0xE5, 0x85, 0x85, 0x43, 0xE5, 0x85, + 0x8D, 0x43, 0xE5, 0x85, 0x94, 0x43, 0xE5, 0x85, + 0xA4, 0x43, 0xE5, 0x85, 0xA5, 0x43, 0xE5, 0x85, + 0xA7, 0x43, 0xE5, 0x85, 0xA8, 0x43, 0xE5, 0x85, + 0xA9, 0x43, 0xE5, 0x85, 0xAB, 0x43, 0xE5, 0x85, + 0xAD, 0x43, 0xE5, 0x85, 0xB7, 0x43, 0xE5, 0x86, + 0x80, 0x43, 0xE5, 0x86, 0x82, 0x43, 0xE5, 0x86, // Bytes d00 - d3f - 0x41, 0xCC, 0x86, 0xCC, 0x89, 0x05, 0x61, 0xCC, - 0x86, 0xCC, 0x89, 0x05, 0x41, 0xCC, 0x86, 0xCC, - 0x83, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0x05, - 0x41, 0xCC, 0xA3, 0xCC, 0x86, 0x05, 0x61, 0xCC, - 0xA3, 0xCC, 0x86, 0x03, 0x45, 0xCC, 0xA3, 0x03, - 0x65, 0xCC, 0xA3, 0x03, 0x45, 0xCC, 0x89, 0x03, - 0x65, 0xCC, 0x89, 0x03, 0x45, 0xCC, 0x83, 0x03, - 0x65, 0xCC, 0x83, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x8D, 0x43, 0xE5, 0x86, 0x92, 0x43, 0xE5, 0x86, + 0x95, 0x43, 0xE5, 0x86, 0x96, 0x43, 0xE5, 0x86, + 0x97, 0x43, 0xE5, 0x86, 0x99, 0x43, 0xE5, 0x86, + 0xA4, 0x43, 0xE5, 0x86, 0xAB, 0x43, 0xE5, 0x86, + 0xAC, 0x43, 0xE5, 0x86, 0xB5, 0x43, 0xE5, 0x86, + 0xB7, 0x43, 0xE5, 0x87, 0x89, 0x43, 0xE5, 0x87, + 0x8C, 0x43, 0xE5, 0x87, 0x9C, 0x43, 0xE5, 0x87, + 0x9E, 0x43, 0xE5, 0x87, 0xA0, 0x43, 0xE5, 0x87, // Bytes d40 - d7f - 0x81, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0x05, - 0x45, 0xCC, 0x82, 0xCC, 0x80, 0x05, 0x65, 0xCC, - 0x82, 0xCC, 0x80, 0x05, 0x45, 0xCC, 0x82, 0xCC, - 0x89, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x89, 0x05, - 0x45, 0xCC, 0x82, 0xCC, 0x83, 0x05, 0x65, 0xCC, - 0x82, 0xCC, 0x83, 0x05, 0x45, 0xCC, 0xA3, 0xCC, - 0x82, 0x05, 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0x03, - 0x49, 0xCC, 0x89, 0x03, 0x69, 0xCC, 0x89, 0x03, + 0xB5, 0x43, 0xE5, 0x88, 0x80, 0x43, 0xE5, 0x88, + 0x83, 0x43, 0xE5, 0x88, 0x87, 0x43, 0xE5, 0x88, + 0x97, 0x43, 0xE5, 0x88, 0x9D, 0x43, 0xE5, 0x88, + 0xA9, 0x43, 0xE5, 0x88, 0xBA, 0x43, 0xE5, 0x88, + 0xBB, 0x43, 0xE5, 0x89, 0x86, 0x43, 0xE5, 0x89, + 0x8D, 0x43, 0xE5, 0x89, 0xB2, 0x43, 0xE5, 0x89, + 0xB7, 0x43, 0xE5, 0x8A, 0x89, 0x43, 0xE5, 0x8A, + 0x9B, 0x43, 0xE5, 0x8A, 0xA3, 0x43, 0xE5, 0x8A, // Bytes d80 - dbf - 0x49, 0xCC, 0xA3, 0x03, 0x69, 0xCC, 0xA3, 0x03, - 0x4F, 0xCC, 0xA3, 0x03, 0x6F, 0xCC, 0xA3, 0x03, - 0x4F, 0xCC, 0x89, 0x03, 0x6F, 0xCC, 0x89, 0x05, - 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0x05, 0x6F, 0xCC, - 0x82, 0xCC, 0x81, 0x05, 0x4F, 0xCC, 0x82, 0xCC, - 0x80, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0x05, - 0x4F, 0xCC, 0x82, 0xCC, 0x89, 0x05, 0x6F, 0xCC, - 0x82, 0xCC, 0x89, 0x05, 0x4F, 0xCC, 0x82, 0xCC, + 0xB3, 0x43, 0xE5, 0x8A, 0xB4, 0x43, 0xE5, 0x8B, + 0x87, 0x43, 0xE5, 0x8B, 0x89, 0x43, 0xE5, 0x8B, + 0x92, 0x43, 0xE5, 0x8B, 0x9E, 0x43, 0xE5, 0x8B, + 0xA4, 0x43, 0xE5, 0x8B, 0xB5, 0x43, 0xE5, 0x8B, + 0xB9, 0x43, 0xE5, 0x8B, 0xBA, 0x43, 0xE5, 0x8C, + 0x85, 0x43, 0xE5, 0x8C, 0x86, 0x43, 0xE5, 0x8C, + 0x95, 0x43, 0xE5, 0x8C, 0x97, 0x43, 0xE5, 0x8C, + 0x9A, 0x43, 0xE5, 0x8C, 0xB8, 0x43, 0xE5, 0x8C, // Bytes dc0 - dff - 0x83, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0x05, - 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0x05, 0x6F, 0xCC, - 0xA3, 0xCC, 0x82, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, - 0x81, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0x05, - 0x4F, 0xCC, 0x9B, 0xCC, 0x80, 0x05, 0x6F, 0xCC, - 0x9B, 0xCC, 0x80, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, - 0x89, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0x05, - 0x4F, 0xCC, 0x9B, 0xCC, 0x83, 0x05, 0x6F, 0xCC, + 0xBB, 0x43, 0xE5, 0x8C, 0xBF, 0x43, 0xE5, 0x8D, + 0x81, 0x43, 0xE5, 0x8D, 0x84, 0x43, 0xE5, 0x8D, + 0x85, 0x43, 0xE5, 0x8D, 0x89, 0x43, 0xE5, 0x8D, + 0x91, 0x43, 0xE5, 0x8D, 0x94, 0x43, 0xE5, 0x8D, + 0x9A, 0x43, 0xE5, 0x8D, 0x9C, 0x43, 0xE5, 0x8D, + 0xA9, 0x43, 0xE5, 0x8D, 0xB0, 0x43, 0xE5, 0x8D, + 0xB3, 0x43, 0xE5, 0x8D, 0xB5, 0x43, 0xE5, 0x8D, + 0xBD, 0x43, 0xE5, 0x8D, 0xBF, 0x43, 0xE5, 0x8E, // Bytes e00 - e3f - 0x9B, 0xCC, 0x83, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, - 0xA3, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0x03, - 0x55, 0xCC, 0xA3, 0x03, 0x75, 0xCC, 0xA3, 0x03, - 0x55, 0xCC, 0x89, 0x03, 0x75, 0xCC, 0x89, 0x05, - 0x55, 0xCC, 0x9B, 0xCC, 0x81, 0x05, 0x75, 0xCC, - 0x9B, 0xCC, 0x81, 0x05, 0x55, 0xCC, 0x9B, 0xCC, - 0x80, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0x05, - 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0x05, 0x75, 0xCC, + 0x82, 0x43, 0xE5, 0x8E, 0xB6, 0x43, 0xE5, 0x8F, + 0x83, 0x43, 0xE5, 0x8F, 0x88, 0x43, 0xE5, 0x8F, + 0x8A, 0x43, 0xE5, 0x8F, 0x8C, 0x43, 0xE5, 0x8F, + 0x9F, 0x43, 0xE5, 0x8F, 0xA3, 0x43, 0xE5, 0x8F, + 0xA5, 0x43, 0xE5, 0x8F, 0xAB, 0x43, 0xE5, 0x8F, + 0xAF, 0x43, 0xE5, 0x8F, 0xB1, 0x43, 0xE5, 0x8F, + 0xB3, 0x43, 0xE5, 0x90, 0x86, 0x43, 0xE5, 0x90, + 0x88, 0x43, 0xE5, 0x90, 0x8D, 0x43, 0xE5, 0x90, // Bytes e40 - e7f - 0x9B, 0xCC, 0x89, 0x05, 0x55, 0xCC, 0x9B, 0xCC, - 0x83, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0x05, - 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0x05, 0x75, 0xCC, - 0x9B, 0xCC, 0xA3, 0x03, 0x59, 0xCC, 0x80, 0x03, - 0x79, 0xCC, 0x80, 0x03, 0x59, 0xCC, 0xA3, 0x03, - 0x79, 0xCC, 0xA3, 0x03, 0x59, 0xCC, 0x89, 0x03, - 0x79, 0xCC, 0x89, 0x03, 0x59, 0xCC, 0x83, 0x03, - 0x79, 0xCC, 0x83, 0x04, 0xCE, 0xB1, 0xCC, 0x93, + 0x8F, 0x43, 0xE5, 0x90, 0x9D, 0x43, 0xE5, 0x90, + 0xB8, 0x43, 0xE5, 0x90, 0xB9, 0x43, 0xE5, 0x91, + 0x82, 0x43, 0xE5, 0x91, 0x88, 0x43, 0xE5, 0x91, + 0xA8, 0x43, 0xE5, 0x92, 0x9E, 0x43, 0xE5, 0x92, + 0xA2, 0x43, 0xE5, 0x92, 0xBD, 0x43, 0xE5, 0x93, + 0xB6, 0x43, 0xE5, 0x94, 0x90, 0x43, 0xE5, 0x95, + 0x8F, 0x43, 0xE5, 0x95, 0x93, 0x43, 0xE5, 0x95, + 0x95, 0x43, 0xE5, 0x95, 0xA3, 0x43, 0xE5, 0x96, // Bytes e80 - ebf - 0x04, 0xCE, 0xB1, 0xCC, 0x94, 0x06, 0xCE, 0xB1, - 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, 0x93, - 0xCC, 0x81, 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, - 0x81, 0x06, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, - 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0x04, - 0xCE, 0x91, 0xCC, 0x93, 0x04, 0xCE, 0x91, 0xCC, - 0x94, 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, + 0x84, 0x43, 0xE5, 0x96, 0x87, 0x43, 0xE5, 0x96, + 0x99, 0x43, 0xE5, 0x96, 0x9D, 0x43, 0xE5, 0x96, + 0xAB, 0x43, 0xE5, 0x96, 0xB3, 0x43, 0xE5, 0x96, + 0xB6, 0x43, 0xE5, 0x97, 0x80, 0x43, 0xE5, 0x97, + 0x82, 0x43, 0xE5, 0x97, 0xA2, 0x43, 0xE5, 0x98, + 0x86, 0x43, 0xE5, 0x99, 0x91, 0x43, 0xE5, 0x99, + 0xA8, 0x43, 0xE5, 0x99, 0xB4, 0x43, 0xE5, 0x9B, + 0x97, 0x43, 0xE5, 0x9B, 0x9B, 0x43, 0xE5, 0x9B, // Bytes ec0 - eff - 0x06, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0x06, - 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, - 0x91, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0x91, - 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0x91, 0xCC, - 0x94, 0xCD, 0x82, 0x04, 0xCE, 0xB5, 0xCC, 0x93, - 0x04, 0xCE, 0xB5, 0xCC, 0x94, 0x06, 0xCE, 0xB5, - 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0xB5, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xB5, 0xCC, 0x93, + 0xB9, 0x43, 0xE5, 0x9C, 0x96, 0x43, 0xE5, 0x9C, + 0x97, 0x43, 0xE5, 0x9C, 0x9F, 0x43, 0xE5, 0x9C, + 0xB0, 0x43, 0xE5, 0x9E, 0x8B, 0x43, 0xE5, 0x9F, + 0x8E, 0x43, 0xE5, 0x9F, 0xB4, 0x43, 0xE5, 0xA0, + 0x8D, 0x43, 0xE5, 0xA0, 0xB1, 0x43, 0xE5, 0xA0, + 0xB2, 0x43, 0xE5, 0xA1, 0x80, 0x43, 0xE5, 0xA1, + 0x9A, 0x43, 0xE5, 0xA1, 0x9E, 0x43, 0xE5, 0xA2, + 0xA8, 0x43, 0xE5, 0xA2, 0xAC, 0x43, 0xE5, 0xA2, // Bytes f00 - f3f - 0xCC, 0x81, 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, - 0x81, 0x04, 0xCE, 0x95, 0xCC, 0x93, 0x04, 0xCE, - 0x95, 0xCC, 0x94, 0x06, 0xCE, 0x95, 0xCC, 0x93, - 0xCC, 0x80, 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, - 0x80, 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, - 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0x04, - 0xCE, 0xB7, 0xCC, 0x93, 0x04, 0xCE, 0xB7, 0xCC, - 0x94, 0x06, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, + 0xB3, 0x43, 0xE5, 0xA3, 0x98, 0x43, 0xE5, 0xA3, + 0x9F, 0x43, 0xE5, 0xA3, 0xAB, 0x43, 0xE5, 0xA3, + 0xAE, 0x43, 0xE5, 0xA3, 0xB0, 0x43, 0xE5, 0xA3, + 0xB2, 0x43, 0xE5, 0xA3, 0xB7, 0x43, 0xE5, 0xA4, + 0x82, 0x43, 0xE5, 0xA4, 0x86, 0x43, 0xE5, 0xA4, + 0x8A, 0x43, 0xE5, 0xA4, 0x95, 0x43, 0xE5, 0xA4, + 0x9A, 0x43, 0xE5, 0xA4, 0x9C, 0x43, 0xE5, 0xA4, + 0xA2, 0x43, 0xE5, 0xA4, 0xA7, 0x43, 0xE5, 0xA4, // Bytes f40 - f7f - 0x06, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0x06, - 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, - 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xB7, - 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0xB7, 0xCC, - 0x94, 0xCD, 0x82, 0x04, 0xCE, 0x97, 0xCC, 0x93, - 0x04, 0xCE, 0x97, 0xCC, 0x94, 0x06, 0xCE, 0x97, - 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0x97, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x97, 0xCC, 0x93, + 0xA9, 0x43, 0xE5, 0xA5, 0x84, 0x43, 0xE5, 0xA5, + 0x88, 0x43, 0xE5, 0xA5, 0x91, 0x43, 0xE5, 0xA5, + 0x94, 0x43, 0xE5, 0xA5, 0xA2, 0x43, 0xE5, 0xA5, + 0xB3, 0x43, 0xE5, 0xA7, 0x98, 0x43, 0xE5, 0xA7, + 0xAC, 0x43, 0xE5, 0xA8, 0x9B, 0x43, 0xE5, 0xA8, + 0xA7, 0x43, 0xE5, 0xA9, 0xA2, 0x43, 0xE5, 0xA9, + 0xA6, 0x43, 0xE5, 0xAA, 0xB5, 0x43, 0xE5, 0xAC, + 0x88, 0x43, 0xE5, 0xAC, 0xA8, 0x43, 0xE5, 0xAC, // Bytes f80 - fbf - 0xCC, 0x81, 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCC, - 0x81, 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, - 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, 0x04, - 0xCE, 0xB9, 0xCC, 0x93, 0x04, 0xCE, 0xB9, 0xCC, - 0x94, 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, - 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0x06, - 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, - 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xB9, + 0xBE, 0x43, 0xE5, 0xAD, 0x90, 0x43, 0xE5, 0xAD, + 0x97, 0x43, 0xE5, 0xAD, 0xA6, 0x43, 0xE5, 0xAE, + 0x80, 0x43, 0xE5, 0xAE, 0x85, 0x43, 0xE5, 0xAE, + 0x97, 0x43, 0xE5, 0xAF, 0x83, 0x43, 0xE5, 0xAF, + 0x98, 0x43, 0xE5, 0xAF, 0xA7, 0x43, 0xE5, 0xAF, + 0xAE, 0x43, 0xE5, 0xAF, 0xB3, 0x43, 0xE5, 0xAF, + 0xB8, 0x43, 0xE5, 0xAF, 0xBF, 0x43, 0xE5, 0xB0, + 0x86, 0x43, 0xE5, 0xB0, 0x8F, 0x43, 0xE5, 0xB0, // Bytes fc0 - fff - 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCE, 0xB9, 0xCC, - 0x94, 0xCD, 0x82, 0x04, 0xCE, 0x99, 0xCC, 0x93, - 0x04, 0xCE, 0x99, 0xCC, 0x94, 0x06, 0xCE, 0x99, - 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, 0x99, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x99, 0xCC, 0x93, - 0xCC, 0x81, 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, - 0x81, 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, - 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0x04, + 0xA2, 0x43, 0xE5, 0xB0, 0xB8, 0x43, 0xE5, 0xB0, + 0xBF, 0x43, 0xE5, 0xB1, 0xA0, 0x43, 0xE5, 0xB1, + 0xA2, 0x43, 0xE5, 0xB1, 0xA4, 0x43, 0xE5, 0xB1, + 0xA5, 0x43, 0xE5, 0xB1, 0xAE, 0x43, 0xE5, 0xB1, + 0xB1, 0x43, 0xE5, 0xB2, 0x8D, 0x43, 0xE5, 0xB3, + 0x80, 0x43, 0xE5, 0xB4, 0x99, 0x43, 0xE5, 0xB5, + 0x83, 0x43, 0xE5, 0xB5, 0x90, 0x43, 0xE5, 0xB5, + 0xAB, 0x43, 0xE5, 0xB5, 0xAE, 0x43, 0xE5, 0xB5, // Bytes 1000 - 103f - 0xCE, 0xBF, 0xCC, 0x93, 0x04, 0xCE, 0xBF, 0xCC, - 0x94, 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, - 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0x06, - 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, - 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0x04, 0xCE, 0x9F, - 0xCC, 0x93, 0x04, 0xCE, 0x9F, 0xCC, 0x94, 0x06, - 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, - 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0x06, 0xCE, 0x9F, + 0xBC, 0x43, 0xE5, 0xB6, 0xB2, 0x43, 0xE5, 0xB6, + 0xBA, 0x43, 0xE5, 0xB7, 0x9B, 0x43, 0xE5, 0xB7, + 0xA1, 0x43, 0xE5, 0xB7, 0xA2, 0x43, 0xE5, 0xB7, + 0xA5, 0x43, 0xE5, 0xB7, 0xA6, 0x43, 0xE5, 0xB7, + 0xB1, 0x43, 0xE5, 0xB7, 0xBD, 0x43, 0xE5, 0xB7, + 0xBE, 0x43, 0xE5, 0xB8, 0xA8, 0x43, 0xE5, 0xB8, + 0xBD, 0x43, 0xE5, 0xB9, 0xA9, 0x43, 0xE5, 0xB9, + 0xB2, 0x43, 0xE5, 0xB9, 0xB4, 0x43, 0xE5, 0xB9, // Bytes 1040 - 107f - 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, 0x9F, 0xCC, - 0x94, 0xCC, 0x81, 0x04, 0xCF, 0x85, 0xCC, 0x93, - 0x04, 0xCF, 0x85, 0xCC, 0x94, 0x06, 0xCF, 0x85, - 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCF, 0x85, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCF, 0x85, 0xCC, 0x93, - 0xCC, 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, - 0x81, 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, - 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0x04, + 0xBA, 0x43, 0xE5, 0xB9, 0xBC, 0x43, 0xE5, 0xB9, + 0xBF, 0x43, 0xE5, 0xBA, 0xA6, 0x43, 0xE5, 0xBA, + 0xB0, 0x43, 0xE5, 0xBA, 0xB3, 0x43, 0xE5, 0xBA, + 0xB6, 0x43, 0xE5, 0xBB, 0x89, 0x43, 0xE5, 0xBB, + 0x8A, 0x43, 0xE5, 0xBB, 0x92, 0x43, 0xE5, 0xBB, + 0x93, 0x43, 0xE5, 0xBB, 0x99, 0x43, 0xE5, 0xBB, + 0xAC, 0x43, 0xE5, 0xBB, 0xB4, 0x43, 0xE5, 0xBB, + 0xBE, 0x43, 0xE5, 0xBC, 0x84, 0x43, 0xE5, 0xBC, // Bytes 1080 - 10bf - 0xCE, 0xA5, 0xCC, 0x94, 0x06, 0xCE, 0xA5, 0xCC, - 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xA5, 0xCC, 0x94, - 0xCC, 0x81, 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, - 0x82, 0x04, 0xCF, 0x89, 0xCC, 0x93, 0x04, 0xCF, - 0x89, 0xCC, 0x94, 0x06, 0xCF, 0x89, 0xCC, 0x93, - 0xCC, 0x80, 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCC, - 0x80, 0x06, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, - 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0x06, + 0x8B, 0x43, 0xE5, 0xBC, 0x93, 0x43, 0xE5, 0xBC, + 0xA2, 0x43, 0xE5, 0xBD, 0x90, 0x43, 0xE5, 0xBD, + 0x93, 0x43, 0xE5, 0xBD, 0xA1, 0x43, 0xE5, 0xBD, + 0xA2, 0x43, 0xE5, 0xBD, 0xA9, 0x43, 0xE5, 0xBD, + 0xAB, 0x43, 0xE5, 0xBD, 0xB3, 0x43, 0xE5, 0xBE, + 0x8B, 0x43, 0xE5, 0xBE, 0x8C, 0x43, 0xE5, 0xBE, + 0x97, 0x43, 0xE5, 0xBE, 0x9A, 0x43, 0xE5, 0xBE, + 0xA9, 0x43, 0xE5, 0xBE, 0xAD, 0x43, 0xE5, 0xBF, // Bytes 10c0 - 10ff - 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0x06, 0xCF, - 0x89, 0xCC, 0x94, 0xCD, 0x82, 0x04, 0xCE, 0xA9, - 0xCC, 0x93, 0x04, 0xCE, 0xA9, 0xCC, 0x94, 0x06, - 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0x06, 0xCE, - 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0x06, 0xCE, 0xA9, - 0xCC, 0x93, 0xCC, 0x81, 0x06, 0xCE, 0xA9, 0xCC, - 0x94, 0xCC, 0x81, 0x06, 0xCE, 0xA9, 0xCC, 0x93, - 0xCD, 0x82, 0x06, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, + 0x83, 0x43, 0xE5, 0xBF, 0x8D, 0x43, 0xE5, 0xBF, + 0x97, 0x43, 0xE5, 0xBF, 0xB5, 0x43, 0xE5, 0xBF, + 0xB9, 0x43, 0xE6, 0x80, 0x92, 0x43, 0xE6, 0x80, + 0x9C, 0x43, 0xE6, 0x81, 0xB5, 0x43, 0xE6, 0x82, + 0x81, 0x43, 0xE6, 0x82, 0x94, 0x43, 0xE6, 0x83, + 0x87, 0x43, 0xE6, 0x83, 0x98, 0x43, 0xE6, 0x83, + 0xA1, 0x43, 0xE6, 0x84, 0x88, 0x43, 0xE6, 0x85, + 0x84, 0x43, 0xE6, 0x85, 0x88, 0x43, 0xE6, 0x85, // Bytes 1100 - 113f - 0x82, 0x04, 0xCE, 0xB1, 0xCC, 0x80, 0x04, 0xCE, - 0xB5, 0xCC, 0x80, 0x04, 0xCE, 0xB7, 0xCC, 0x80, - 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0x04, 0xCE, 0xBF, - 0xCC, 0x80, 0x04, 0xCF, 0x85, 0xCC, 0x80, 0x04, - 0xCF, 0x89, 0xCC, 0x80, 0x06, 0xCE, 0xB1, 0xCC, - 0x93, 0xCD, 0x85, 0x06, 0xCE, 0xB1, 0xCC, 0x94, - 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, - 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, 0x94, + 0x8C, 0x43, 0xE6, 0x85, 0x8E, 0x43, 0xE6, 0x85, + 0xA0, 0x43, 0xE6, 0x85, 0xA8, 0x43, 0xE6, 0x85, + 0xBA, 0x43, 0xE6, 0x86, 0x8E, 0x43, 0xE6, 0x86, + 0x90, 0x43, 0xE6, 0x86, 0xA4, 0x43, 0xE6, 0x86, + 0xAF, 0x43, 0xE6, 0x86, 0xB2, 0x43, 0xE6, 0x87, + 0x9E, 0x43, 0xE6, 0x87, 0xB2, 0x43, 0xE6, 0x87, + 0xB6, 0x43, 0xE6, 0x88, 0x80, 0x43, 0xE6, 0x88, + 0x88, 0x43, 0xE6, 0x88, 0x90, 0x43, 0xE6, 0x88, // Bytes 1140 - 117f - 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB1, 0xCC, - 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, 0xB1, - 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, - 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, - 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, - 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0x06, - 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, - 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, + 0x9B, 0x43, 0xE6, 0x88, 0xAE, 0x43, 0xE6, 0x88, + 0xB4, 0x43, 0xE6, 0x88, 0xB6, 0x43, 0xE6, 0x89, + 0x8B, 0x43, 0xE6, 0x89, 0x93, 0x43, 0xE6, 0x89, + 0x9D, 0x43, 0xE6, 0x8A, 0x95, 0x43, 0xE6, 0x8A, + 0xB1, 0x43, 0xE6, 0x8B, 0x89, 0x43, 0xE6, 0x8B, + 0x8F, 0x43, 0xE6, 0x8B, 0x93, 0x43, 0xE6, 0x8B, + 0x94, 0x43, 0xE6, 0x8B, 0xBC, 0x43, 0xE6, 0x8B, + 0xBE, 0x43, 0xE6, 0x8C, 0x87, 0x43, 0xE6, 0x8C, // Bytes 1180 - 11bf - 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, - 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCD, - 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, - 0xCD, 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCD, - 0x82, 0xCD, 0x85, 0x08, 0xCE, 0x91, 0xCC, 0x94, - 0xCD, 0x82, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, - 0x93, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, 0x94, - 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, + 0xBD, 0x43, 0xE6, 0x8D, 0x90, 0x43, 0xE6, 0x8D, + 0x95, 0x43, 0xE6, 0x8D, 0xA8, 0x43, 0xE6, 0x8D, + 0xBB, 0x43, 0xE6, 0x8E, 0x83, 0x43, 0xE6, 0x8E, + 0xA0, 0x43, 0xE6, 0x8E, 0xA9, 0x43, 0xE6, 0x8F, + 0x84, 0x43, 0xE6, 0x8F, 0x85, 0x43, 0xE6, 0x8F, + 0xA4, 0x43, 0xE6, 0x90, 0x9C, 0x43, 0xE6, 0x90, + 0xA2, 0x43, 0xE6, 0x91, 0x92, 0x43, 0xE6, 0x91, + 0xA9, 0x43, 0xE6, 0x91, 0xB7, 0x43, 0xE6, 0x91, // Bytes 11c0 - 11ff - 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, 0x94, - 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCE, 0xB7, 0xCC, - 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, 0xB7, - 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCE, - 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, - 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, - 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0x06, - 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, + 0xBE, 0x43, 0xE6, 0x92, 0x9A, 0x43, 0xE6, 0x92, + 0x9D, 0x43, 0xE6, 0x93, 0x84, 0x43, 0xE6, 0x94, + 0xAF, 0x43, 0xE6, 0x94, 0xB4, 0x43, 0xE6, 0x95, + 0x8F, 0x43, 0xE6, 0x95, 0x96, 0x43, 0xE6, 0x95, + 0xAC, 0x43, 0xE6, 0x95, 0xB8, 0x43, 0xE6, 0x96, + 0x87, 0x43, 0xE6, 0x96, 0x97, 0x43, 0xE6, 0x96, + 0x99, 0x43, 0xE6, 0x96, 0xA4, 0x43, 0xE6, 0x96, + 0xB0, 0x43, 0xE6, 0x96, 0xB9, 0x43, 0xE6, 0x97, // Bytes 1200 - 123f - 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, - 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, - 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCD, - 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, - 0xCD, 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCD, - 0x82, 0xCD, 0x85, 0x08, 0xCE, 0x97, 0xCC, 0x94, - 0xCD, 0x82, 0xCD, 0x85, 0x06, 0xCF, 0x89, 0xCC, - 0x93, 0xCD, 0x85, 0x06, 0xCF, 0x89, 0xCC, 0x94, + 0x85, 0x43, 0xE6, 0x97, 0xA0, 0x43, 0xE6, 0x97, + 0xA2, 0x43, 0xE6, 0x97, 0xA3, 0x43, 0xE6, 0x97, + 0xA5, 0x43, 0xE6, 0x98, 0x93, 0x43, 0xE6, 0x98, + 0xA0, 0x43, 0xE6, 0x99, 0x89, 0x43, 0xE6, 0x99, + 0xB4, 0x43, 0xE6, 0x9A, 0x88, 0x43, 0xE6, 0x9A, + 0x91, 0x43, 0xE6, 0x9A, 0x9C, 0x43, 0xE6, 0x9A, + 0xB4, 0x43, 0xE6, 0x9B, 0x86, 0x43, 0xE6, 0x9B, + 0xB0, 0x43, 0xE6, 0x9B, 0xB4, 0x43, 0xE6, 0x9B, // Bytes 1240 - 127f - 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCC, - 0x80, 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, 0x94, - 0xCC, 0x80, 0xCD, 0x85, 0x08, 0xCF, 0x89, 0xCC, - 0x93, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCF, 0x89, - 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0x08, 0xCF, - 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0x08, - 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, - 0x06, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0x06, + 0xB8, 0x43, 0xE6, 0x9C, 0x80, 0x43, 0xE6, 0x9C, + 0x88, 0x43, 0xE6, 0x9C, 0x89, 0x43, 0xE6, 0x9C, + 0x97, 0x43, 0xE6, 0x9C, 0x9B, 0x43, 0xE6, 0x9C, + 0xA1, 0x43, 0xE6, 0x9C, 0xA8, 0x43, 0xE6, 0x9D, + 0x8E, 0x43, 0xE6, 0x9D, 0x93, 0x43, 0xE6, 0x9D, + 0x96, 0x43, 0xE6, 0x9D, 0x9E, 0x43, 0xE6, 0x9D, + 0xBB, 0x43, 0xE6, 0x9E, 0x85, 0x43, 0xE6, 0x9E, + 0x97, 0x43, 0xE6, 0x9F, 0xB3, 0x43, 0xE6, 0x9F, // Bytes 1280 - 12bf - 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0x08, 0xCE, - 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0x08, - 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, - 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCD, - 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, - 0xCD, 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, - 0x82, 0xCD, 0x85, 0x08, 0xCE, 0xA9, 0xCC, 0x94, - 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, 0xB1, 0xCC, + 0xBA, 0x43, 0xE6, 0xA0, 0x97, 0x43, 0xE6, 0xA0, + 0x9F, 0x43, 0xE6, 0xA0, 0xAA, 0x43, 0xE6, 0xA1, + 0x92, 0x43, 0xE6, 0xA2, 0x81, 0x43, 0xE6, 0xA2, + 0x85, 0x43, 0xE6, 0xA2, 0x8E, 0x43, 0xE6, 0xA2, + 0xA8, 0x43, 0xE6, 0xA4, 0x94, 0x43, 0xE6, 0xA5, + 0x82, 0x43, 0xE6, 0xA6, 0xA3, 0x43, 0xE6, 0xA7, + 0xAA, 0x43, 0xE6, 0xA8, 0x82, 0x43, 0xE6, 0xA8, + 0x93, 0x43, 0xE6, 0xAA, 0xA8, 0x43, 0xE6, 0xAB, // Bytes 12c0 - 12ff - 0x86, 0x04, 0xCE, 0xB1, 0xCC, 0x84, 0x06, 0xCE, - 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0x04, 0xCE, 0xB1, - 0xCD, 0x85, 0x06, 0xCE, 0xB1, 0xCC, 0x81, 0xCD, - 0x85, 0x04, 0xCE, 0xB1, 0xCD, 0x82, 0x06, 0xCE, - 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, 0x91, - 0xCC, 0x86, 0x04, 0xCE, 0x91, 0xCC, 0x84, 0x04, - 0xCE, 0x91, 0xCC, 0x80, 0x04, 0xCE, 0x91, 0xCD, - 0x85, 0x03, 0x20, 0xCC, 0x93, 0x02, 0xCE, 0xB9, + 0x93, 0x43, 0xE6, 0xAB, 0x9B, 0x43, 0xE6, 0xAC, + 0x84, 0x43, 0xE6, 0xAC, 0xA0, 0x43, 0xE6, 0xAC, + 0xA1, 0x43, 0xE6, 0xAD, 0x94, 0x43, 0xE6, 0xAD, + 0xA2, 0x43, 0xE6, 0xAD, 0xA3, 0x43, 0xE6, 0xAD, + 0xB2, 0x43, 0xE6, 0xAD, 0xB7, 0x43, 0xE6, 0xAD, + 0xB9, 0x43, 0xE6, 0xAE, 0x9F, 0x43, 0xE6, 0xAE, + 0xAE, 0x43, 0xE6, 0xAE, 0xB3, 0x43, 0xE6, 0xAE, + 0xBA, 0x43, 0xE6, 0xAE, 0xBB, 0x43, 0xE6, 0xAF, // Bytes 1300 - 133f - 0x03, 0x20, 0xCD, 0x82, 0x04, 0xC2, 0xA8, 0xCD, - 0x82, 0x05, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0x06, - 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0x04, 0xCE, - 0xB7, 0xCD, 0x85, 0x06, 0xCE, 0xB7, 0xCC, 0x81, - 0xCD, 0x85, 0x04, 0xCE, 0xB7, 0xCD, 0x82, 0x06, - 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0x04, 0xCE, - 0x95, 0xCC, 0x80, 0x04, 0xCE, 0x97, 0xCC, 0x80, - 0x04, 0xCE, 0x97, 0xCD, 0x85, 0x05, 0xE1, 0xBE, + 0x8B, 0x43, 0xE6, 0xAF, 0x8D, 0x43, 0xE6, 0xAF, + 0x94, 0x43, 0xE6, 0xAF, 0x9B, 0x43, 0xE6, 0xB0, + 0x8F, 0x43, 0xE6, 0xB0, 0x94, 0x43, 0xE6, 0xB0, + 0xB4, 0x43, 0xE6, 0xB1, 0x8E, 0x43, 0xE6, 0xB1, + 0xA7, 0x43, 0xE6, 0xB2, 0x88, 0x43, 0xE6, 0xB2, + 0xBF, 0x43, 0xE6, 0xB3, 0x8C, 0x43, 0xE6, 0xB3, + 0x8D, 0x43, 0xE6, 0xB3, 0xA5, 0x43, 0xE6, 0xB3, + 0xA8, 0x43, 0xE6, 0xB4, 0x96, 0x43, 0xE6, 0xB4, // Bytes 1340 - 137f - 0xBF, 0xCC, 0x80, 0x05, 0x20, 0xCC, 0x93, 0xCC, - 0x80, 0x05, 0xE1, 0xBE, 0xBF, 0xCC, 0x81, 0x05, - 0x20, 0xCC, 0x93, 0xCC, 0x81, 0x05, 0xE1, 0xBE, - 0xBF, 0xCD, 0x82, 0x05, 0x20, 0xCC, 0x93, 0xCD, - 0x82, 0x04, 0xCE, 0xB9, 0xCC, 0x86, 0x04, 0xCE, - 0xB9, 0xCC, 0x84, 0x06, 0xCE, 0xB9, 0xCC, 0x88, - 0xCC, 0x80, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0x06, - 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0x04, 0xCE, + 0x9B, 0x43, 0xE6, 0xB4, 0x9E, 0x43, 0xE6, 0xB4, + 0xB4, 0x43, 0xE6, 0xB4, 0xBE, 0x43, 0xE6, 0xB5, + 0x81, 0x43, 0xE6, 0xB5, 0xA9, 0x43, 0xE6, 0xB5, + 0xAA, 0x43, 0xE6, 0xB5, 0xB7, 0x43, 0xE6, 0xB5, + 0xB8, 0x43, 0xE6, 0xB6, 0x85, 0x43, 0xE6, 0xB7, + 0x8B, 0x43, 0xE6, 0xB7, 0x9A, 0x43, 0xE6, 0xB7, + 0xAA, 0x43, 0xE6, 0xB7, 0xB9, 0x43, 0xE6, 0xB8, + 0x9A, 0x43, 0xE6, 0xB8, 0xAF, 0x43, 0xE6, 0xB9, // Bytes 1380 - 13bf - 0x99, 0xCC, 0x86, 0x04, 0xCE, 0x99, 0xCC, 0x84, - 0x04, 0xCE, 0x99, 0xCC, 0x80, 0x05, 0xE1, 0xBF, - 0xBE, 0xCC, 0x80, 0x05, 0x20, 0xCC, 0x94, 0xCC, - 0x80, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0x05, - 0x20, 0xCC, 0x94, 0xCC, 0x81, 0x05, 0xE1, 0xBF, - 0xBE, 0xCD, 0x82, 0x05, 0x20, 0xCC, 0x94, 0xCD, - 0x82, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0x04, 0xCF, - 0x85, 0xCC, 0x84, 0x06, 0xCF, 0x85, 0xCC, 0x88, + 0xAE, 0x43, 0xE6, 0xBA, 0x80, 0x43, 0xE6, 0xBA, + 0x9C, 0x43, 0xE6, 0xBA, 0xBA, 0x43, 0xE6, 0xBB, + 0x87, 0x43, 0xE6, 0xBB, 0x8B, 0x43, 0xE6, 0xBB, + 0x91, 0x43, 0xE6, 0xBB, 0x9B, 0x43, 0xE6, 0xBC, + 0x8F, 0x43, 0xE6, 0xBC, 0x94, 0x43, 0xE6, 0xBC, + 0xA2, 0x43, 0xE6, 0xBC, 0xA3, 0x43, 0xE6, 0xBD, + 0xAE, 0x43, 0xE6, 0xBF, 0x86, 0x43, 0xE6, 0xBF, + 0xAB, 0x43, 0xE6, 0xBF, 0xBE, 0x43, 0xE7, 0x80, // Bytes 13c0 - 13ff - 0xCC, 0x80, 0x04, 0xCF, 0x81, 0xCC, 0x93, 0x04, - 0xCF, 0x81, 0xCC, 0x94, 0x04, 0xCF, 0x85, 0xCD, - 0x82, 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, - 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0x04, 0xCE, 0xA5, - 0xCC, 0x84, 0x04, 0xCE, 0xA5, 0xCC, 0x80, 0x04, - 0xCE, 0xA1, 0xCC, 0x94, 0x04, 0xC2, 0xA8, 0xCC, - 0x80, 0x05, 0x20, 0xCC, 0x88, 0xCC, 0x80, 0x01, - 0x60, 0x06, 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, + 0x9B, 0x43, 0xE7, 0x80, 0x9E, 0x43, 0xE7, 0x80, + 0xB9, 0x43, 0xE7, 0x81, 0x8A, 0x43, 0xE7, 0x81, + 0xAB, 0x43, 0xE7, 0x81, 0xB0, 0x43, 0xE7, 0x81, + 0xB7, 0x43, 0xE7, 0x81, 0xBD, 0x43, 0xE7, 0x82, + 0x99, 0x43, 0xE7, 0x82, 0xAD, 0x43, 0xE7, 0x83, + 0x88, 0x43, 0xE7, 0x83, 0x99, 0x43, 0xE7, 0x84, + 0xA1, 0x43, 0xE7, 0x85, 0x85, 0x43, 0xE7, 0x85, + 0x89, 0x43, 0xE7, 0x85, 0xAE, 0x43, 0xE7, 0x86, // Bytes 1400 - 143f - 0x04, 0xCF, 0x89, 0xCD, 0x85, 0x06, 0xCF, 0x89, - 0xCC, 0x81, 0xCD, 0x85, 0x04, 0xCF, 0x89, 0xCD, - 0x82, 0x06, 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, - 0x04, 0xCE, 0x9F, 0xCC, 0x80, 0x04, 0xCE, 0xA9, - 0xCC, 0x80, 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0x02, - 0xC2, 0xB4, 0x03, 0x20, 0xCC, 0x94, 0x03, 0xE2, - 0x80, 0x82, 0x03, 0xE2, 0x80, 0x83, 0x03, 0xE2, - 0x80, 0x90, 0x03, 0x20, 0xCC, 0xB3, 0x01, 0x2E, + 0x9C, 0x43, 0xE7, 0x87, 0x8E, 0x43, 0xE7, 0x87, + 0x90, 0x43, 0xE7, 0x88, 0x90, 0x43, 0xE7, 0x88, + 0x9B, 0x43, 0xE7, 0x88, 0xA8, 0x43, 0xE7, 0x88, + 0xAA, 0x43, 0xE7, 0x88, 0xAB, 0x43, 0xE7, 0x88, + 0xB5, 0x43, 0xE7, 0x88, 0xB6, 0x43, 0xE7, 0x88, + 0xBB, 0x43, 0xE7, 0x88, 0xBF, 0x43, 0xE7, 0x89, + 0x87, 0x43, 0xE7, 0x89, 0x90, 0x43, 0xE7, 0x89, + 0x99, 0x43, 0xE7, 0x89, 0x9B, 0x43, 0xE7, 0x89, // Bytes 1440 - 147f - 0x02, 0x2E, 0x2E, 0x03, 0x2E, 0x2E, 0x2E, 0x06, - 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x09, 0xE2, - 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, - 0x06, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x09, - 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, - 0xB5, 0x02, 0x21, 0x21, 0x03, 0x20, 0xCC, 0x85, - 0x02, 0x3F, 0x3F, 0x02, 0x3F, 0x21, 0x02, 0x21, - 0x3F, 0x0C, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xA2, 0x43, 0xE7, 0x89, 0xB9, 0x43, 0xE7, 0x8A, + 0x80, 0x43, 0xE7, 0x8A, 0x95, 0x43, 0xE7, 0x8A, + 0xAC, 0x43, 0xE7, 0x8A, 0xAF, 0x43, 0xE7, 0x8B, + 0x80, 0x43, 0xE7, 0x8B, 0xBC, 0x43, 0xE7, 0x8C, + 0xAA, 0x43, 0xE7, 0x8D, 0xB5, 0x43, 0xE7, 0x8D, + 0xBA, 0x43, 0xE7, 0x8E, 0x84, 0x43, 0xE7, 0x8E, + 0x87, 0x43, 0xE7, 0x8E, 0x89, 0x43, 0xE7, 0x8E, + 0x8B, 0x43, 0xE7, 0x8E, 0xA5, 0x43, 0xE7, 0x8E, // Bytes 1480 - 14bf - 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x01, 0x30, - 0x01, 0x34, 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, - 0x01, 0x38, 0x01, 0x39, 0x01, 0x2B, 0x03, 0xE2, - 0x88, 0x92, 0x01, 0x3D, 0x01, 0x28, 0x01, 0x29, - 0x01, 0x6E, 0x02, 0x52, 0x73, 0x03, 0x61, 0x2F, - 0x63, 0x03, 0x61, 0x2F, 0x73, 0x01, 0x43, 0x03, - 0xC2, 0xB0, 0x43, 0x03, 0x63, 0x2F, 0x6F, 0x03, - 0x63, 0x2F, 0x75, 0x02, 0xC6, 0x90, 0x03, 0xC2, + 0xB2, 0x43, 0xE7, 0x8F, 0x9E, 0x43, 0xE7, 0x90, + 0x86, 0x43, 0xE7, 0x90, 0x89, 0x43, 0xE7, 0x90, + 0xA2, 0x43, 0xE7, 0x91, 0x87, 0x43, 0xE7, 0x91, + 0x9C, 0x43, 0xE7, 0x91, 0xA9, 0x43, 0xE7, 0x91, + 0xB1, 0x43, 0xE7, 0x92, 0x85, 0x43, 0xE7, 0x92, + 0x89, 0x43, 0xE7, 0x92, 0x98, 0x43, 0xE7, 0x93, + 0x8A, 0x43, 0xE7, 0x93, 0x9C, 0x43, 0xE7, 0x93, + 0xA6, 0x43, 0xE7, 0x94, 0x86, 0x43, 0xE7, 0x94, // Bytes 14c0 - 14ff - 0xB0, 0x46, 0x02, 0xC4, 0xA7, 0x02, 0x4E, 0x6F, - 0x01, 0x51, 0x02, 0x53, 0x4D, 0x03, 0x54, 0x45, - 0x4C, 0x02, 0x54, 0x4D, 0x01, 0x5A, 0x02, 0xCE, - 0xA9, 0x01, 0x46, 0x02, 0xD7, 0x90, 0x02, 0xD7, - 0x91, 0x02, 0xD7, 0x92, 0x02, 0xD7, 0x93, 0x03, - 0x46, 0x41, 0x58, 0x02, 0xCE, 0x93, 0x02, 0xCE, - 0xA0, 0x03, 0xE2, 0x88, 0x91, 0x05, 0x31, 0xE2, - 0x81, 0x84, 0x37, 0x05, 0x31, 0xE2, 0x81, 0x84, + 0x98, 0x43, 0xE7, 0x94, 0x9F, 0x43, 0xE7, 0x94, + 0xA4, 0x43, 0xE7, 0x94, 0xA8, 0x43, 0xE7, 0x94, + 0xB0, 0x43, 0xE7, 0x94, 0xB2, 0x43, 0xE7, 0x94, + 0xB3, 0x43, 0xE7, 0x94, 0xB7, 0x43, 0xE7, 0x94, + 0xBB, 0x43, 0xE7, 0x94, 0xBE, 0x43, 0xE7, 0x95, + 0x99, 0x43, 0xE7, 0x95, 0xA5, 0x43, 0xE7, 0x95, + 0xB0, 0x43, 0xE7, 0x96, 0x8B, 0x43, 0xE7, 0x96, + 0x92, 0x43, 0xE7, 0x97, 0xA2, 0x43, 0xE7, 0x98, // Bytes 1500 - 153f - 0x39, 0x06, 0x31, 0xE2, 0x81, 0x84, 0x31, 0x30, - 0x05, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x05, 0x32, - 0xE2, 0x81, 0x84, 0x33, 0x05, 0x31, 0xE2, 0x81, - 0x84, 0x35, 0x05, 0x32, 0xE2, 0x81, 0x84, 0x35, - 0x05, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x05, 0x34, - 0xE2, 0x81, 0x84, 0x35, 0x05, 0x31, 0xE2, 0x81, - 0x84, 0x36, 0x05, 0x35, 0xE2, 0x81, 0x84, 0x36, - 0x05, 0x31, 0xE2, 0x81, 0x84, 0x38, 0x05, 0x33, + 0x90, 0x43, 0xE7, 0x98, 0x9D, 0x43, 0xE7, 0x98, + 0x9F, 0x43, 0xE7, 0x99, 0x82, 0x43, 0xE7, 0x99, + 0xA9, 0x43, 0xE7, 0x99, 0xB6, 0x43, 0xE7, 0x99, + 0xBD, 0x43, 0xE7, 0x9A, 0xAE, 0x43, 0xE7, 0x9A, + 0xBF, 0x43, 0xE7, 0x9B, 0x8A, 0x43, 0xE7, 0x9B, + 0x9B, 0x43, 0xE7, 0x9B, 0xA3, 0x43, 0xE7, 0x9B, + 0xA7, 0x43, 0xE7, 0x9B, 0xAE, 0x43, 0xE7, 0x9B, + 0xB4, 0x43, 0xE7, 0x9C, 0x81, 0x43, 0xE7, 0x9C, // Bytes 1540 - 157f - 0xE2, 0x81, 0x84, 0x38, 0x05, 0x35, 0xE2, 0x81, - 0x84, 0x38, 0x05, 0x37, 0xE2, 0x81, 0x84, 0x38, - 0x04, 0x31, 0xE2, 0x81, 0x84, 0x02, 0x49, 0x49, - 0x03, 0x49, 0x49, 0x49, 0x02, 0x49, 0x56, 0x01, - 0x56, 0x02, 0x56, 0x49, 0x03, 0x56, 0x49, 0x49, - 0x04, 0x56, 0x49, 0x49, 0x49, 0x02, 0x49, 0x58, - 0x01, 0x58, 0x02, 0x58, 0x49, 0x03, 0x58, 0x49, - 0x49, 0x02, 0x69, 0x69, 0x03, 0x69, 0x69, 0x69, + 0x9E, 0x43, 0xE7, 0x9C, 0x9F, 0x43, 0xE7, 0x9D, + 0x80, 0x43, 0xE7, 0x9D, 0x8A, 0x43, 0xE7, 0x9E, + 0x8B, 0x43, 0xE7, 0x9E, 0xA7, 0x43, 0xE7, 0x9F, + 0x9B, 0x43, 0xE7, 0x9F, 0xA2, 0x43, 0xE7, 0x9F, + 0xB3, 0x43, 0xE7, 0xA1, 0x8E, 0x43, 0xE7, 0xA1, + 0xAB, 0x43, 0xE7, 0xA2, 0x8C, 0x43, 0xE7, 0xA2, + 0x91, 0x43, 0xE7, 0xA3, 0x8A, 0x43, 0xE7, 0xA3, + 0x8C, 0x43, 0xE7, 0xA3, 0xBB, 0x43, 0xE7, 0xA4, // Bytes 1580 - 15bf - 0x02, 0x69, 0x76, 0x02, 0x76, 0x69, 0x03, 0x76, - 0x69, 0x69, 0x04, 0x76, 0x69, 0x69, 0x69, 0x02, - 0x69, 0x78, 0x02, 0x78, 0x69, 0x03, 0x78, 0x69, - 0x69, 0x05, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x05, - 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, 0xE2, 0x86, - 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x86, 0x94, 0xCC, - 0xB8, 0x05, 0xE2, 0x87, 0x90, 0xCC, 0xB8, 0x05, - 0xE2, 0x87, 0x94, 0xCC, 0xB8, 0x05, 0xE2, 0x87, + 0xAA, 0x43, 0xE7, 0xA4, 0xBA, 0x43, 0xE7, 0xA4, + 0xBC, 0x43, 0xE7, 0xA4, 0xBE, 0x43, 0xE7, 0xA5, + 0x88, 0x43, 0xE7, 0xA5, 0x89, 0x43, 0xE7, 0xA5, + 0x90, 0x43, 0xE7, 0xA5, 0x96, 0x43, 0xE7, 0xA5, + 0x9D, 0x43, 0xE7, 0xA5, 0x9E, 0x43, 0xE7, 0xA5, + 0xA5, 0x43, 0xE7, 0xA5, 0xBF, 0x43, 0xE7, 0xA6, + 0x81, 0x43, 0xE7, 0xA6, 0x8D, 0x43, 0xE7, 0xA6, + 0x8E, 0x43, 0xE7, 0xA6, 0x8F, 0x43, 0xE7, 0xA6, // Bytes 15c0 - 15ff - 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x88, 0x83, 0xCC, - 0xB8, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05, - 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0xE2, 0x88, - 0xA3, 0xCC, 0xB8, 0x05, 0xE2, 0x88, 0xA5, 0xCC, - 0xB8, 0x06, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, - 0x09, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, - 0x88, 0xAB, 0x06, 0xE2, 0x88, 0xAE, 0xE2, 0x88, - 0xAE, 0x09, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, + 0xAE, 0x43, 0xE7, 0xA6, 0xB8, 0x43, 0xE7, 0xA6, + 0xBE, 0x43, 0xE7, 0xA7, 0x8A, 0x43, 0xE7, 0xA7, + 0x98, 0x43, 0xE7, 0xA7, 0xAB, 0x43, 0xE7, 0xA8, + 0x9C, 0x43, 0xE7, 0xA9, 0x80, 0x43, 0xE7, 0xA9, + 0x8A, 0x43, 0xE7, 0xA9, 0x8F, 0x43, 0xE7, 0xA9, + 0xB4, 0x43, 0xE7, 0xA9, 0xBA, 0x43, 0xE7, 0xAA, + 0x81, 0x43, 0xE7, 0xAA, 0xB1, 0x43, 0xE7, 0xAB, + 0x8B, 0x43, 0xE7, 0xAB, 0xAE, 0x43, 0xE7, 0xAB, // Bytes 1600 - 163f - 0xE2, 0x88, 0xAE, 0x05, 0xE2, 0x88, 0xBC, 0xCC, - 0xB8, 0x05, 0xE2, 0x89, 0x83, 0xCC, 0xB8, 0x05, - 0xE2, 0x89, 0x85, 0xCC, 0xB8, 0x05, 0xE2, 0x89, - 0x88, 0xCC, 0xB8, 0x03, 0x3D, 0xCC, 0xB8, 0x05, - 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0xE2, 0x89, - 0x8D, 0xCC, 0xB8, 0x03, 0x3C, 0xCC, 0xB8, 0x03, - 0x3E, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xA4, 0xCC, - 0xB8, 0x05, 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0x05, + 0xB9, 0x43, 0xE7, 0xAC, 0xA0, 0x43, 0xE7, 0xAE, + 0x8F, 0x43, 0xE7, 0xAF, 0x80, 0x43, 0xE7, 0xAF, + 0x86, 0x43, 0xE7, 0xAF, 0x89, 0x43, 0xE7, 0xB0, + 0xBE, 0x43, 0xE7, 0xB1, 0xA0, 0x43, 0xE7, 0xB1, + 0xB3, 0x43, 0xE7, 0xB1, 0xBB, 0x43, 0xE7, 0xB2, + 0x92, 0x43, 0xE7, 0xB2, 0xBE, 0x43, 0xE7, 0xB3, + 0x92, 0x43, 0xE7, 0xB3, 0x96, 0x43, 0xE7, 0xB3, + 0xA3, 0x43, 0xE7, 0xB3, 0xA7, 0x43, 0xE7, 0xB3, // Bytes 1640 - 167f - 0xE2, 0x89, 0xB2, 0xCC, 0xB8, 0x05, 0xE2, 0x89, - 0xB3, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xB6, 0xCC, - 0xB8, 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8, 0x05, - 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x05, 0xE2, 0x89, - 0xBB, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0x82, 0xCC, - 0xB8, 0x05, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, 0x05, - 0xE2, 0x8A, 0x86, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, - 0x87, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0xA2, 0xCC, + 0xA8, 0x43, 0xE7, 0xB3, 0xB8, 0x43, 0xE7, 0xB4, + 0x80, 0x43, 0xE7, 0xB4, 0x90, 0x43, 0xE7, 0xB4, + 0xA2, 0x43, 0xE7, 0xB4, 0xAF, 0x43, 0xE7, 0xB5, + 0x82, 0x43, 0xE7, 0xB5, 0x9B, 0x43, 0xE7, 0xB5, + 0xA3, 0x43, 0xE7, 0xB6, 0xA0, 0x43, 0xE7, 0xB6, + 0xBE, 0x43, 0xE7, 0xB7, 0x87, 0x43, 0xE7, 0xB7, + 0xB4, 0x43, 0xE7, 0xB8, 0x82, 0x43, 0xE7, 0xB8, + 0x89, 0x43, 0xE7, 0xB8, 0xB7, 0x43, 0xE7, 0xB9, // Bytes 1680 - 16bf - 0xB8, 0x05, 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0x05, - 0xE2, 0x8A, 0xA9, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, - 0xAB, 0xCC, 0xB8, 0x05, 0xE2, 0x89, 0xBC, 0xCC, - 0xB8, 0x05, 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0x05, - 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, - 0x92, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, 0xB2, 0xCC, - 0xB8, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8, 0x05, - 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x05, 0xE2, 0x8A, + 0x81, 0x43, 0xE7, 0xB9, 0x85, 0x43, 0xE7, 0xBC, + 0xB6, 0x43, 0xE7, 0xBC, 0xBE, 0x43, 0xE7, 0xBD, + 0x91, 0x43, 0xE7, 0xBD, 0xB2, 0x43, 0xE7, 0xBD, + 0xB9, 0x43, 0xE7, 0xBD, 0xBA, 0x43, 0xE7, 0xBE, + 0x85, 0x43, 0xE7, 0xBE, 0x8A, 0x43, 0xE7, 0xBE, + 0x95, 0x43, 0xE7, 0xBE, 0x9A, 0x43, 0xE7, 0xBE, + 0xBD, 0x43, 0xE7, 0xBF, 0xBA, 0x43, 0xE8, 0x80, + 0x81, 0x43, 0xE8, 0x80, 0x85, 0x43, 0xE8, 0x80, // Bytes 16c0 - 16ff - 0xB5, 0xCC, 0xB8, 0x03, 0xE3, 0x80, 0x88, 0x03, - 0xE3, 0x80, 0x89, 0x02, 0x31, 0x30, 0x02, 0x31, - 0x31, 0x02, 0x31, 0x32, 0x02, 0x31, 0x33, 0x02, - 0x31, 0x34, 0x02, 0x31, 0x35, 0x02, 0x31, 0x36, - 0x02, 0x31, 0x37, 0x02, 0x31, 0x38, 0x02, 0x31, - 0x39, 0x02, 0x32, 0x30, 0x03, 0x28, 0x31, 0x29, - 0x03, 0x28, 0x32, 0x29, 0x03, 0x28, 0x33, 0x29, - 0x03, 0x28, 0x34, 0x29, 0x03, 0x28, 0x35, 0x29, + 0x8C, 0x43, 0xE8, 0x80, 0x92, 0x43, 0xE8, 0x80, + 0xB3, 0x43, 0xE8, 0x81, 0x86, 0x43, 0xE8, 0x81, + 0xA0, 0x43, 0xE8, 0x81, 0xAF, 0x43, 0xE8, 0x81, + 0xB0, 0x43, 0xE8, 0x81, 0xBE, 0x43, 0xE8, 0x81, + 0xBF, 0x43, 0xE8, 0x82, 0x89, 0x43, 0xE8, 0x82, + 0x8B, 0x43, 0xE8, 0x82, 0xAD, 0x43, 0xE8, 0x82, + 0xB2, 0x43, 0xE8, 0x84, 0x83, 0x43, 0xE8, 0x84, + 0xBE, 0x43, 0xE8, 0x87, 0x98, 0x43, 0xE8, 0x87, // Bytes 1700 - 173f - 0x03, 0x28, 0x36, 0x29, 0x03, 0x28, 0x37, 0x29, - 0x03, 0x28, 0x38, 0x29, 0x03, 0x28, 0x39, 0x29, - 0x04, 0x28, 0x31, 0x30, 0x29, 0x04, 0x28, 0x31, - 0x31, 0x29, 0x04, 0x28, 0x31, 0x32, 0x29, 0x04, - 0x28, 0x31, 0x33, 0x29, 0x04, 0x28, 0x31, 0x34, - 0x29, 0x04, 0x28, 0x31, 0x35, 0x29, 0x04, 0x28, - 0x31, 0x36, 0x29, 0x04, 0x28, 0x31, 0x37, 0x29, - 0x04, 0x28, 0x31, 0x38, 0x29, 0x04, 0x28, 0x31, + 0xA3, 0x43, 0xE8, 0x87, 0xA8, 0x43, 0xE8, 0x87, + 0xAA, 0x43, 0xE8, 0x87, 0xAD, 0x43, 0xE8, 0x87, + 0xB3, 0x43, 0xE8, 0x87, 0xBC, 0x43, 0xE8, 0x88, + 0x81, 0x43, 0xE8, 0x88, 0x84, 0x43, 0xE8, 0x88, + 0x8C, 0x43, 0xE8, 0x88, 0x98, 0x43, 0xE8, 0x88, + 0x9B, 0x43, 0xE8, 0x88, 0x9F, 0x43, 0xE8, 0x89, + 0xAE, 0x43, 0xE8, 0x89, 0xAF, 0x43, 0xE8, 0x89, + 0xB2, 0x43, 0xE8, 0x89, 0xB8, 0x43, 0xE8, 0x89, // Bytes 1740 - 177f - 0x39, 0x29, 0x04, 0x28, 0x32, 0x30, 0x29, 0x02, - 0x31, 0x2E, 0x02, 0x32, 0x2E, 0x02, 0x33, 0x2E, - 0x02, 0x34, 0x2E, 0x02, 0x35, 0x2E, 0x02, 0x36, - 0x2E, 0x02, 0x37, 0x2E, 0x02, 0x38, 0x2E, 0x02, - 0x39, 0x2E, 0x03, 0x31, 0x30, 0x2E, 0x03, 0x31, - 0x31, 0x2E, 0x03, 0x31, 0x32, 0x2E, 0x03, 0x31, - 0x33, 0x2E, 0x03, 0x31, 0x34, 0x2E, 0x03, 0x31, - 0x35, 0x2E, 0x03, 0x31, 0x36, 0x2E, 0x03, 0x31, + 0xB9, 0x43, 0xE8, 0x8A, 0x8B, 0x43, 0xE8, 0x8A, + 0x91, 0x43, 0xE8, 0x8A, 0x9D, 0x43, 0xE8, 0x8A, + 0xB1, 0x43, 0xE8, 0x8A, 0xB3, 0x43, 0xE8, 0x8A, + 0xBD, 0x43, 0xE8, 0x8B, 0xA5, 0x43, 0xE8, 0x8B, + 0xA6, 0x43, 0xE8, 0x8C, 0x9D, 0x43, 0xE8, 0x8C, + 0xA3, 0x43, 0xE8, 0x8C, 0xB6, 0x43, 0xE8, 0x8D, + 0x92, 0x43, 0xE8, 0x8D, 0x93, 0x43, 0xE8, 0x8D, + 0xA3, 0x43, 0xE8, 0x8E, 0xAD, 0x43, 0xE8, 0x8E, // Bytes 1780 - 17bf - 0x37, 0x2E, 0x03, 0x31, 0x38, 0x2E, 0x03, 0x31, - 0x39, 0x2E, 0x03, 0x32, 0x30, 0x2E, 0x03, 0x28, - 0x61, 0x29, 0x03, 0x28, 0x62, 0x29, 0x03, 0x28, - 0x63, 0x29, 0x03, 0x28, 0x64, 0x29, 0x03, 0x28, - 0x65, 0x29, 0x03, 0x28, 0x66, 0x29, 0x03, 0x28, - 0x67, 0x29, 0x03, 0x28, 0x68, 0x29, 0x03, 0x28, - 0x69, 0x29, 0x03, 0x28, 0x6A, 0x29, 0x03, 0x28, - 0x6B, 0x29, 0x03, 0x28, 0x6C, 0x29, 0x03, 0x28, + 0xBD, 0x43, 0xE8, 0x8F, 0x89, 0x43, 0xE8, 0x8F, + 0x8A, 0x43, 0xE8, 0x8F, 0x8C, 0x43, 0xE8, 0x8F, + 0x9C, 0x43, 0xE8, 0x8F, 0xA7, 0x43, 0xE8, 0x8F, + 0xAF, 0x43, 0xE8, 0x8F, 0xB1, 0x43, 0xE8, 0x90, + 0xBD, 0x43, 0xE8, 0x91, 0x89, 0x43, 0xE8, 0x91, + 0x97, 0x43, 0xE8, 0x93, 0xAE, 0x43, 0xE8, 0x93, + 0xB1, 0x43, 0xE8, 0x93, 0xB3, 0x43, 0xE8, 0x93, + 0xBC, 0x43, 0xE8, 0x94, 0x96, 0x43, 0xE8, 0x95, // Bytes 17c0 - 17ff - 0x6D, 0x29, 0x03, 0x28, 0x6E, 0x29, 0x03, 0x28, - 0x6F, 0x29, 0x03, 0x28, 0x70, 0x29, 0x03, 0x28, - 0x71, 0x29, 0x03, 0x28, 0x72, 0x29, 0x03, 0x28, - 0x73, 0x29, 0x03, 0x28, 0x74, 0x29, 0x03, 0x28, - 0x75, 0x29, 0x03, 0x28, 0x76, 0x29, 0x03, 0x28, - 0x77, 0x29, 0x03, 0x28, 0x78, 0x29, 0x03, 0x28, - 0x79, 0x29, 0x03, 0x28, 0x7A, 0x29, 0x01, 0x53, - 0x01, 0x59, 0x01, 0x71, 0x0C, 0xE2, 0x88, 0xAB, + 0xA4, 0x43, 0xE8, 0x97, 0x8D, 0x43, 0xE8, 0x97, + 0xBA, 0x43, 0xE8, 0x98, 0x86, 0x43, 0xE8, 0x98, + 0x92, 0x43, 0xE8, 0x98, 0xAD, 0x43, 0xE8, 0x98, + 0xBF, 0x43, 0xE8, 0x99, 0x8D, 0x43, 0xE8, 0x99, + 0x90, 0x43, 0xE8, 0x99, 0x9C, 0x43, 0xE8, 0x99, + 0xA7, 0x43, 0xE8, 0x99, 0xA9, 0x43, 0xE8, 0x99, + 0xAB, 0x43, 0xE8, 0x9A, 0x88, 0x43, 0xE8, 0x9A, + 0xA9, 0x43, 0xE8, 0x9B, 0xA2, 0x43, 0xE8, 0x9C, // Bytes 1800 - 183f - 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, - 0xAB, 0x03, 0x3A, 0x3A, 0x3D, 0x02, 0x3D, 0x3D, - 0x03, 0x3D, 0x3D, 0x3D, 0x05, 0xE2, 0xAB, 0x9D, - 0xCC, 0xB8, 0x03, 0xE2, 0xB5, 0xA1, 0x03, 0xE6, - 0xAF, 0x8D, 0x03, 0xE9, 0xBE, 0x9F, 0x03, 0xE4, - 0xB8, 0x80, 0x03, 0xE4, 0xB8, 0xA8, 0x03, 0xE4, - 0xB8, 0xB6, 0x03, 0xE4, 0xB8, 0xBF, 0x03, 0xE4, - 0xB9, 0x99, 0x03, 0xE4, 0xBA, 0x85, 0x03, 0xE4, + 0x8E, 0x43, 0xE8, 0x9C, 0xA8, 0x43, 0xE8, 0x9D, + 0xAB, 0x43, 0xE8, 0x9D, 0xB9, 0x43, 0xE8, 0x9E, + 0x86, 0x43, 0xE8, 0x9E, 0xBA, 0x43, 0xE8, 0x9F, + 0xA1, 0x43, 0xE8, 0xA0, 0x81, 0x43, 0xE8, 0xA0, + 0x9F, 0x43, 0xE8, 0xA1, 0x80, 0x43, 0xE8, 0xA1, + 0x8C, 0x43, 0xE8, 0xA1, 0xA0, 0x43, 0xE8, 0xA1, + 0xA3, 0x43, 0xE8, 0xA3, 0x82, 0x43, 0xE8, 0xA3, + 0x8F, 0x43, 0xE8, 0xA3, 0x97, 0x43, 0xE8, 0xA3, // Bytes 1840 - 187f - 0xBA, 0x8C, 0x03, 0xE4, 0xBA, 0xA0, 0x03, 0xE4, - 0xBA, 0xBA, 0x03, 0xE5, 0x84, 0xBF, 0x03, 0xE5, - 0x85, 0xA5, 0x03, 0xE5, 0x85, 0xAB, 0x03, 0xE5, - 0x86, 0x82, 0x03, 0xE5, 0x86, 0x96, 0x03, 0xE5, - 0x86, 0xAB, 0x03, 0xE5, 0x87, 0xA0, 0x03, 0xE5, - 0x87, 0xB5, 0x03, 0xE5, 0x88, 0x80, 0x03, 0xE5, - 0x8A, 0x9B, 0x03, 0xE5, 0x8B, 0xB9, 0x03, 0xE5, - 0x8C, 0x95, 0x03, 0xE5, 0x8C, 0x9A, 0x03, 0xE5, + 0x9E, 0x43, 0xE8, 0xA3, 0xA1, 0x43, 0xE8, 0xA3, + 0xB8, 0x43, 0xE8, 0xA3, 0xBA, 0x43, 0xE8, 0xA4, + 0x90, 0x43, 0xE8, 0xA5, 0x81, 0x43, 0xE8, 0xA5, + 0xA4, 0x43, 0xE8, 0xA5, 0xBE, 0x43, 0xE8, 0xA6, + 0x86, 0x43, 0xE8, 0xA6, 0x8B, 0x43, 0xE8, 0xA6, + 0x96, 0x43, 0xE8, 0xA7, 0x92, 0x43, 0xE8, 0xA7, + 0xA3, 0x43, 0xE8, 0xA8, 0x80, 0x43, 0xE8, 0xAA, + 0xA0, 0x43, 0xE8, 0xAA, 0xAA, 0x43, 0xE8, 0xAA, // Bytes 1880 - 18bf - 0x8C, 0xB8, 0x03, 0xE5, 0x8D, 0x81, 0x03, 0xE5, - 0x8D, 0x9C, 0x03, 0xE5, 0x8D, 0xA9, 0x03, 0xE5, - 0x8E, 0x82, 0x03, 0xE5, 0x8E, 0xB6, 0x03, 0xE5, - 0x8F, 0x88, 0x03, 0xE5, 0x8F, 0xA3, 0x03, 0xE5, - 0x9B, 0x97, 0x03, 0xE5, 0x9C, 0x9F, 0x03, 0xE5, - 0xA3, 0xAB, 0x03, 0xE5, 0xA4, 0x82, 0x03, 0xE5, - 0xA4, 0x8A, 0x03, 0xE5, 0xA4, 0x95, 0x03, 0xE5, - 0xA4, 0xA7, 0x03, 0xE5, 0xA5, 0xB3, 0x03, 0xE5, + 0xBF, 0x43, 0xE8, 0xAB, 0x8B, 0x43, 0xE8, 0xAB, + 0x92, 0x43, 0xE8, 0xAB, 0x96, 0x43, 0xE8, 0xAB, + 0xAD, 0x43, 0xE8, 0xAB, 0xB8, 0x43, 0xE8, 0xAB, + 0xBE, 0x43, 0xE8, 0xAC, 0x81, 0x43, 0xE8, 0xAC, + 0xB9, 0x43, 0xE8, 0xAD, 0x98, 0x43, 0xE8, 0xAE, + 0x80, 0x43, 0xE8, 0xAE, 0x8A, 0x43, 0xE8, 0xB0, + 0xB7, 0x43, 0xE8, 0xB1, 0x86, 0x43, 0xE8, 0xB1, + 0x88, 0x43, 0xE8, 0xB1, 0x95, 0x43, 0xE8, 0xB1, // Bytes 18c0 - 18ff - 0xAD, 0x90, 0x03, 0xE5, 0xAE, 0x80, 0x03, 0xE5, - 0xAF, 0xB8, 0x03, 0xE5, 0xB0, 0x8F, 0x03, 0xE5, - 0xB0, 0xA2, 0x03, 0xE5, 0xB0, 0xB8, 0x03, 0xE5, - 0xB1, 0xAE, 0x03, 0xE5, 0xB1, 0xB1, 0x03, 0xE5, - 0xB7, 0x9B, 0x03, 0xE5, 0xB7, 0xA5, 0x03, 0xE5, - 0xB7, 0xB1, 0x03, 0xE5, 0xB7, 0xBE, 0x03, 0xE5, - 0xB9, 0xB2, 0x03, 0xE5, 0xB9, 0xBA, 0x03, 0xE5, - 0xB9, 0xBF, 0x03, 0xE5, 0xBB, 0xB4, 0x03, 0xE5, + 0xB8, 0x43, 0xE8, 0xB2, 0x9D, 0x43, 0xE8, 0xB2, + 0xA1, 0x43, 0xE8, 0xB2, 0xA9, 0x43, 0xE8, 0xB2, + 0xAB, 0x43, 0xE8, 0xB3, 0x81, 0x43, 0xE8, 0xB3, + 0x82, 0x43, 0xE8, 0xB3, 0x87, 0x43, 0xE8, 0xB3, + 0x88, 0x43, 0xE8, 0xB3, 0x93, 0x43, 0xE8, 0xB4, + 0x88, 0x43, 0xE8, 0xB4, 0x9B, 0x43, 0xE8, 0xB5, + 0xA4, 0x43, 0xE8, 0xB5, 0xB0, 0x43, 0xE8, 0xB5, + 0xB7, 0x43, 0xE8, 0xB6, 0xB3, 0x43, 0xE8, 0xB6, // Bytes 1900 - 193f - 0xBB, 0xBE, 0x03, 0xE5, 0xBC, 0x8B, 0x03, 0xE5, - 0xBC, 0x93, 0x03, 0xE5, 0xBD, 0x90, 0x03, 0xE5, - 0xBD, 0xA1, 0x03, 0xE5, 0xBD, 0xB3, 0x03, 0xE5, - 0xBF, 0x83, 0x03, 0xE6, 0x88, 0x88, 0x03, 0xE6, - 0x88, 0xB6, 0x03, 0xE6, 0x89, 0x8B, 0x03, 0xE6, - 0x94, 0xAF, 0x03, 0xE6, 0x94, 0xB4, 0x03, 0xE6, - 0x96, 0x87, 0x03, 0xE6, 0x96, 0x97, 0x03, 0xE6, - 0x96, 0xA4, 0x03, 0xE6, 0x96, 0xB9, 0x03, 0xE6, + 0xBC, 0x43, 0xE8, 0xB7, 0x8B, 0x43, 0xE8, 0xB7, + 0xAF, 0x43, 0xE8, 0xB7, 0xB0, 0x43, 0xE8, 0xBA, + 0xAB, 0x43, 0xE8, 0xBB, 0x8A, 0x43, 0xE8, 0xBB, + 0x94, 0x43, 0xE8, 0xBC, 0xA6, 0x43, 0xE8, 0xBC, + 0xAA, 0x43, 0xE8, 0xBC, 0xB8, 0x43, 0xE8, 0xBC, + 0xBB, 0x43, 0xE8, 0xBD, 0xA2, 0x43, 0xE8, 0xBE, + 0x9B, 0x43, 0xE8, 0xBE, 0x9E, 0x43, 0xE8, 0xBE, + 0xB0, 0x43, 0xE8, 0xBE, 0xB5, 0x43, 0xE8, 0xBE, // Bytes 1940 - 197f - 0x97, 0xA0, 0x03, 0xE6, 0x97, 0xA5, 0x03, 0xE6, - 0x9B, 0xB0, 0x03, 0xE6, 0x9C, 0x88, 0x03, 0xE6, - 0x9C, 0xA8, 0x03, 0xE6, 0xAC, 0xA0, 0x03, 0xE6, - 0xAD, 0xA2, 0x03, 0xE6, 0xAD, 0xB9, 0x03, 0xE6, - 0xAE, 0xB3, 0x03, 0xE6, 0xAF, 0x8B, 0x03, 0xE6, - 0xAF, 0x94, 0x03, 0xE6, 0xAF, 0x9B, 0x03, 0xE6, - 0xB0, 0x8F, 0x03, 0xE6, 0xB0, 0x94, 0x03, 0xE6, - 0xB0, 0xB4, 0x03, 0xE7, 0x81, 0xAB, 0x03, 0xE7, + 0xB6, 0x43, 0xE9, 0x80, 0xA3, 0x43, 0xE9, 0x80, + 0xB8, 0x43, 0xE9, 0x81, 0x8A, 0x43, 0xE9, 0x81, + 0xA9, 0x43, 0xE9, 0x81, 0xB2, 0x43, 0xE9, 0x81, + 0xBC, 0x43, 0xE9, 0x82, 0x8F, 0x43, 0xE9, 0x82, + 0x91, 0x43, 0xE9, 0x82, 0x94, 0x43, 0xE9, 0x83, + 0x8E, 0x43, 0xE9, 0x83, 0xB1, 0x43, 0xE9, 0x83, + 0xBD, 0x43, 0xE9, 0x84, 0x91, 0x43, 0xE9, 0x84, + 0x9B, 0x43, 0xE9, 0x85, 0x89, 0x43, 0xE9, 0x85, // Bytes 1980 - 19bf - 0x88, 0xAA, 0x03, 0xE7, 0x88, 0xB6, 0x03, 0xE7, - 0x88, 0xBB, 0x03, 0xE7, 0x88, 0xBF, 0x03, 0xE7, - 0x89, 0x87, 0x03, 0xE7, 0x89, 0x99, 0x03, 0xE7, - 0x89, 0x9B, 0x03, 0xE7, 0x8A, 0xAC, 0x03, 0xE7, - 0x8E, 0x84, 0x03, 0xE7, 0x8E, 0x89, 0x03, 0xE7, - 0x93, 0x9C, 0x03, 0xE7, 0x93, 0xA6, 0x03, 0xE7, - 0x94, 0x98, 0x03, 0xE7, 0x94, 0x9F, 0x03, 0xE7, - 0x94, 0xA8, 0x03, 0xE7, 0x94, 0xB0, 0x03, 0xE7, + 0xAA, 0x43, 0xE9, 0x86, 0x99, 0x43, 0xE9, 0x86, + 0xB4, 0x43, 0xE9, 0x87, 0x86, 0x43, 0xE9, 0x87, + 0x8C, 0x43, 0xE9, 0x87, 0x8F, 0x43, 0xE9, 0x87, + 0x91, 0x43, 0xE9, 0x88, 0xB4, 0x43, 0xE9, 0x88, + 0xB8, 0x43, 0xE9, 0x89, 0xB6, 0x43, 0xE9, 0x89, + 0xBC, 0x43, 0xE9, 0x8B, 0x97, 0x43, 0xE9, 0x8B, + 0x98, 0x43, 0xE9, 0x8C, 0x84, 0x43, 0xE9, 0x8D, + 0x8A, 0x43, 0xE9, 0x8F, 0xB9, 0x43, 0xE9, 0x90, // Bytes 19c0 - 19ff - 0x96, 0x8B, 0x03, 0xE7, 0x96, 0x92, 0x03, 0xE7, - 0x99, 0xB6, 0x03, 0xE7, 0x99, 0xBD, 0x03, 0xE7, - 0x9A, 0xAE, 0x03, 0xE7, 0x9A, 0xBF, 0x03, 0xE7, - 0x9B, 0xAE, 0x03, 0xE7, 0x9F, 0x9B, 0x03, 0xE7, - 0x9F, 0xA2, 0x03, 0xE7, 0x9F, 0xB3, 0x03, 0xE7, - 0xA4, 0xBA, 0x03, 0xE7, 0xA6, 0xB8, 0x03, 0xE7, - 0xA6, 0xBE, 0x03, 0xE7, 0xA9, 0xB4, 0x03, 0xE7, - 0xAB, 0x8B, 0x03, 0xE7, 0xAB, 0xB9, 0x03, 0xE7, + 0x95, 0x43, 0xE9, 0x95, 0xB7, 0x43, 0xE9, 0x96, + 0x80, 0x43, 0xE9, 0x96, 0x8B, 0x43, 0xE9, 0x96, + 0xAD, 0x43, 0xE9, 0x96, 0xB7, 0x43, 0xE9, 0x98, + 0x9C, 0x43, 0xE9, 0x98, 0xAE, 0x43, 0xE9, 0x99, + 0x8B, 0x43, 0xE9, 0x99, 0x8D, 0x43, 0xE9, 0x99, + 0xB5, 0x43, 0xE9, 0x99, 0xB8, 0x43, 0xE9, 0x99, + 0xBC, 0x43, 0xE9, 0x9A, 0x86, 0x43, 0xE9, 0x9A, + 0xA3, 0x43, 0xE9, 0x9A, 0xB6, 0x43, 0xE9, 0x9A, // Bytes 1a00 - 1a3f - 0xB1, 0xB3, 0x03, 0xE7, 0xB3, 0xB8, 0x03, 0xE7, - 0xBC, 0xB6, 0x03, 0xE7, 0xBD, 0x91, 0x03, 0xE7, - 0xBE, 0x8A, 0x03, 0xE7, 0xBE, 0xBD, 0x03, 0xE8, - 0x80, 0x81, 0x03, 0xE8, 0x80, 0x8C, 0x03, 0xE8, - 0x80, 0x92, 0x03, 0xE8, 0x80, 0xB3, 0x03, 0xE8, - 0x81, 0xBF, 0x03, 0xE8, 0x82, 0x89, 0x03, 0xE8, - 0x87, 0xA3, 0x03, 0xE8, 0x87, 0xAA, 0x03, 0xE8, - 0x87, 0xB3, 0x03, 0xE8, 0x87, 0xBC, 0x03, 0xE8, + 0xB8, 0x43, 0xE9, 0x9A, 0xB9, 0x43, 0xE9, 0x9B, + 0x83, 0x43, 0xE9, 0x9B, 0xA2, 0x43, 0xE9, 0x9B, + 0xA3, 0x43, 0xE9, 0x9B, 0xA8, 0x43, 0xE9, 0x9B, + 0xB6, 0x43, 0xE9, 0x9B, 0xB7, 0x43, 0xE9, 0x9C, + 0xA3, 0x43, 0xE9, 0x9C, 0xB2, 0x43, 0xE9, 0x9D, + 0x88, 0x43, 0xE9, 0x9D, 0x91, 0x43, 0xE9, 0x9D, + 0x96, 0x43, 0xE9, 0x9D, 0x9E, 0x43, 0xE9, 0x9D, + 0xA2, 0x43, 0xE9, 0x9D, 0xA9, 0x43, 0xE9, 0x9F, // Bytes 1a40 - 1a7f - 0x88, 0x8C, 0x03, 0xE8, 0x88, 0x9B, 0x03, 0xE8, - 0x88, 0x9F, 0x03, 0xE8, 0x89, 0xAE, 0x03, 0xE8, - 0x89, 0xB2, 0x03, 0xE8, 0x89, 0xB8, 0x03, 0xE8, - 0x99, 0x8D, 0x03, 0xE8, 0x99, 0xAB, 0x03, 0xE8, - 0xA1, 0x80, 0x03, 0xE8, 0xA1, 0x8C, 0x03, 0xE8, - 0xA1, 0xA3, 0x03, 0xE8, 0xA5, 0xBE, 0x03, 0xE8, - 0xA6, 0x8B, 0x03, 0xE8, 0xA7, 0x92, 0x03, 0xE8, - 0xA8, 0x80, 0x03, 0xE8, 0xB0, 0xB7, 0x03, 0xE8, + 0x8B, 0x43, 0xE9, 0x9F, 0x9B, 0x43, 0xE9, 0x9F, + 0xA0, 0x43, 0xE9, 0x9F, 0xAD, 0x43, 0xE9, 0x9F, + 0xB3, 0x43, 0xE9, 0x9F, 0xBF, 0x43, 0xE9, 0xA0, + 0x81, 0x43, 0xE9, 0xA0, 0x85, 0x43, 0xE9, 0xA0, + 0x8B, 0x43, 0xE9, 0xA0, 0x98, 0x43, 0xE9, 0xA0, + 0xA9, 0x43, 0xE9, 0xA0, 0xBB, 0x43, 0xE9, 0xA1, + 0x9E, 0x43, 0xE9, 0xA2, 0xA8, 0x43, 0xE9, 0xA3, + 0x9B, 0x43, 0xE9, 0xA3, 0x9F, 0x43, 0xE9, 0xA3, // Bytes 1a80 - 1abf - 0xB1, 0x86, 0x03, 0xE8, 0xB1, 0x95, 0x03, 0xE8, - 0xB1, 0xB8, 0x03, 0xE8, 0xB2, 0x9D, 0x03, 0xE8, - 0xB5, 0xA4, 0x03, 0xE8, 0xB5, 0xB0, 0x03, 0xE8, - 0xB6, 0xB3, 0x03, 0xE8, 0xBA, 0xAB, 0x03, 0xE8, - 0xBB, 0x8A, 0x03, 0xE8, 0xBE, 0x9B, 0x03, 0xE8, - 0xBE, 0xB0, 0x03, 0xE8, 0xBE, 0xB5, 0x03, 0xE9, - 0x82, 0x91, 0x03, 0xE9, 0x85, 0x89, 0x03, 0xE9, - 0x87, 0x86, 0x03, 0xE9, 0x87, 0x8C, 0x03, 0xE9, + 0xA2, 0x43, 0xE9, 0xA3, 0xAF, 0x43, 0xE9, 0xA3, + 0xBC, 0x43, 0xE9, 0xA4, 0xA8, 0x43, 0xE9, 0xA4, + 0xA9, 0x43, 0xE9, 0xA6, 0x96, 0x43, 0xE9, 0xA6, + 0x99, 0x43, 0xE9, 0xA6, 0xA7, 0x43, 0xE9, 0xA6, + 0xAC, 0x43, 0xE9, 0xA7, 0x82, 0x43, 0xE9, 0xA7, + 0xB1, 0x43, 0xE9, 0xA7, 0xBE, 0x43, 0xE9, 0xA9, + 0xAA, 0x43, 0xE9, 0xAA, 0xA8, 0x43, 0xE9, 0xAB, + 0x98, 0x43, 0xE9, 0xAB, 0x9F, 0x43, 0xE9, 0xAC, // Bytes 1ac0 - 1aff - 0x87, 0x91, 0x03, 0xE9, 0x95, 0xB7, 0x03, 0xE9, - 0x96, 0x80, 0x03, 0xE9, 0x98, 0x9C, 0x03, 0xE9, - 0x9A, 0xB6, 0x03, 0xE9, 0x9A, 0xB9, 0x03, 0xE9, - 0x9B, 0xA8, 0x03, 0xE9, 0x9D, 0x91, 0x03, 0xE9, - 0x9D, 0x9E, 0x03, 0xE9, 0x9D, 0xA2, 0x03, 0xE9, - 0x9D, 0xA9, 0x03, 0xE9, 0x9F, 0x8B, 0x03, 0xE9, - 0x9F, 0xAD, 0x03, 0xE9, 0x9F, 0xB3, 0x03, 0xE9, - 0xA0, 0x81, 0x03, 0xE9, 0xA2, 0xA8, 0x03, 0xE9, + 0x92, 0x43, 0xE9, 0xAC, 0xA5, 0x43, 0xE9, 0xAC, + 0xAF, 0x43, 0xE9, 0xAC, 0xB2, 0x43, 0xE9, 0xAC, + 0xBC, 0x43, 0xE9, 0xAD, 0x9A, 0x43, 0xE9, 0xAD, + 0xAF, 0x43, 0xE9, 0xB1, 0x80, 0x43, 0xE9, 0xB1, + 0x97, 0x43, 0xE9, 0xB3, 0xA5, 0x43, 0xE9, 0xB3, + 0xBD, 0x43, 0xE9, 0xB5, 0xA7, 0x43, 0xE9, 0xB6, + 0xB4, 0x43, 0xE9, 0xB7, 0xBA, 0x43, 0xE9, 0xB8, + 0x9E, 0x43, 0xE9, 0xB9, 0xB5, 0x43, 0xE9, 0xB9, // Bytes 1b00 - 1b3f - 0xA3, 0x9B, 0x03, 0xE9, 0xA3, 0x9F, 0x03, 0xE9, - 0xA6, 0x96, 0x03, 0xE9, 0xA6, 0x99, 0x03, 0xE9, - 0xA6, 0xAC, 0x03, 0xE9, 0xAA, 0xA8, 0x03, 0xE9, - 0xAB, 0x98, 0x03, 0xE9, 0xAB, 0x9F, 0x03, 0xE9, - 0xAC, 0xA5, 0x03, 0xE9, 0xAC, 0xAF, 0x03, 0xE9, - 0xAC, 0xB2, 0x03, 0xE9, 0xAC, 0xBC, 0x03, 0xE9, - 0xAD, 0x9A, 0x03, 0xE9, 0xB3, 0xA5, 0x03, 0xE9, - 0xB9, 0xB5, 0x03, 0xE9, 0xB9, 0xBF, 0x03, 0xE9, + 0xBF, 0x43, 0xE9, 0xBA, 0x97, 0x43, 0xE9, 0xBA, + 0x9F, 0x43, 0xE9, 0xBA, 0xA5, 0x43, 0xE9, 0xBA, + 0xBB, 0x43, 0xE9, 0xBB, 0x83, 0x43, 0xE9, 0xBB, + 0x8D, 0x43, 0xE9, 0xBB, 0x8E, 0x43, 0xE9, 0xBB, + 0x91, 0x43, 0xE9, 0xBB, 0xB9, 0x43, 0xE9, 0xBB, + 0xBD, 0x43, 0xE9, 0xBB, 0xBE, 0x43, 0xE9, 0xBC, + 0x85, 0x43, 0xE9, 0xBC, 0x8E, 0x43, 0xE9, 0xBC, + 0x8F, 0x43, 0xE9, 0xBC, 0x93, 0x43, 0xE9, 0xBC, // Bytes 1b40 - 1b7f - 0xBA, 0xA5, 0x03, 0xE9, 0xBA, 0xBB, 0x03, 0xE9, - 0xBB, 0x83, 0x03, 0xE9, 0xBB, 0x8D, 0x03, 0xE9, - 0xBB, 0x91, 0x03, 0xE9, 0xBB, 0xB9, 0x03, 0xE9, - 0xBB, 0xBD, 0x03, 0xE9, 0xBC, 0x8E, 0x03, 0xE9, - 0xBC, 0x93, 0x03, 0xE9, 0xBC, 0xA0, 0x03, 0xE9, - 0xBC, 0xBB, 0x03, 0xE9, 0xBD, 0x8A, 0x03, 0xE9, - 0xBD, 0x92, 0x03, 0xE9, 0xBE, 0x8D, 0x03, 0xE9, - 0xBE, 0x9C, 0x03, 0xE9, 0xBE, 0xA0, 0x03, 0xE3, + 0x96, 0x43, 0xE9, 0xBC, 0xA0, 0x43, 0xE9, 0xBC, + 0xBB, 0x43, 0xE9, 0xBD, 0x83, 0x43, 0xE9, 0xBD, + 0x8A, 0x43, 0xE9, 0xBD, 0x92, 0x43, 0xE9, 0xBE, + 0x8D, 0x43, 0xE9, 0xBE, 0x8E, 0x43, 0xE9, 0xBE, + 0x9C, 0x43, 0xE9, 0xBE, 0x9F, 0x43, 0xE9, 0xBE, + 0xA0, 0x43, 0xEA, 0x9D, 0xAF, 0x44, 0x28, 0x31, + 0x30, 0x29, 0x44, 0x28, 0x31, 0x31, 0x29, 0x44, + 0x28, 0x31, 0x32, 0x29, 0x44, 0x28, 0x31, 0x33, // Bytes 1b80 - 1bbf - 0x80, 0x92, 0x03, 0xE5, 0x8D, 0x84, 0x03, 0xE5, - 0x8D, 0x85, 0x06, 0xE3, 0x81, 0x8B, 0xE3, 0x82, - 0x99, 0x06, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, - 0x06, 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x06, - 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x81, 0x93, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, - 0x95, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0x97, - 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0x99, 0xE3, + 0x29, 0x44, 0x28, 0x31, 0x34, 0x29, 0x44, 0x28, + 0x31, 0x35, 0x29, 0x44, 0x28, 0x31, 0x36, 0x29, + 0x44, 0x28, 0x31, 0x37, 0x29, 0x44, 0x28, 0x31, + 0x38, 0x29, 0x44, 0x28, 0x31, 0x39, 0x29, 0x44, + 0x28, 0x32, 0x30, 0x29, 0x44, 0x30, 0xE7, 0x82, + 0xB9, 0x44, 0x31, 0xE2, 0x81, 0x84, 0x44, 0x31, + 0xE6, 0x97, 0xA5, 0x44, 0x31, 0xE6, 0x9C, 0x88, + 0x44, 0x31, 0xE7, 0x82, 0xB9, 0x44, 0x32, 0xE6, // Bytes 1bc0 - 1bff - 0x82, 0x99, 0x06, 0xE3, 0x81, 0x9B, 0xE3, 0x82, - 0x99, 0x06, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, - 0x06, 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x06, - 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, - 0xA6, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xA8, - 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xAF, 0xE3, - 0x82, 0x99, 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, + 0x97, 0xA5, 0x44, 0x32, 0xE6, 0x9C, 0x88, 0x44, + 0x32, 0xE7, 0x82, 0xB9, 0x44, 0x33, 0xE6, 0x97, + 0xA5, 0x44, 0x33, 0xE6, 0x9C, 0x88, 0x44, 0x33, + 0xE7, 0x82, 0xB9, 0x44, 0x34, 0xE6, 0x97, 0xA5, + 0x44, 0x34, 0xE6, 0x9C, 0x88, 0x44, 0x34, 0xE7, + 0x82, 0xB9, 0x44, 0x35, 0xE6, 0x97, 0xA5, 0x44, + 0x35, 0xE6, 0x9C, 0x88, 0x44, 0x35, 0xE7, 0x82, + 0xB9, 0x44, 0x36, 0xE6, 0x97, 0xA5, 0x44, 0x36, // Bytes 1c00 - 1c3f - 0x9A, 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, - 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x06, - 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x81, - 0xB8, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x81, 0xB8, - 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x81, 0xBB, 0xE3, - 0x82, 0x99, 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, - 0x9A, 0x06, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, + 0xE6, 0x9C, 0x88, 0x44, 0x36, 0xE7, 0x82, 0xB9, + 0x44, 0x37, 0xE6, 0x97, 0xA5, 0x44, 0x37, 0xE6, + 0x9C, 0x88, 0x44, 0x37, 0xE7, 0x82, 0xB9, 0x44, + 0x38, 0xE6, 0x97, 0xA5, 0x44, 0x38, 0xE6, 0x9C, + 0x88, 0x44, 0x38, 0xE7, 0x82, 0xB9, 0x44, 0x39, + 0xE6, 0x97, 0xA5, 0x44, 0x39, 0xE6, 0x9C, 0x88, + 0x44, 0x39, 0xE7, 0x82, 0xB9, 0x44, 0x56, 0x49, + 0x49, 0x49, 0x44, 0x61, 0x2E, 0x6D, 0x2E, 0x44, // Bytes 1c40 - 1c7f - 0x04, 0x20, 0xE3, 0x82, 0x99, 0x04, 0x20, 0xE3, - 0x82, 0x9A, 0x06, 0xE3, 0x82, 0x9D, 0xE3, 0x82, - 0x99, 0x06, 0xE3, 0x82, 0x88, 0xE3, 0x82, 0x8A, - 0x06, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x06, - 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, - 0xB1, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB3, - 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB5, 0xE3, + 0x6B, 0x63, 0x61, 0x6C, 0x44, 0x70, 0x2E, 0x6D, + 0x2E, 0x44, 0x76, 0x69, 0x69, 0x69, 0x44, 0xD5, + 0xA5, 0xD6, 0x82, 0x44, 0xD5, 0xB4, 0xD5, 0xA5, + 0x44, 0xD5, 0xB4, 0xD5, 0xAB, 0x44, 0xD5, 0xB4, + 0xD5, 0xAD, 0x44, 0xD5, 0xB4, 0xD5, 0xB6, 0x44, + 0xD5, 0xBE, 0xD5, 0xB6, 0x44, 0xD7, 0x90, 0xD7, + 0x9C, 0x44, 0xD8, 0xA7, 0xD9, 0xB4, 0x44, 0xD8, + 0xA8, 0xD8, 0xAC, 0x44, 0xD8, 0xA8, 0xD8, 0xAD, // Bytes 1c80 - 1cbf - 0x82, 0x99, 0x06, 0xE3, 0x82, 0xB7, 0xE3, 0x82, - 0x99, 0x06, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, - 0x06, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x06, - 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, - 0x81, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x84, - 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x86, 0xE3, - 0x82, 0x99, 0x06, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0x44, 0xD8, 0xA8, 0xD8, 0xAE, 0x44, 0xD8, 0xA8, + 0xD8, 0xB1, 0x44, 0xD8, 0xA8, 0xD8, 0xB2, 0x44, + 0xD8, 0xA8, 0xD9, 0x85, 0x44, 0xD8, 0xA8, 0xD9, + 0x86, 0x44, 0xD8, 0xA8, 0xD9, 0x87, 0x44, 0xD8, + 0xA8, 0xD9, 0x89, 0x44, 0xD8, 0xA8, 0xD9, 0x8A, + 0x44, 0xD8, 0xAA, 0xD8, 0xAC, 0x44, 0xD8, 0xAA, + 0xD8, 0xAD, 0x44, 0xD8, 0xAA, 0xD8, 0xAE, 0x44, + 0xD8, 0xAA, 0xD8, 0xB1, 0x44, 0xD8, 0xAA, 0xD8, // Bytes 1cc0 - 1cff - 0x99, 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, - 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x06, - 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x83, - 0x95, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0x95, - 0xE3, 0x82, 0x9A, 0x06, 0xE3, 0x83, 0x98, 0xE3, - 0x82, 0x99, 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, - 0x9A, 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, + 0xB2, 0x44, 0xD8, 0xAA, 0xD9, 0x85, 0x44, 0xD8, + 0xAA, 0xD9, 0x86, 0x44, 0xD8, 0xAA, 0xD9, 0x87, + 0x44, 0xD8, 0xAA, 0xD9, 0x89, 0x44, 0xD8, 0xAA, + 0xD9, 0x8A, 0x44, 0xD8, 0xAB, 0xD8, 0xAC, 0x44, + 0xD8, 0xAB, 0xD8, 0xB1, 0x44, 0xD8, 0xAB, 0xD8, + 0xB2, 0x44, 0xD8, 0xAB, 0xD9, 0x85, 0x44, 0xD8, + 0xAB, 0xD9, 0x86, 0x44, 0xD8, 0xAB, 0xD9, 0x87, + 0x44, 0xD8, 0xAB, 0xD9, 0x89, 0x44, 0xD8, 0xAB, // Bytes 1d00 - 1d3f - 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x06, - 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x06, 0xE3, - 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, - 0xB0, 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0xB1, - 0xE3, 0x82, 0x99, 0x06, 0xE3, 0x83, 0xB2, 0xE3, - 0x82, 0x99, 0x06, 0xE3, 0x83, 0xBD, 0xE3, 0x82, - 0x99, 0x06, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, - 0x03, 0xE1, 0x84, 0x80, 0x03, 0xE1, 0x84, 0x81, + 0xD9, 0x8A, 0x44, 0xD8, 0xAC, 0xD8, 0xAD, 0x44, + 0xD8, 0xAC, 0xD9, 0x85, 0x44, 0xD8, 0xAC, 0xD9, + 0x89, 0x44, 0xD8, 0xAC, 0xD9, 0x8A, 0x44, 0xD8, + 0xAD, 0xD8, 0xAC, 0x44, 0xD8, 0xAD, 0xD9, 0x85, + 0x44, 0xD8, 0xAD, 0xD9, 0x89, 0x44, 0xD8, 0xAD, + 0xD9, 0x8A, 0x44, 0xD8, 0xAE, 0xD8, 0xAC, 0x44, + 0xD8, 0xAE, 0xD8, 0xAD, 0x44, 0xD8, 0xAE, 0xD9, + 0x85, 0x44, 0xD8, 0xAE, 0xD9, 0x89, 0x44, 0xD8, // Bytes 1d40 - 1d7f - 0x03, 0xE1, 0x86, 0xAA, 0x03, 0xE1, 0x84, 0x82, - 0x03, 0xE1, 0x86, 0xAC, 0x03, 0xE1, 0x86, 0xAD, - 0x03, 0xE1, 0x84, 0x83, 0x03, 0xE1, 0x84, 0x84, - 0x03, 0xE1, 0x84, 0x85, 0x03, 0xE1, 0x86, 0xB0, - 0x03, 0xE1, 0x86, 0xB1, 0x03, 0xE1, 0x86, 0xB2, - 0x03, 0xE1, 0x86, 0xB3, 0x03, 0xE1, 0x86, 0xB4, - 0x03, 0xE1, 0x86, 0xB5, 0x03, 0xE1, 0x84, 0x9A, - 0x03, 0xE1, 0x84, 0x86, 0x03, 0xE1, 0x84, 0x87, + 0xAE, 0xD9, 0x8A, 0x44, 0xD8, 0xB3, 0xD8, 0xAC, + 0x44, 0xD8, 0xB3, 0xD8, 0xAD, 0x44, 0xD8, 0xB3, + 0xD8, 0xAE, 0x44, 0xD8, 0xB3, 0xD8, 0xB1, 0x44, + 0xD8, 0xB3, 0xD9, 0x85, 0x44, 0xD8, 0xB3, 0xD9, + 0x87, 0x44, 0xD8, 0xB3, 0xD9, 0x89, 0x44, 0xD8, + 0xB3, 0xD9, 0x8A, 0x44, 0xD8, 0xB4, 0xD8, 0xAC, + 0x44, 0xD8, 0xB4, 0xD8, 0xAD, 0x44, 0xD8, 0xB4, + 0xD8, 0xAE, 0x44, 0xD8, 0xB4, 0xD8, 0xB1, 0x44, // Bytes 1d80 - 1dbf - 0x03, 0xE1, 0x84, 0x88, 0x03, 0xE1, 0x84, 0xA1, - 0x03, 0xE1, 0x84, 0x89, 0x03, 0xE1, 0x84, 0x8A, - 0x03, 0xE1, 0x84, 0x8B, 0x03, 0xE1, 0x84, 0x8C, - 0x03, 0xE1, 0x84, 0x8D, 0x03, 0xE1, 0x84, 0x8E, - 0x03, 0xE1, 0x84, 0x8F, 0x03, 0xE1, 0x84, 0x90, - 0x03, 0xE1, 0x84, 0x91, 0x03, 0xE1, 0x84, 0x92, - 0x03, 0xE1, 0x85, 0xA1, 0x03, 0xE1, 0x85, 0xA2, - 0x03, 0xE1, 0x85, 0xA3, 0x03, 0xE1, 0x85, 0xA4, + 0xD8, 0xB4, 0xD9, 0x85, 0x44, 0xD8, 0xB4, 0xD9, + 0x87, 0x44, 0xD8, 0xB4, 0xD9, 0x89, 0x44, 0xD8, + 0xB4, 0xD9, 0x8A, 0x44, 0xD8, 0xB5, 0xD8, 0xAD, + 0x44, 0xD8, 0xB5, 0xD8, 0xAE, 0x44, 0xD8, 0xB5, + 0xD8, 0xB1, 0x44, 0xD8, 0xB5, 0xD9, 0x85, 0x44, + 0xD8, 0xB5, 0xD9, 0x89, 0x44, 0xD8, 0xB5, 0xD9, + 0x8A, 0x44, 0xD8, 0xB6, 0xD8, 0xAC, 0x44, 0xD8, + 0xB6, 0xD8, 0xAD, 0x44, 0xD8, 0xB6, 0xD8, 0xAE, // Bytes 1dc0 - 1dff - 0x03, 0xE1, 0x85, 0xA5, 0x03, 0xE1, 0x85, 0xA6, - 0x03, 0xE1, 0x85, 0xA7, 0x03, 0xE1, 0x85, 0xA8, - 0x03, 0xE1, 0x85, 0xA9, 0x03, 0xE1, 0x85, 0xAA, - 0x03, 0xE1, 0x85, 0xAB, 0x03, 0xE1, 0x85, 0xAC, - 0x03, 0xE1, 0x85, 0xAD, 0x03, 0xE1, 0x85, 0xAE, - 0x03, 0xE1, 0x85, 0xAF, 0x03, 0xE1, 0x85, 0xB0, - 0x03, 0xE1, 0x85, 0xB1, 0x03, 0xE1, 0x85, 0xB2, - 0x03, 0xE1, 0x85, 0xB3, 0x03, 0xE1, 0x85, 0xB4, + 0x44, 0xD8, 0xB6, 0xD8, 0xB1, 0x44, 0xD8, 0xB6, + 0xD9, 0x85, 0x44, 0xD8, 0xB6, 0xD9, 0x89, 0x44, + 0xD8, 0xB6, 0xD9, 0x8A, 0x44, 0xD8, 0xB7, 0xD8, + 0xAD, 0x44, 0xD8, 0xB7, 0xD9, 0x85, 0x44, 0xD8, + 0xB7, 0xD9, 0x89, 0x44, 0xD8, 0xB7, 0xD9, 0x8A, + 0x44, 0xD8, 0xB8, 0xD9, 0x85, 0x44, 0xD8, 0xB9, + 0xD8, 0xAC, 0x44, 0xD8, 0xB9, 0xD9, 0x85, 0x44, + 0xD8, 0xB9, 0xD9, 0x89, 0x44, 0xD8, 0xB9, 0xD9, // Bytes 1e00 - 1e3f - 0x03, 0xE1, 0x85, 0xB5, 0x03, 0xE1, 0x85, 0xA0, - 0x03, 0xE1, 0x84, 0x94, 0x03, 0xE1, 0x84, 0x95, - 0x03, 0xE1, 0x87, 0x87, 0x03, 0xE1, 0x87, 0x88, - 0x03, 0xE1, 0x87, 0x8C, 0x03, 0xE1, 0x87, 0x8E, - 0x03, 0xE1, 0x87, 0x93, 0x03, 0xE1, 0x87, 0x97, - 0x03, 0xE1, 0x87, 0x99, 0x03, 0xE1, 0x84, 0x9C, - 0x03, 0xE1, 0x87, 0x9D, 0x03, 0xE1, 0x87, 0x9F, - 0x03, 0xE1, 0x84, 0x9D, 0x03, 0xE1, 0x84, 0x9E, + 0x8A, 0x44, 0xD8, 0xBA, 0xD8, 0xAC, 0x44, 0xD8, + 0xBA, 0xD9, 0x85, 0x44, 0xD8, 0xBA, 0xD9, 0x89, + 0x44, 0xD8, 0xBA, 0xD9, 0x8A, 0x44, 0xD9, 0x81, + 0xD8, 0xAC, 0x44, 0xD9, 0x81, 0xD8, 0xAD, 0x44, + 0xD9, 0x81, 0xD8, 0xAE, 0x44, 0xD9, 0x81, 0xD9, + 0x85, 0x44, 0xD9, 0x81, 0xD9, 0x89, 0x44, 0xD9, + 0x81, 0xD9, 0x8A, 0x44, 0xD9, 0x82, 0xD8, 0xAD, + 0x44, 0xD9, 0x82, 0xD9, 0x85, 0x44, 0xD9, 0x82, // Bytes 1e40 - 1e7f - 0x03, 0xE1, 0x84, 0xA0, 0x03, 0xE1, 0x84, 0xA2, - 0x03, 0xE1, 0x84, 0xA3, 0x03, 0xE1, 0x84, 0xA7, - 0x03, 0xE1, 0x84, 0xA9, 0x03, 0xE1, 0x84, 0xAB, - 0x03, 0xE1, 0x84, 0xAC, 0x03, 0xE1, 0x84, 0xAD, - 0x03, 0xE1, 0x84, 0xAE, 0x03, 0xE1, 0x84, 0xAF, - 0x03, 0xE1, 0x84, 0xB2, 0x03, 0xE1, 0x84, 0xB6, - 0x03, 0xE1, 0x85, 0x80, 0x03, 0xE1, 0x85, 0x87, - 0x03, 0xE1, 0x85, 0x8C, 0x03, 0xE1, 0x87, 0xB1, + 0xD9, 0x89, 0x44, 0xD9, 0x82, 0xD9, 0x8A, 0x44, + 0xD9, 0x83, 0xD8, 0xA7, 0x44, 0xD9, 0x83, 0xD8, + 0xAC, 0x44, 0xD9, 0x83, 0xD8, 0xAD, 0x44, 0xD9, + 0x83, 0xD8, 0xAE, 0x44, 0xD9, 0x83, 0xD9, 0x84, + 0x44, 0xD9, 0x83, 0xD9, 0x85, 0x44, 0xD9, 0x83, + 0xD9, 0x89, 0x44, 0xD9, 0x83, 0xD9, 0x8A, 0x44, + 0xD9, 0x84, 0xD8, 0xA7, 0x44, 0xD9, 0x84, 0xD8, + 0xAC, 0x44, 0xD9, 0x84, 0xD8, 0xAD, 0x44, 0xD9, // Bytes 1e80 - 1ebf - 0x03, 0xE1, 0x87, 0xB2, 0x03, 0xE1, 0x85, 0x97, - 0x03, 0xE1, 0x85, 0x98, 0x03, 0xE1, 0x85, 0x99, - 0x03, 0xE1, 0x86, 0x84, 0x03, 0xE1, 0x86, 0x85, - 0x03, 0xE1, 0x86, 0x88, 0x03, 0xE1, 0x86, 0x91, - 0x03, 0xE1, 0x86, 0x92, 0x03, 0xE1, 0x86, 0x94, - 0x03, 0xE1, 0x86, 0x9E, 0x03, 0xE1, 0x86, 0xA1, - 0x03, 0xE4, 0xB8, 0x89, 0x03, 0xE5, 0x9B, 0x9B, - 0x03, 0xE4, 0xB8, 0x8A, 0x03, 0xE4, 0xB8, 0xAD, + 0x84, 0xD8, 0xAE, 0x44, 0xD9, 0x84, 0xD9, 0x85, + 0x44, 0xD9, 0x84, 0xD9, 0x87, 0x44, 0xD9, 0x84, + 0xD9, 0x89, 0x44, 0xD9, 0x84, 0xD9, 0x8A, 0x44, + 0xD9, 0x85, 0xD8, 0xA7, 0x44, 0xD9, 0x85, 0xD8, + 0xAC, 0x44, 0xD9, 0x85, 0xD8, 0xAD, 0x44, 0xD9, + 0x85, 0xD8, 0xAE, 0x44, 0xD9, 0x85, 0xD9, 0x85, + 0x44, 0xD9, 0x85, 0xD9, 0x89, 0x44, 0xD9, 0x85, + 0xD9, 0x8A, 0x44, 0xD9, 0x86, 0xD8, 0xAC, 0x44, // Bytes 1ec0 - 1eff - 0x03, 0xE4, 0xB8, 0x8B, 0x03, 0xE7, 0x94, 0xB2, - 0x03, 0xE4, 0xB8, 0x99, 0x03, 0xE4, 0xB8, 0x81, - 0x03, 0xE5, 0xA4, 0xA9, 0x03, 0xE5, 0x9C, 0xB0, - 0x05, 0x28, 0xE1, 0x84, 0x80, 0x29, 0x05, 0x28, - 0xE1, 0x84, 0x82, 0x29, 0x05, 0x28, 0xE1, 0x84, - 0x83, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x85, 0x29, - 0x05, 0x28, 0xE1, 0x84, 0x86, 0x29, 0x05, 0x28, - 0xE1, 0x84, 0x87, 0x29, 0x05, 0x28, 0xE1, 0x84, + 0xD9, 0x86, 0xD8, 0xAD, 0x44, 0xD9, 0x86, 0xD8, + 0xAE, 0x44, 0xD9, 0x86, 0xD8, 0xB1, 0x44, 0xD9, + 0x86, 0xD8, 0xB2, 0x44, 0xD9, 0x86, 0xD9, 0x85, + 0x44, 0xD9, 0x86, 0xD9, 0x86, 0x44, 0xD9, 0x86, + 0xD9, 0x87, 0x44, 0xD9, 0x86, 0xD9, 0x89, 0x44, + 0xD9, 0x86, 0xD9, 0x8A, 0x44, 0xD9, 0x87, 0xD8, + 0xAC, 0x44, 0xD9, 0x87, 0xD9, 0x85, 0x44, 0xD9, + 0x87, 0xD9, 0x89, 0x44, 0xD9, 0x87, 0xD9, 0x8A, // Bytes 1f00 - 1f3f - 0x89, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x8B, 0x29, - 0x05, 0x28, 0xE1, 0x84, 0x8C, 0x29, 0x05, 0x28, - 0xE1, 0x84, 0x8E, 0x29, 0x05, 0x28, 0xE1, 0x84, - 0x8F, 0x29, 0x05, 0x28, 0xE1, 0x84, 0x90, 0x29, - 0x05, 0x28, 0xE1, 0x84, 0x91, 0x29, 0x05, 0x28, - 0xE1, 0x84, 0x92, 0x29, 0x08, 0x28, 0xE1, 0x84, - 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, - 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, + 0x44, 0xD9, 0x88, 0xD9, 0xB4, 0x44, 0xD9, 0x8A, + 0xD8, 0xAC, 0x44, 0xD9, 0x8A, 0xD8, 0xAD, 0x44, + 0xD9, 0x8A, 0xD8, 0xAE, 0x44, 0xD9, 0x8A, 0xD8, + 0xB1, 0x44, 0xD9, 0x8A, 0xD8, 0xB2, 0x44, 0xD9, + 0x8A, 0xD9, 0x85, 0x44, 0xD9, 0x8A, 0xD9, 0x86, + 0x44, 0xD9, 0x8A, 0xD9, 0x87, 0x44, 0xD9, 0x8A, + 0xD9, 0x89, 0x44, 0xD9, 0x8A, 0xD9, 0x8A, 0x44, + 0xD9, 0x8A, 0xD9, 0xB4, 0x44, 0xDB, 0x87, 0xD9, // Bytes 1f40 - 1f7f - 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x08, - 0x28, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, - 0x08, 0x28, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, - 0x29, 0x08, 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, - 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x89, 0xE1, - 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x8B, - 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, - 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, 0xE1, + 0xB4, 0x44, 0xF0, 0xA0, 0x84, 0xA2, 0x44, 0xF0, + 0xA0, 0x94, 0x9C, 0x44, 0xF0, 0xA0, 0x94, 0xA5, + 0x44, 0xF0, 0xA0, 0x95, 0x8B, 0x44, 0xF0, 0xA0, + 0x98, 0xBA, 0x44, 0xF0, 0xA0, 0xA0, 0x84, 0x44, + 0xF0, 0xA0, 0xA3, 0x9E, 0x44, 0xF0, 0xA0, 0xA8, + 0xAC, 0x44, 0xF0, 0xA0, 0xAD, 0xA3, 0x44, 0xF0, + 0xA1, 0x93, 0xA4, 0x44, 0xF0, 0xA1, 0x9A, 0xA8, + 0x44, 0xF0, 0xA1, 0x9B, 0xAA, 0x44, 0xF0, 0xA1, // Bytes 1f80 - 1fbf - 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x08, 0x28, - 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x08, - 0x28, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29, - 0x08, 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, - 0x29, 0x08, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85, - 0xA1, 0x29, 0x08, 0x28, 0xE1, 0x84, 0x8C, 0xE1, - 0x85, 0xAE, 0x29, 0x11, 0x28, 0xE1, 0x84, 0x8B, - 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, + 0xA7, 0x88, 0x44, 0xF0, 0xA1, 0xAC, 0x98, 0x44, + 0xF0, 0xA1, 0xB4, 0x8B, 0x44, 0xF0, 0xA1, 0xB7, + 0xA4, 0x44, 0xF0, 0xA1, 0xB7, 0xA6, 0x44, 0xF0, + 0xA2, 0x86, 0x83, 0x44, 0xF0, 0xA2, 0x86, 0x9F, + 0x44, 0xF0, 0xA2, 0x8C, 0xB1, 0x44, 0xF0, 0xA2, + 0x9B, 0x94, 0x44, 0xF0, 0xA2, 0xA1, 0x84, 0x44, + 0xF0, 0xA2, 0xA1, 0x8A, 0x44, 0xF0, 0xA2, 0xAC, + 0x8C, 0x44, 0xF0, 0xA2, 0xAF, 0xB1, 0x44, 0xF0, // Bytes 1fc0 - 1fff - 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x0E, 0x28, 0xE1, - 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, - 0xE1, 0x85, 0xAE, 0x29, 0x05, 0x28, 0xE4, 0xB8, - 0x80, 0x29, 0x05, 0x28, 0xE4, 0xBA, 0x8C, 0x29, - 0x05, 0x28, 0xE4, 0xB8, 0x89, 0x29, 0x05, 0x28, - 0xE5, 0x9B, 0x9B, 0x29, 0x05, 0x28, 0xE4, 0xBA, - 0x94, 0x29, 0x05, 0x28, 0xE5, 0x85, 0xAD, 0x29, - 0x05, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x05, 0x28, + 0xA3, 0x80, 0x8A, 0x44, 0xF0, 0xA3, 0x8A, 0xB8, + 0x44, 0xF0, 0xA3, 0x8D, 0x9F, 0x44, 0xF0, 0xA3, + 0x8E, 0x93, 0x44, 0xF0, 0xA3, 0x8E, 0x9C, 0x44, + 0xF0, 0xA3, 0x8F, 0x83, 0x44, 0xF0, 0xA3, 0x8F, + 0x95, 0x44, 0xF0, 0xA3, 0x91, 0xAD, 0x44, 0xF0, + 0xA3, 0x9A, 0xA3, 0x44, 0xF0, 0xA3, 0xA2, 0xA7, + 0x44, 0xF0, 0xA3, 0xAA, 0x8D, 0x44, 0xF0, 0xA3, + 0xAB, 0xBA, 0x44, 0xF0, 0xA3, 0xB2, 0xBC, 0x44, // Bytes 2000 - 203f - 0xE5, 0x85, 0xAB, 0x29, 0x05, 0x28, 0xE4, 0xB9, - 0x9D, 0x29, 0x05, 0x28, 0xE5, 0x8D, 0x81, 0x29, - 0x05, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x05, 0x28, - 0xE7, 0x81, 0xAB, 0x29, 0x05, 0x28, 0xE6, 0xB0, - 0xB4, 0x29, 0x05, 0x28, 0xE6, 0x9C, 0xA8, 0x29, - 0x05, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x05, 0x28, - 0xE5, 0x9C, 0x9F, 0x29, 0x05, 0x28, 0xE6, 0x97, - 0xA5, 0x29, 0x05, 0x28, 0xE6, 0xA0, 0xAA, 0x29, + 0xF0, 0xA3, 0xB4, 0x9E, 0x44, 0xF0, 0xA3, 0xBB, + 0x91, 0x44, 0xF0, 0xA3, 0xBD, 0x9E, 0x44, 0xF0, + 0xA3, 0xBE, 0x8E, 0x44, 0xF0, 0xA4, 0x89, 0xA3, + 0x44, 0xF0, 0xA4, 0x8B, 0xAE, 0x44, 0xF0, 0xA4, + 0x8E, 0xAB, 0x44, 0xF0, 0xA4, 0x98, 0x88, 0x44, + 0xF0, 0xA4, 0x9C, 0xB5, 0x44, 0xF0, 0xA4, 0xA0, + 0x94, 0x44, 0xF0, 0xA4, 0xB0, 0xB6, 0x44, 0xF0, + 0xA4, 0xB2, 0x92, 0x44, 0xF0, 0xA4, 0xBE, 0xA1, // Bytes 2040 - 207f - 0x05, 0x28, 0xE6, 0x9C, 0x89, 0x29, 0x05, 0x28, - 0xE7, 0xA4, 0xBE, 0x29, 0x05, 0x28, 0xE5, 0x90, - 0x8D, 0x29, 0x05, 0x28, 0xE7, 0x89, 0xB9, 0x29, - 0x05, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x05, 0x28, - 0xE7, 0xA5, 0x9D, 0x29, 0x05, 0x28, 0xE5, 0x8A, - 0xB4, 0x29, 0x05, 0x28, 0xE4, 0xBB, 0xA3, 0x29, - 0x05, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x05, 0x28, - 0xE5, 0xAD, 0xA6, 0x29, 0x05, 0x28, 0xE7, 0x9B, + 0x44, 0xF0, 0xA4, 0xBE, 0xB8, 0x44, 0xF0, 0xA5, + 0x81, 0x84, 0x44, 0xF0, 0xA5, 0x83, 0xB2, 0x44, + 0xF0, 0xA5, 0x83, 0xB3, 0x44, 0xF0, 0xA5, 0x84, + 0x99, 0x44, 0xF0, 0xA5, 0x84, 0xB3, 0x44, 0xF0, + 0xA5, 0x89, 0x89, 0x44, 0xF0, 0xA5, 0x90, 0x9D, + 0x44, 0xF0, 0xA5, 0x98, 0xA6, 0x44, 0xF0, 0xA5, + 0x9A, 0x9A, 0x44, 0xF0, 0xA5, 0x9B, 0x85, 0x44, + 0xF0, 0xA5, 0xA5, 0xBC, 0x44, 0xF0, 0xA5, 0xAA, // Bytes 2080 - 20bf - 0xA3, 0x29, 0x05, 0x28, 0xE4, 0xBC, 0x81, 0x29, - 0x05, 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x05, 0x28, - 0xE5, 0x8D, 0x94, 0x29, 0x05, 0x28, 0xE7, 0xA5, - 0xAD, 0x29, 0x05, 0x28, 0xE4, 0xBC, 0x91, 0x29, - 0x05, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x05, 0x28, - 0xE8, 0x87, 0xB3, 0x29, 0x03, 0xE5, 0x95, 0x8F, - 0x03, 0xE5, 0xB9, 0xBC, 0x03, 0xE7, 0xAE, 0x8F, - 0x03, 0x50, 0x54, 0x45, 0x02, 0x32, 0x31, 0x02, + 0xA7, 0x44, 0xF0, 0xA5, 0xAE, 0xAB, 0x44, 0xF0, + 0xA5, 0xB2, 0x80, 0x44, 0xF0, 0xA5, 0xB3, 0x90, + 0x44, 0xF0, 0xA5, 0xBE, 0x86, 0x44, 0xF0, 0xA6, + 0x87, 0x9A, 0x44, 0xF0, 0xA6, 0x88, 0xA8, 0x44, + 0xF0, 0xA6, 0x89, 0x87, 0x44, 0xF0, 0xA6, 0x8B, + 0x99, 0x44, 0xF0, 0xA6, 0x8C, 0xBE, 0x44, 0xF0, + 0xA6, 0x93, 0x9A, 0x44, 0xF0, 0xA6, 0x94, 0xA3, + 0x44, 0xF0, 0xA6, 0x96, 0xA8, 0x44, 0xF0, 0xA6, // Bytes 20c0 - 20ff - 0x32, 0x32, 0x02, 0x32, 0x33, 0x02, 0x32, 0x34, - 0x02, 0x32, 0x35, 0x02, 0x32, 0x36, 0x02, 0x32, - 0x37, 0x02, 0x32, 0x38, 0x02, 0x32, 0x39, 0x02, - 0x33, 0x30, 0x02, 0x33, 0x31, 0x02, 0x33, 0x32, - 0x02, 0x33, 0x33, 0x02, 0x33, 0x34, 0x02, 0x33, - 0x35, 0x06, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, - 0x06, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x06, - 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x06, 0xE1, + 0x9E, 0xA7, 0x44, 0xF0, 0xA6, 0x9E, 0xB5, 0x44, + 0xF0, 0xA6, 0xAC, 0xBC, 0x44, 0xF0, 0xA6, 0xB0, + 0xB6, 0x44, 0xF0, 0xA6, 0xB3, 0x95, 0x44, 0xF0, + 0xA6, 0xB5, 0xAB, 0x44, 0xF0, 0xA6, 0xBC, 0xAC, + 0x44, 0xF0, 0xA6, 0xBE, 0xB1, 0x44, 0xF0, 0xA7, + 0x83, 0x92, 0x44, 0xF0, 0xA7, 0x8F, 0x8A, 0x44, + 0xF0, 0xA7, 0x99, 0xA7, 0x44, 0xF0, 0xA7, 0xA2, + 0xAE, 0x44, 0xF0, 0xA7, 0xA5, 0xA6, 0x44, 0xF0, // Bytes 2100 - 213f - 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, - 0x86, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x87, - 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x89, 0xE1, - 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x8B, 0xE1, 0x85, - 0xA1, 0x06, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, - 0x06, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x06, - 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x06, 0xE1, - 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, + 0xA7, 0xB2, 0xA8, 0x44, 0xF0, 0xA7, 0xBB, 0x93, + 0x44, 0xF0, 0xA7, 0xBC, 0xAF, 0x44, 0xF0, 0xA8, + 0x97, 0x92, 0x44, 0xF0, 0xA8, 0x97, 0xAD, 0x44, + 0xF0, 0xA8, 0x9C, 0xAE, 0x44, 0xF0, 0xA8, 0xAF, + 0xBA, 0x44, 0xF0, 0xA8, 0xB5, 0xB7, 0x44, 0xF0, + 0xA9, 0x85, 0x85, 0x44, 0xF0, 0xA9, 0x87, 0x9F, + 0x44, 0xF0, 0xA9, 0x88, 0x9A, 0x44, 0xF0, 0xA9, + 0x90, 0x8A, 0x44, 0xF0, 0xA9, 0x92, 0x96, 0x44, // Bytes 2140 - 217f - 0x91, 0xE1, 0x85, 0xA1, 0x06, 0xE1, 0x84, 0x92, - 0xE1, 0x85, 0xA1, 0x0F, 0xE1, 0x84, 0x8E, 0xE1, - 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, - 0xE1, 0x85, 0xA9, 0x0C, 0xE1, 0x84, 0x8C, 0xE1, - 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, - 0x06, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x03, - 0xE4, 0xBA, 0x94, 0x03, 0xE5, 0x85, 0xAD, 0x03, - 0xE4, 0xB8, 0x83, 0x03, 0xE4, 0xB9, 0x9D, 0x03, + 0xF0, 0xA9, 0x96, 0xB6, 0x44, 0xF0, 0xA9, 0xAC, + 0xB0, 0x44, 0xF0, 0xAA, 0x83, 0x8E, 0x44, 0xF0, + 0xAA, 0x84, 0x85, 0x44, 0xF0, 0xAA, 0x88, 0x8E, + 0x44, 0xF0, 0xAA, 0x8A, 0x91, 0x44, 0xF0, 0xAA, + 0x8E, 0x92, 0x44, 0xF0, 0xAA, 0x98, 0x80, 0x45, + 0x28, 0xE1, 0x84, 0x80, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x82, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x83, + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x85, 0x29, 0x45, // Bytes 2180 - 21bf - 0xE6, 0xA0, 0xAA, 0x03, 0xE6, 0x9C, 0x89, 0x03, - 0xE7, 0xA4, 0xBE, 0x03, 0xE5, 0x90, 0x8D, 0x03, - 0xE7, 0x89, 0xB9, 0x03, 0xE8, 0xB2, 0xA1, 0x03, - 0xE7, 0xA5, 0x9D, 0x03, 0xE5, 0x8A, 0xB4, 0x03, - 0xE7, 0xA7, 0x98, 0x03, 0xE7, 0x94, 0xB7, 0x03, - 0xE9, 0x81, 0xA9, 0x03, 0xE5, 0x84, 0xAA, 0x03, - 0xE5, 0x8D, 0xB0, 0x03, 0xE6, 0xB3, 0xA8, 0x03, - 0xE9, 0xA0, 0x85, 0x03, 0xE4, 0xBC, 0x91, 0x03, + 0x28, 0xE1, 0x84, 0x86, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x87, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x89, + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x45, + 0x28, 0xE1, 0x84, 0x8C, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x8E, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8F, + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x90, 0x29, 0x45, + 0x28, 0xE1, 0x84, 0x91, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x92, 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x80, // Bytes 21c0 - 21ff - 0xE5, 0x86, 0x99, 0x03, 0xE6, 0xAD, 0xA3, 0x03, - 0xE5, 0xB7, 0xA6, 0x03, 0xE5, 0x8F, 0xB3, 0x03, - 0xE5, 0x8C, 0xBB, 0x03, 0xE5, 0xAE, 0x97, 0x03, - 0xE5, 0xAD, 0xA6, 0x03, 0xE7, 0x9B, 0xA3, 0x03, - 0xE4, 0xBC, 0x81, 0x03, 0xE8, 0xB3, 0x87, 0x03, - 0xE5, 0x8D, 0x94, 0x03, 0xE5, 0xA4, 0x9C, 0x02, - 0x33, 0x36, 0x02, 0x33, 0x37, 0x02, 0x33, 0x38, - 0x02, 0x33, 0x39, 0x02, 0x34, 0x30, 0x02, 0x34, + 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x45, + 0x28, 0xE4, 0xB8, 0x89, 0x29, 0x45, 0x28, 0xE4, + 0xB9, 0x9D, 0x29, 0x45, 0x28, 0xE4, 0xBA, 0x8C, + 0x29, 0x45, 0x28, 0xE4, 0xBA, 0x94, 0x29, 0x45, + 0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x45, 0x28, 0xE4, + 0xBC, 0x81, 0x29, 0x45, 0x28, 0xE4, 0xBC, 0x91, + 0x29, 0x45, 0x28, 0xE5, 0x85, 0xAB, 0x29, 0x45, + 0x28, 0xE5, 0x85, 0xAD, 0x29, 0x45, 0x28, 0xE5, // Bytes 2200 - 223f - 0x31, 0x02, 0x34, 0x32, 0x02, 0x34, 0x33, 0x02, - 0x34, 0x34, 0x02, 0x34, 0x35, 0x02, 0x34, 0x36, - 0x02, 0x34, 0x37, 0x02, 0x34, 0x38, 0x02, 0x34, - 0x39, 0x02, 0x35, 0x30, 0x04, 0x31, 0xE6, 0x9C, - 0x88, 0x04, 0x32, 0xE6, 0x9C, 0x88, 0x04, 0x33, - 0xE6, 0x9C, 0x88, 0x04, 0x34, 0xE6, 0x9C, 0x88, - 0x04, 0x35, 0xE6, 0x9C, 0x88, 0x04, 0x36, 0xE6, - 0x9C, 0x88, 0x04, 0x37, 0xE6, 0x9C, 0x88, 0x04, + 0x8A, 0xB4, 0x29, 0x45, 0x28, 0xE5, 0x8D, 0x81, + 0x29, 0x45, 0x28, 0xE5, 0x8D, 0x94, 0x29, 0x45, + 0x28, 0xE5, 0x90, 0x8D, 0x29, 0x45, 0x28, 0xE5, + 0x91, 0xBC, 0x29, 0x45, 0x28, 0xE5, 0x9B, 0x9B, + 0x29, 0x45, 0x28, 0xE5, 0x9C, 0x9F, 0x29, 0x45, + 0x28, 0xE5, 0xAD, 0xA6, 0x29, 0x45, 0x28, 0xE6, + 0x97, 0xA5, 0x29, 0x45, 0x28, 0xE6, 0x9C, 0x88, + 0x29, 0x45, 0x28, 0xE6, 0x9C, 0x89, 0x29, 0x45, // Bytes 2240 - 227f - 0x38, 0xE6, 0x9C, 0x88, 0x04, 0x39, 0xE6, 0x9C, - 0x88, 0x05, 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x05, - 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x05, 0x31, 0x32, - 0xE6, 0x9C, 0x88, 0x02, 0x48, 0x67, 0x03, 0x65, - 0x72, 0x67, 0x02, 0x65, 0x56, 0x03, 0x4C, 0x54, - 0x44, 0x03, 0xE3, 0x82, 0xA2, 0x03, 0xE3, 0x82, - 0xA4, 0x03, 0xE3, 0x82, 0xA6, 0x03, 0xE3, 0x82, - 0xA8, 0x03, 0xE3, 0x82, 0xAA, 0x03, 0xE3, 0x82, + 0x28, 0xE6, 0x9C, 0xA8, 0x29, 0x45, 0x28, 0xE6, + 0xA0, 0xAA, 0x29, 0x45, 0x28, 0xE6, 0xB0, 0xB4, + 0x29, 0x45, 0x28, 0xE7, 0x81, 0xAB, 0x29, 0x45, + 0x28, 0xE7, 0x89, 0xB9, 0x29, 0x45, 0x28, 0xE7, + 0x9B, 0xA3, 0x29, 0x45, 0x28, 0xE7, 0xA4, 0xBE, + 0x29, 0x45, 0x28, 0xE7, 0xA5, 0x9D, 0x29, 0x45, + 0x28, 0xE7, 0xA5, 0xAD, 0x29, 0x45, 0x28, 0xE8, + 0x87, 0xAA, 0x29, 0x45, 0x28, 0xE8, 0x87, 0xB3, // Bytes 2280 - 22bf - 0xAB, 0x03, 0xE3, 0x82, 0xAD, 0x03, 0xE3, 0x82, - 0xAF, 0x03, 0xE3, 0x82, 0xB1, 0x03, 0xE3, 0x82, - 0xB3, 0x03, 0xE3, 0x82, 0xB5, 0x03, 0xE3, 0x82, - 0xB7, 0x03, 0xE3, 0x82, 0xB9, 0x03, 0xE3, 0x82, - 0xBB, 0x03, 0xE3, 0x82, 0xBD, 0x03, 0xE3, 0x82, - 0xBF, 0x03, 0xE3, 0x83, 0x81, 0x03, 0xE3, 0x83, - 0x84, 0x03, 0xE3, 0x83, 0x86, 0x03, 0xE3, 0x83, - 0x88, 0x03, 0xE3, 0x83, 0x8A, 0x03, 0xE3, 0x83, + 0x29, 0x45, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x45, + 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x45, 0x28, 0xE9, + 0x87, 0x91, 0x29, 0x45, 0x30, 0xE2, 0x81, 0x84, + 0x33, 0x45, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x45, + 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x30, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x31, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x45, + 0x31, 0x31, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x32, // Bytes 22c0 - 22ff - 0x8B, 0x03, 0xE3, 0x83, 0x8C, 0x03, 0xE3, 0x83, - 0x8D, 0x03, 0xE3, 0x83, 0x8E, 0x03, 0xE3, 0x83, - 0x8F, 0x03, 0xE3, 0x83, 0x92, 0x03, 0xE3, 0x83, - 0x95, 0x03, 0xE3, 0x83, 0x98, 0x03, 0xE3, 0x83, - 0x9B, 0x03, 0xE3, 0x83, 0x9E, 0x03, 0xE3, 0x83, - 0x9F, 0x03, 0xE3, 0x83, 0xA0, 0x03, 0xE3, 0x83, - 0xA1, 0x03, 0xE3, 0x83, 0xA2, 0x03, 0xE3, 0x83, - 0xA4, 0x03, 0xE3, 0x83, 0xA6, 0x03, 0xE3, 0x83, + 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x32, 0xE6, 0x9C, + 0x88, 0x45, 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x33, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x34, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x34, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x35, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x36, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x36, 0xE7, 0x82, 0xB9, 0x45, // Bytes 2300 - 233f - 0xA8, 0x03, 0xE3, 0x83, 0xA9, 0x03, 0xE3, 0x83, - 0xAA, 0x03, 0xE3, 0x83, 0xAB, 0x03, 0xE3, 0x83, - 0xAC, 0x03, 0xE3, 0x83, 0xAD, 0x03, 0xE3, 0x83, - 0xAF, 0x03, 0xE3, 0x83, 0xB0, 0x03, 0xE3, 0x83, - 0xB1, 0x03, 0xE3, 0x83, 0xB2, 0x0F, 0xE3, 0x82, - 0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, - 0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, + 0x31, 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x37, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x38, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x38, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x39, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x39, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0xE2, 0x81, 0x84, + 0x32, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x45, + 0x31, 0xE2, 0x81, 0x84, 0x34, 0x45, 0x31, 0xE2, + 0x81, 0x84, 0x35, 0x45, 0x31, 0xE2, 0x81, 0x84, // Bytes 2340 - 237f - 0x82, 0xA1, 0x0F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, - 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, - 0x82, 0xA2, 0x09, 0xE3, 0x82, 0xA2, 0xE3, 0x83, - 0xBC, 0xE3, 0x83, 0xAB, 0x0F, 0xE3, 0x82, 0xA4, - 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, - 0xAF, 0xE3, 0x82, 0x99, 0x09, 0xE3, 0x82, 0xA4, - 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x09, 0xE3, - 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, + 0x36, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x37, 0x45, + 0x31, 0xE2, 0x81, 0x84, 0x38, 0x45, 0x31, 0xE2, + 0x81, 0x84, 0x39, 0x45, 0x32, 0x30, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x45, + 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x31, + 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x32, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x32, 0xE7, 0x82, 0xB9, 0x45, + 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x33, // Bytes 2380 - 23bf - 0x12, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, - 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, - 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x82, 0xA8, 0xE3, - 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, - 0x09, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, - 0x82, 0xB9, 0x09, 0xE3, 0x82, 0xAA, 0xE3, 0x83, - 0xBC, 0xE3, 0x83, 0xA0, 0x09, 0xE3, 0x82, 0xAB, - 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, 0x0C, 0xE3, + 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x34, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x34, 0xE7, 0x82, 0xB9, 0x45, + 0x32, 0x35, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x36, + 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x37, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x38, 0xE6, 0x97, 0xA5, 0x45, + 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0xE2, + 0x81, 0x84, 0x33, 0x45, 0x32, 0xE2, 0x81, 0x84, + 0x35, 0x45, 0x33, 0x30, 0xE6, 0x97, 0xA5, 0x45, // Bytes 23c0 - 23ff - 0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, - 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, 0xAB, 0xE3, - 0x83, 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, - 0x0C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x82, - 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, - 0x83, 0x9E, 0x0C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, - 0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0C, + 0x33, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x33, 0xE2, + 0x81, 0x84, 0x34, 0x45, 0x33, 0xE2, 0x81, 0x84, + 0x35, 0x45, 0x33, 0xE2, 0x81, 0x84, 0x38, 0x45, + 0x34, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x35, 0xE2, + 0x81, 0x84, 0x36, 0x45, 0x35, 0xE2, 0x81, 0x84, + 0x38, 0x45, 0x37, 0xE2, 0x81, 0x84, 0x38, 0x45, + 0x41, 0xE2, 0x88, 0x95, 0x6D, 0x45, 0x56, 0xE2, + 0x88, 0x95, 0x6D, 0x45, 0x6D, 0xE2, 0x88, 0x95, // Bytes 2400 - 243f - 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0x8B, 0xE3, 0x83, 0xBC, 0x0C, 0xE3, 0x82, 0xAD, - 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, - 0xBC, 0x12, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xBC, 0x06, 0xE3, 0x82, 0xAD, - 0xE3, 0x83, 0xAD, 0x12, 0xE3, 0x82, 0xAD, 0xE3, - 0x83, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, + 0x73, 0x46, 0x31, 0xE2, 0x81, 0x84, 0x31, 0x30, + 0x46, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, 0x46, + 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x46, 0xD8, + 0xA8, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xA8, + 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD8, + 0xAC, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, + 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, // Bytes 2440 - 247f - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x12, 0xE3, - 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, - 0xAB, 0x0F, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, - 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, - 0x88, 0x0C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x12, 0xE3, - 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, + 0x46, 0xD8, 0xAA, 0xD8, 0xAD, 0xD9, 0x85, 0x46, + 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD8, + 0xAA, 0xD8, 0xAE, 0xD9, 0x89, 0x46, 0xD8, 0xAA, + 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD9, + 0x85, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, 0xD9, 0x85, + 0xD8, 0xAD, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, + 0xAE, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A, 0x46, // Bytes 2480 - 24bf - 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, - 0xB3, 0x12, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, - 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, - 0xA4, 0xE3, 0x83, 0xAD, 0x0C, 0xE3, 0x82, 0xAF, - 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, - 0x8D, 0x09, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC, - 0xE3, 0x82, 0xB9, 0x09, 0xE3, 0x82, 0xB3, 0xE3, - 0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x0C, 0xE3, 0x82, + 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD8, + 0xAC, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xAC, + 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xAC, 0xD9, + 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAC, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, + 0x8A, 0x46, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD8, // Bytes 24c0 - 24ff - 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B, 0xE3, - 0x82, 0x9A, 0x0C, 0xE3, 0x82, 0xB5, 0xE3, 0x82, - 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x0F, - 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x0F, - 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, - 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x09, - 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD8, 0xB3, + 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xB3, 0xD8, + 0xAE, 0xD9, 0x89, 0x46, 0xD8, 0xB3, 0xD8, 0xAE, + 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, + 0xAC, 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAD, + 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0x46, + 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xB4, 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD8, 0xB4, // Bytes 2500 - 253f - 0x81, 0x09, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x88, 0x0C, 0xE3, 0x82, 0xBF, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, - 0x09, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, - 0x82, 0xB7, 0x09, 0xE3, 0x83, 0x88, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xAB, 0x06, 0xE3, 0x83, 0x88, - 0xE3, 0x83, 0xB3, 0x06, 0xE3, 0x83, 0x8A, 0xE3, - 0x83, 0x8E, 0x09, 0xE3, 0x83, 0x8E, 0xE3, 0x83, + 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB4, 0xD9, + 0x85, 0xD8, 0xAE, 0x46, 0xD8, 0xB4, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, + 0xAD, 0x46, 0xD8, 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x46, + 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0x46, 0xD8, + 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB6, + 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD8, 0xB6, 0xD8, // Bytes 2540 - 257f - 0x83, 0xE3, 0x83, 0x88, 0x09, 0xE3, 0x83, 0x8F, - 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84, 0x12, 0xE3, - 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, - 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, - 0x88, 0x0C, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, - 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x0F, 0xE3, - 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, - 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0x12, 0xE3, + 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB6, 0xD8, 0xAE, + 0xD9, 0x85, 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, + 0xAD, 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD9, 0x85, + 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD8, + 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB9, + 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xB9, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xBA, 0xD9, 0x85, // Bytes 2580 - 25bf - 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, - 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, - 0xAB, 0x0C, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, - 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x09, 0xE3, - 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, - 0x09, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, - 0x83, 0xAB, 0x12, 0xE3, 0x83, 0x95, 0xE3, 0x82, - 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, + 0xD9, 0x85, 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x85, 0x46, + 0xD9, 0x81, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, + 0x82, 0xD9, 0x84, 0xDB, 0x92, 0x46, 0xD9, 0x82, + 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x82, 0xD9, + 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x82, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD9, 0x83, 0xD9, 0x85, 0xD9, // Bytes 25c0 - 25ff - 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x83, - 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0x88, 0x12, 0xE3, 0x83, 0x95, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, - 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x09, 0xE3, 0x83, - 0x95, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x0F, - 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, - 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x09, + 0x85, 0x46, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0x46, + 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, + 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x84, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD9, 0x84, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, + 0x85, 0x46, 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xAD, // Bytes 2600 - 263f - 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, - 0xBD, 0x0C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, - 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x09, 0xE3, - 0x83, 0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, - 0x0C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, - 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x0F, 0xE3, 0x83, - 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0C, 0xE3, 0x83, + 0x46, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD9, + 0x85, 0xD8, 0xAC, 0xD8, 0xAE, 0x46, 0xD9, 0x85, + 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8, + 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAD, + 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, + 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0x46, // Bytes 2640 - 267f - 0x98, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, - 0x82, 0xBF, 0x0F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, - 0x9A, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, - 0x83, 0x88, 0x0C, 0xE3, 0x83, 0x9B, 0xE3, 0x82, - 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x06, - 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x0F, 0xE3, - 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, - 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x09, 0xE3, + 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, + 0x85, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD9, 0x85, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD9, 0x86, 0xD8, 0xAC, + 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, + 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x85, 0x46, + 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD9, // Bytes 2680 - 26bf - 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, - 0x09, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0xB3, 0x0C, 0xE3, 0x83, 0x9E, 0xE3, 0x82, - 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0x09, - 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83, - 0xAB, 0x09, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, - 0xE3, 0x83, 0x8F, 0x09, 0xE3, 0x83, 0x9E, 0xE3, - 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x0F, 0xE3, 0x83, + 0x86, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x86, + 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x87, 0xD9, 0x85, + 0xD8, 0xAC, 0x46, 0xD9, 0x87, 0xD9, 0x85, 0xD9, + 0x85, 0x46, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, + 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, // Bytes 26c0 - 26ff - 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, - 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x83, - 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, - 0x83, 0xB3, 0x06, 0xE3, 0x83, 0x9F, 0xE3, 0x83, - 0xAA, 0x12, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, - 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, - 0xBC, 0xE3, 0x83, 0xAB, 0x09, 0xE3, 0x83, 0xA1, - 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0F, 0xE3, + 0xD9, 0x94, 0xD8, 0xA7, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD8, 0xAC, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD8, 0xAD, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, + 0xAE, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB1, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB2, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xD9, 0x86, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD9, 0x87, 0x46, 0xD9, 0x8A, 0xD9, // Bytes 2700 - 273f - 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, - 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, - 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, - 0xE3, 0x83, 0xAB, 0x0C, 0xE3, 0x83, 0xA4, 0xE3, - 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, - 0x09, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, - 0x83, 0xAB, 0x09, 0xE3, 0x83, 0xA6, 0xE3, 0x82, - 0xA2, 0xE3, 0x83, 0xB3, 0x0C, 0xE3, 0x83, 0xAA, + 0x94, 0xD9, 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD9, 0x89, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xDB, 0x95, 0x46, 0xE0, 0xB9, 0x8D, + 0xE0, 0xB8, 0xB2, 0x46, 0xE0, 0xBA, 0xAB, 0xE0, // Bytes 2740 - 277f - 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, - 0xAB, 0x06, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, - 0x0C, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, - 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0x0F, 0xE3, 0x83, - 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, - 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x06, 0xE3, 0x83, - 0xAC, 0xE3, 0x83, 0xA0, 0x12, 0xE3, 0x83, 0xAC, - 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0xBA, 0x99, 0x46, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, + 0xA1, 0x46, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, + 0x46, 0xE0, 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0x46, + 0xE0, 0xBD, 0x82, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, + 0xBD, 0x8C, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, + 0x91, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x96, + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x9B, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0x90, 0xE0, 0xBE, // Bytes 2780 - 27bf - 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0x09, - 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, - 0x88, 0x04, 0x30, 0xE7, 0x82, 0xB9, 0x04, 0x31, - 0xE7, 0x82, 0xB9, 0x04, 0x32, 0xE7, 0x82, 0xB9, - 0x04, 0x33, 0xE7, 0x82, 0xB9, 0x04, 0x34, 0xE7, - 0x82, 0xB9, 0x04, 0x35, 0xE7, 0x82, 0xB9, 0x04, - 0x36, 0xE7, 0x82, 0xB9, 0x04, 0x37, 0xE7, 0x82, - 0xB9, 0x04, 0x38, 0xE7, 0x82, 0xB9, 0x04, 0x39, + 0xB5, 0x46, 0xE0, 0xBE, 0x92, 0xE0, 0xBE, 0xB7, + 0x46, 0xE0, 0xBE, 0x9C, 0xE0, 0xBE, 0xB7, 0x46, + 0xE0, 0xBE, 0xA1, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, + 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, + 0xAB, 0xE0, 0xBE, 0xB7, 0x46, 0xE1, 0x84, 0x80, + 0xE1, 0x85, 0xA1, 0x46, 0xE1, 0x84, 0x82, 0xE1, + 0x85, 0xA1, 0x46, 0xE1, 0x84, 0x83, 0xE1, 0x85, + 0xA1, 0x46, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, // Bytes 27c0 - 27ff - 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x30, 0xE7, 0x82, - 0xB9, 0x05, 0x31, 0x31, 0xE7, 0x82, 0xB9, 0x05, - 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x33, - 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x34, 0xE7, 0x82, - 0xB9, 0x05, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x05, - 0x31, 0x36, 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x37, - 0xE7, 0x82, 0xB9, 0x05, 0x31, 0x38, 0xE7, 0x82, - 0xB9, 0x05, 0x31, 0x39, 0xE7, 0x82, 0xB9, 0x05, + 0x46, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x46, + 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x46, 0xE1, + 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x46, 0xE1, 0x84, + 0x8B, 0xE1, 0x85, 0xA1, 0x46, 0xE1, 0x84, 0x8B, + 0xE1, 0x85, 0xAE, 0x46, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA1, 0x46, 0xE1, 0x84, 0x8E, 0xE1, 0x85, + 0xA1, 0x46, 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, + 0x46, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x46, // Bytes 2800 - 283f - 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x05, 0x32, 0x31, - 0xE7, 0x82, 0xB9, 0x05, 0x32, 0x32, 0xE7, 0x82, - 0xB9, 0x05, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x05, - 0x32, 0x34, 0xE7, 0x82, 0xB9, 0x03, 0x68, 0x50, - 0x61, 0x02, 0x64, 0x61, 0x02, 0x41, 0x55, 0x03, - 0x62, 0x61, 0x72, 0x02, 0x6F, 0x56, 0x02, 0x70, - 0x63, 0x02, 0x64, 0x6D, 0x03, 0x64, 0x6D, 0x32, - 0x03, 0x64, 0x6D, 0x33, 0x02, 0x49, 0x55, 0x06, + 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x46, 0xE1, + 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x46, 0xE2, 0x80, + 0xB2, 0xE2, 0x80, 0xB2, 0x46, 0xE2, 0x80, 0xB5, + 0xE2, 0x80, 0xB5, 0x46, 0xE2, 0x88, 0xAB, 0xE2, + 0x88, 0xAB, 0x46, 0xE2, 0x88, 0xAE, 0xE2, 0x88, + 0xAE, 0x46, 0xE3, 0x81, 0xBB, 0xE3, 0x81, 0x8B, + 0x46, 0xE3, 0x82, 0x88, 0xE3, 0x82, 0x8A, 0x46, + 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0x46, 0xE3, // Bytes 2840 - 287f - 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x06, 0xE6, - 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0x06, 0xE5, 0xA4, - 0xA7, 0xE6, 0xAD, 0xA3, 0x06, 0xE6, 0x98, 0x8E, - 0xE6, 0xB2, 0xBB, 0x0C, 0xE6, 0xA0, 0xAA, 0xE5, - 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, - 0x02, 0x70, 0x41, 0x02, 0x6E, 0x41, 0x03, 0xCE, - 0xBC, 0x41, 0x02, 0x6D, 0x41, 0x02, 0x6B, 0x41, - 0x02, 0x4B, 0x42, 0x02, 0x4D, 0x42, 0x02, 0x47, + 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x46, 0xE3, 0x82, + 0xB3, 0xE3, 0x83, 0x88, 0x46, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, 0x8A, 0xE3, + 0x83, 0x8E, 0x46, 0xE3, 0x83, 0x9B, 0xE3, 0x83, + 0xB3, 0x46, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, + 0x46, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, 0x46, + 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0, 0x46, 0xE5, + 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0x46, 0xE5, 0xB9, // Bytes 2880 - 28bf - 0x42, 0x03, 0x63, 0x61, 0x6C, 0x04, 0x6B, 0x63, - 0x61, 0x6C, 0x02, 0x70, 0x46, 0x02, 0x6E, 0x46, - 0x03, 0xCE, 0xBC, 0x46, 0x03, 0xCE, 0xBC, 0x67, - 0x02, 0x6D, 0x67, 0x02, 0x6B, 0x67, 0x02, 0x48, - 0x7A, 0x03, 0x6B, 0x48, 0x7A, 0x03, 0x4D, 0x48, - 0x7A, 0x03, 0x47, 0x48, 0x7A, 0x03, 0x54, 0x48, - 0x7A, 0x03, 0xCE, 0xBC, 0x6C, 0x02, 0x6D, 0x6C, - 0x02, 0x64, 0x6C, 0x02, 0x6B, 0x6C, 0x02, 0x66, + 0xB3, 0xE6, 0x88, 0x90, 0x46, 0xE6, 0x98, 0x8E, + 0xE6, 0xB2, 0xBB, 0x46, 0xE6, 0x98, 0xAD, 0xE5, + 0x92, 0x8C, 0x47, 0x72, 0x61, 0x64, 0xE2, 0x88, + 0x95, 0x73, 0x47, 0xE3, 0x80, 0x94, 0x53, 0xE3, + 0x80, 0x95, 0x48, 0x28, 0xE1, 0x84, 0x80, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x82, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, // Bytes 28c0 - 28ff - 0x6D, 0x02, 0x6E, 0x6D, 0x03, 0xCE, 0xBC, 0x6D, - 0x02, 0x6D, 0x6D, 0x02, 0x63, 0x6D, 0x02, 0x6B, - 0x6D, 0x03, 0x6D, 0x6D, 0x32, 0x03, 0x63, 0x6D, - 0x32, 0x02, 0x6D, 0x32, 0x03, 0x6B, 0x6D, 0x32, - 0x03, 0x6D, 0x6D, 0x33, 0x03, 0x63, 0x6D, 0x33, - 0x02, 0x6D, 0x33, 0x03, 0x6B, 0x6D, 0x33, 0x05, - 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x06, 0x6D, 0xE2, - 0x88, 0x95, 0x73, 0x32, 0x02, 0x50, 0x61, 0x03, + 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C, + 0xE1, 0x85, 0xAE, 0x29, 0x48, 0x28, 0xE1, 0x84, // Bytes 2900 - 293f - 0x6B, 0x50, 0x61, 0x03, 0x4D, 0x50, 0x61, 0x03, - 0x47, 0x50, 0x61, 0x03, 0x72, 0x61, 0x64, 0x07, - 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x08, - 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, - 0x02, 0x70, 0x73, 0x02, 0x6E, 0x73, 0x03, 0xCE, - 0xBC, 0x73, 0x02, 0x6D, 0x73, 0x02, 0x70, 0x56, - 0x02, 0x6E, 0x56, 0x03, 0xCE, 0xBC, 0x56, 0x02, - 0x6D, 0x56, 0x02, 0x6B, 0x56, 0x02, 0x4D, 0x56, + 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, + 0x73, 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83, 0xD8, + 0xA8, 0xD8, 0xB1, 0x48, 0xD8, 0xA7, 0xD9, 0x84, // Bytes 2940 - 297f - 0x02, 0x70, 0x57, 0x02, 0x6E, 0x57, 0x03, 0xCE, - 0xBC, 0x57, 0x02, 0x6D, 0x57, 0x02, 0x6B, 0x57, - 0x02, 0x4D, 0x57, 0x03, 0x6B, 0xCE, 0xA9, 0x03, - 0x4D, 0xCE, 0xA9, 0x04, 0x61, 0x2E, 0x6D, 0x2E, - 0x02, 0x42, 0x71, 0x02, 0x63, 0x63, 0x02, 0x63, - 0x64, 0x06, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, - 0x03, 0x43, 0x6F, 0x2E, 0x02, 0x64, 0x42, 0x02, - 0x47, 0x79, 0x02, 0x68, 0x61, 0x02, 0x48, 0x50, + 0xD9, 0x84, 0xD9, 0x87, 0x48, 0xD8, 0xB1, 0xD8, + 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0x48, 0xD8, 0xB1, + 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x48, 0xD8, + 0xB5, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85, 0x48, + 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, + 0x48, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, + 0xAF, 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, 0x84, + 0xD9, 0x85, 0x49, 0xE2, 0x80, 0xB2, 0xE2, 0x80, // Bytes 2980 - 29bf - 0x02, 0x69, 0x6E, 0x02, 0x4B, 0x4B, 0x02, 0x4B, - 0x4D, 0x02, 0x6B, 0x74, 0x02, 0x6C, 0x6D, 0x02, - 0x6C, 0x6E, 0x03, 0x6C, 0x6F, 0x67, 0x02, 0x6C, - 0x78, 0x02, 0x6D, 0x62, 0x03, 0x6D, 0x69, 0x6C, - 0x03, 0x6D, 0x6F, 0x6C, 0x02, 0x50, 0x48, 0x04, - 0x70, 0x2E, 0x6D, 0x2E, 0x03, 0x50, 0x50, 0x4D, - 0x02, 0x50, 0x52, 0x02, 0x73, 0x72, 0x02, 0x53, - 0x76, 0x02, 0x57, 0x62, 0x05, 0x56, 0xE2, 0x88, + 0xB2, 0xE2, 0x80, 0xB2, 0x49, 0xE2, 0x80, 0xB5, + 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x49, 0xE2, + 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0x49, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, + 0x88, 0xAE, 0x49, 0xE3, 0x80, 0x94, 0xE4, 0xB8, + 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80, 0x95, // Bytes 29c0 - 29ff - 0x95, 0x6D, 0x05, 0x41, 0xE2, 0x88, 0x95, 0x6D, - 0x04, 0x31, 0xE6, 0x97, 0xA5, 0x04, 0x32, 0xE6, - 0x97, 0xA5, 0x04, 0x33, 0xE6, 0x97, 0xA5, 0x04, - 0x34, 0xE6, 0x97, 0xA5, 0x04, 0x35, 0xE6, 0x97, - 0xA5, 0x04, 0x36, 0xE6, 0x97, 0xA5, 0x04, 0x37, - 0xE6, 0x97, 0xA5, 0x04, 0x38, 0xE6, 0x97, 0xA5, - 0x04, 0x39, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x30, - 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x31, 0xE6, 0x97, + 0x49, 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x89, + 0x93, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE6, 0x95, 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x9B, + 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x82, 0xA2, // Bytes 2a00 - 2a3f - 0xA5, 0x05, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x05, - 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x34, - 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x35, 0xE6, 0x97, - 0xA5, 0x05, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x05, - 0x31, 0x37, 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x38, - 0xE6, 0x97, 0xA5, 0x05, 0x31, 0x39, 0xE6, 0x97, - 0xA5, 0x05, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x05, - 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x32, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, + 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, + 0x49, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x82, 0xAA, 0xE3, 0x83, + 0xB3, 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xAA, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x49, 0xE3, + 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, + 0x49, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC, 0xE3, // Bytes 2a40 - 2a7f - 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x33, 0xE6, 0x97, - 0xA5, 0x05, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x05, - 0x32, 0x35, 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x36, - 0xE6, 0x97, 0xA5, 0x05, 0x32, 0x37, 0xE6, 0x97, - 0xA5, 0x05, 0x32, 0x38, 0xE6, 0x97, 0xA5, 0x05, - 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x05, 0x33, 0x30, - 0xE6, 0x97, 0xA5, 0x05, 0x33, 0x31, 0xE6, 0x97, - 0xA5, 0x03, 0x67, 0x61, 0x6C, 0x03, 0xEA, 0x9D, + 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xB3, 0xE3, 0x83, + 0xAB, 0xE3, 0x83, 0x8A, 0x49, 0xE3, 0x82, 0xBB, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49, 0xE3, + 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, + 0x49, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xB7, 0x49, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x8E, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x49, 0xE3, // Bytes 2a80 - 2abf - 0xAF, 0x03, 0xE8, 0xB1, 0x88, 0x03, 0xE6, 0x9B, - 0xB4, 0x03, 0xE8, 0xB3, 0x88, 0x03, 0xE6, 0xBB, - 0x91, 0x03, 0xE4, 0xB8, 0xB2, 0x03, 0xE5, 0x8F, - 0xA5, 0x03, 0xE5, 0xA5, 0x91, 0x03, 0xE5, 0x96, - 0x87, 0x03, 0xE5, 0xA5, 0x88, 0x03, 0xE6, 0x87, - 0xB6, 0x03, 0xE7, 0x99, 0xA9, 0x03, 0xE7, 0xBE, - 0x85, 0x03, 0xE8, 0x98, 0xBF, 0x03, 0xE8, 0x9E, - 0xBA, 0x03, 0xE8, 0xA3, 0xB8, 0x03, 0xE9, 0x82, + 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84, + 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xB3, 0x49, 0xE3, 0x83, 0x95, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x49, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xBD, + 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x84, 0x49, 0xE3, 0x83, 0x9B, 0xE3, 0x83, // Bytes 2ac0 - 2aff - 0x8F, 0x03, 0xE6, 0xA8, 0x82, 0x03, 0xE6, 0xB4, - 0x9B, 0x03, 0xE7, 0x83, 0x99, 0x03, 0xE7, 0x8F, - 0x9E, 0x03, 0xE8, 0x90, 0xBD, 0x03, 0xE9, 0x85, - 0xAA, 0x03, 0xE9, 0xA7, 0xB1, 0x03, 0xE4, 0xBA, - 0x82, 0x03, 0xE5, 0x8D, 0xB5, 0x03, 0xE6, 0xAC, - 0x84, 0x03, 0xE7, 0x88, 0x9B, 0x03, 0xE8, 0x98, - 0xAD, 0x03, 0xE9, 0xB8, 0x9E, 0x03, 0xE5, 0xB5, - 0x90, 0x03, 0xE6, 0xBF, 0xAB, 0x03, 0xE8, 0x97, + 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x9B, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x49, 0xE3, + 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, 0xE3, + 0x83, 0x8F, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, + 0xAB, 0xE3, 0x82, 0xAF, 0x49, 0xE3, 0x83, 0xA4, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, + 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, // Bytes 2b00 - 2b3f - 0x8D, 0x03, 0xE8, 0xA5, 0xA4, 0x03, 0xE6, 0x8B, - 0x89, 0x03, 0xE8, 0x87, 0x98, 0x03, 0xE8, 0xA0, - 0x9F, 0x03, 0xE5, 0xBB, 0x8A, 0x03, 0xE6, 0x9C, - 0x97, 0x03, 0xE6, 0xB5, 0xAA, 0x03, 0xE7, 0x8B, - 0xBC, 0x03, 0xE9, 0x83, 0x8E, 0x03, 0xE4, 0xBE, - 0x86, 0x03, 0xE5, 0x86, 0xB7, 0x03, 0xE5, 0x8B, - 0x9E, 0x03, 0xE6, 0x93, 0x84, 0x03, 0xE6, 0xAB, - 0x93, 0x03, 0xE7, 0x88, 0x90, 0x03, 0xE7, 0x9B, + 0x49, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, + 0x83, 0x88, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, 0x85, + 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, 0x4C, + 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, + 0xB2, 0xE2, 0x80, 0xB2, 0x4C, 0xE2, 0x88, 0xAB, + 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0x4C, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0x4C, 0xE3, // Bytes 2b40 - 2b7f - 0xA7, 0x03, 0xE8, 0x98, 0x86, 0x03, 0xE8, 0x99, - 0x9C, 0x03, 0xE8, 0xB7, 0xAF, 0x03, 0xE9, 0x9C, - 0xB2, 0x03, 0xE9, 0xAD, 0xAF, 0x03, 0xE9, 0xB7, - 0xBA, 0x03, 0xE7, 0xA2, 0x8C, 0x03, 0xE7, 0xA5, - 0xBF, 0x03, 0xE7, 0xB6, 0xA0, 0x03, 0xE8, 0x8F, - 0x89, 0x03, 0xE9, 0x8C, 0x84, 0x03, 0xE8, 0xAB, - 0x96, 0x03, 0xE5, 0xA3, 0x9F, 0x03, 0xE5, 0xBC, - 0x84, 0x03, 0xE7, 0xB1, 0xA0, 0x03, 0xE8, 0x81, + 0x82, 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, + 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0x4C, 0xE3, 0x82, + 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, + 0x83, 0x88, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, + 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, // Bytes 2b80 - 2bbf - 0xBE, 0x03, 0xE7, 0x89, 0xA2, 0x03, 0xE7, 0xA3, - 0x8A, 0x03, 0xE8, 0xB3, 0x82, 0x03, 0xE9, 0x9B, - 0xB7, 0x03, 0xE5, 0xA3, 0x98, 0x03, 0xE5, 0xB1, - 0xA2, 0x03, 0xE6, 0xA8, 0x93, 0x03, 0xE6, 0xB7, - 0x9A, 0x03, 0xE6, 0xBC, 0x8F, 0x03, 0xE7, 0xB4, - 0xAF, 0x03, 0xE7, 0xB8, 0xB7, 0x03, 0xE9, 0x99, - 0x8B, 0x03, 0xE5, 0x8B, 0x92, 0x03, 0xE8, 0x82, - 0x8B, 0x03, 0xE5, 0x87, 0x9C, 0x03, 0xE5, 0x87, + 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0x8B, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, + 0xBC, 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x4C, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0x8D, 0x4C, 0xE3, 0x82, 0xB5, 0xE3, + 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, // Bytes 2bc0 - 2bff - 0x8C, 0x03, 0xE7, 0xA8, 0x9C, 0x03, 0xE7, 0xB6, - 0xBE, 0x03, 0xE8, 0x8F, 0xB1, 0x03, 0xE9, 0x99, - 0xB5, 0x03, 0xE8, 0xAE, 0x80, 0x03, 0xE6, 0x8B, - 0x8F, 0x03, 0xE8, 0xAB, 0xBE, 0x03, 0xE4, 0xB8, - 0xB9, 0x03, 0xE5, 0xAF, 0xA7, 0x03, 0xE6, 0x80, - 0x92, 0x03, 0xE7, 0x8E, 0x87, 0x03, 0xE7, 0x95, - 0xB0, 0x03, 0xE5, 0x8C, 0x97, 0x03, 0xE7, 0xA3, - 0xBB, 0x03, 0xE4, 0xBE, 0xBF, 0x03, 0xE5, 0xBE, + 0x4C, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x84, 0x4C, 0xE3, 0x83, 0x92, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, + 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x98, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, // Bytes 2c00 - 2c3f - 0xA9, 0x03, 0xE4, 0xB8, 0x8D, 0x03, 0xE6, 0xB3, - 0x8C, 0x03, 0xE6, 0x95, 0xB8, 0x03, 0xE7, 0xB4, - 0xA2, 0x03, 0xE5, 0x8F, 0x83, 0x03, 0xE5, 0xA1, - 0x9E, 0x03, 0xE7, 0x9C, 0x81, 0x03, 0xE8, 0x91, - 0x89, 0x03, 0xE8, 0xAA, 0xAA, 0x03, 0xE6, 0xAE, - 0xBA, 0x03, 0xE6, 0xB2, 0x88, 0x03, 0xE6, 0x8B, - 0xBE, 0x03, 0xE8, 0x8B, 0xA5, 0x03, 0xE6, 0x8E, - 0xA0, 0x03, 0xE7, 0x95, 0xA5, 0x03, 0xE4, 0xBA, + 0xBF, 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x4C, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, + 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x9B, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, + 0x4C, 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0x4C, 0xE3, 0x83, + 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, // Bytes 2c40 - 2c7f - 0xAE, 0x03, 0xE5, 0x85, 0xA9, 0x03, 0xE5, 0x87, - 0x89, 0x03, 0xE6, 0xA2, 0x81, 0x03, 0xE7, 0xB3, - 0xA7, 0x03, 0xE8, 0x89, 0xAF, 0x03, 0xE8, 0xAB, - 0x92, 0x03, 0xE9, 0x87, 0x8F, 0x03, 0xE5, 0x8B, - 0xB5, 0x03, 0xE5, 0x91, 0x82, 0x03, 0xE5, 0xBB, - 0xAC, 0x03, 0xE6, 0x97, 0x85, 0x03, 0xE6, 0xBF, - 0xBE, 0x03, 0xE7, 0xA4, 0xAA, 0x03, 0xE9, 0x96, - 0xAD, 0x03, 0xE9, 0xA9, 0xAA, 0x03, 0xE9, 0xBA, + 0x83, 0xB3, 0x4C, 0xE3, 0x83, 0xA1, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x4C, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xBC, 0x4C, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, + 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x4E, 0x28, + 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, // Bytes 2c80 - 2cbf - 0x97, 0x03, 0xE9, 0xBB, 0x8E, 0x03, 0xE6, 0x9B, - 0x86, 0x03, 0xE6, 0xAD, 0xB7, 0x03, 0xE8, 0xBD, - 0xA2, 0x03, 0xE5, 0xB9, 0xB4, 0x03, 0xE6, 0x86, - 0x90, 0x03, 0xE6, 0x88, 0x80, 0x03, 0xE6, 0x92, - 0x9A, 0x03, 0xE6, 0xBC, 0xA3, 0x03, 0xE7, 0x85, - 0x89, 0x03, 0xE7, 0x92, 0x89, 0x03, 0xE7, 0xA7, - 0x8A, 0x03, 0xE7, 0xB7, 0xB4, 0x03, 0xE8, 0x81, - 0xAF, 0x03, 0xE8, 0xBC, 0xA6, 0x03, 0xE8, 0x93, + 0x92, 0xE1, 0x85, 0xAE, 0x29, 0x4F, 0xD8, 0xAC, + 0xD9, 0x84, 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, + 0xA7, 0xD9, 0x84, 0xD9, 0x87, 0x4F, 0xE1, 0x84, + 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, + 0x84, 0x80, 0xE1, 0x85, 0xA9, 0x4F, 0xE3, 0x82, + 0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, + 0xA2, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, // Bytes 2cc0 - 2cff - 0xAE, 0x03, 0xE9, 0x80, 0xA3, 0x03, 0xE9, 0x8D, - 0x8A, 0x03, 0xE5, 0x88, 0x97, 0x03, 0xE5, 0x8A, - 0xA3, 0x03, 0xE5, 0x92, 0xBD, 0x03, 0xE7, 0x83, - 0x88, 0x03, 0xE8, 0xA3, 0x82, 0x03, 0xE5, 0xBB, - 0x89, 0x03, 0xE5, 0xBF, 0xB5, 0x03, 0xE6, 0x8D, - 0xBB, 0x03, 0xE6, 0xAE, 0xAE, 0x03, 0xE7, 0xB0, - 0xBE, 0x03, 0xE7, 0x8D, 0xB5, 0x03, 0xE4, 0xBB, - 0xA4, 0x03, 0xE5, 0x9B, 0xB9, 0x03, 0xE5, 0xB6, + 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0x4F, 0xE3, 0x82, + 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, + 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, + 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x4F, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3, // Bytes 2d00 - 2d3f - 0xBA, 0x03, 0xE6, 0x80, 0x9C, 0x03, 0xE7, 0x8E, - 0xB2, 0x03, 0xE7, 0x91, 0xA9, 0x03, 0xE7, 0xBE, - 0x9A, 0x03, 0xE8, 0x81, 0x86, 0x03, 0xE9, 0x88, - 0xB4, 0x03, 0xE9, 0x9B, 0xB6, 0x03, 0xE9, 0x9D, - 0x88, 0x03, 0xE9, 0xA0, 0x98, 0x03, 0xE4, 0xBE, - 0x8B, 0x03, 0xE7, 0xA6, 0xAE, 0x03, 0xE9, 0x86, - 0xB4, 0x03, 0xE9, 0x9A, 0xB8, 0x03, 0xE6, 0x83, - 0xA1, 0x03, 0xE4, 0xBA, 0x86, 0x03, 0xE5, 0x83, + 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, + 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3, + 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x83, + 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, + 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, + 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, + 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, // Bytes 2d40 - 2d7f - 0x9A, 0x03, 0xE5, 0xAF, 0xAE, 0x03, 0xE5, 0xB0, - 0xBF, 0x03, 0xE6, 0x96, 0x99, 0x03, 0xE7, 0x87, - 0x8E, 0x03, 0xE7, 0x99, 0x82, 0x03, 0xE8, 0x93, - 0xBC, 0x03, 0xE9, 0x81, 0xBC, 0x03, 0xE6, 0x9A, - 0x88, 0x03, 0xE9, 0x98, 0xAE, 0x03, 0xE5, 0x8A, - 0x89, 0x03, 0xE6, 0x9D, 0xBB, 0x03, 0xE6, 0x9F, - 0xB3, 0x03, 0xE6, 0xB5, 0x81, 0x03, 0xE6, 0xBA, - 0x9C, 0x03, 0xE7, 0x90, 0x89, 0x03, 0xE7, 0x95, + 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x51, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, + 0xE1, 0x85, 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x52, + 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xAB, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xBC, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, + 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x52, 0xE3, 0x82, // Bytes 2d80 - 2dbf - 0x99, 0x03, 0xE7, 0xA1, 0xAB, 0x03, 0xE7, 0xB4, - 0x90, 0x03, 0xE9, 0xA1, 0x9E, 0x03, 0xE6, 0x88, - 0xAE, 0x03, 0xE9, 0x99, 0xB8, 0x03, 0xE5, 0x80, - 0xAB, 0x03, 0xE5, 0xB4, 0x99, 0x03, 0xE6, 0xB7, - 0xAA, 0x03, 0xE8, 0xBC, 0xAA, 0x03, 0xE5, 0xBE, - 0x8B, 0x03, 0xE6, 0x85, 0x84, 0x03, 0xE6, 0xA0, - 0x97, 0x03, 0xE9, 0x9A, 0x86, 0x03, 0xE5, 0x88, - 0xA9, 0x03, 0xE5, 0x90, 0x8F, 0x03, 0xE5, 0xB1, + 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, + 0x52, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xB3, 0x52, 0xE3, 0x82, 0xAF, 0xE3, + 0x83, 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, + 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0x52, 0xE3, + 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, // Bytes 2dc0 - 2dff - 0xA5, 0x03, 0xE6, 0x98, 0x93, 0x03, 0xE6, 0x9D, - 0x8E, 0x03, 0xE6, 0xA2, 0xA8, 0x03, 0xE6, 0xB3, - 0xA5, 0x03, 0xE7, 0x90, 0x86, 0x03, 0xE7, 0x97, - 0xA2, 0x03, 0xE7, 0xBD, 0xB9, 0x03, 0xE8, 0xA3, - 0x8F, 0x03, 0xE8, 0xA3, 0xA1, 0x03, 0xE9, 0x9B, - 0xA2, 0x03, 0xE5, 0x8C, 0xBF, 0x03, 0xE6, 0xBA, - 0xBA, 0x03, 0xE5, 0x90, 0x9D, 0x03, 0xE7, 0x87, - 0x90, 0x03, 0xE7, 0x92, 0x98, 0x03, 0xE8, 0x97, + 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x88, 0x52, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, + 0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x95, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, + 0xB7, 0xE3, 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x52, + 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, // Bytes 2e00 - 2e3f - 0xBA, 0x03, 0xE9, 0x9A, 0xA3, 0x03, 0xE9, 0xB1, - 0x97, 0x03, 0xE9, 0xBA, 0x9F, 0x03, 0xE6, 0x9E, - 0x97, 0x03, 0xE6, 0xB7, 0x8B, 0x03, 0xE8, 0x87, - 0xA8, 0x03, 0xE7, 0xAC, 0xA0, 0x03, 0xE7, 0xB2, - 0x92, 0x03, 0xE7, 0x8B, 0x80, 0x03, 0xE7, 0x82, - 0x99, 0x03, 0xE8, 0xAD, 0x98, 0x03, 0xE4, 0xBB, - 0x80, 0x03, 0xE8, 0x8C, 0xB6, 0x03, 0xE5, 0x88, - 0xBA, 0x03, 0xE5, 0x88, 0x87, 0x03, 0xE5, 0xBA, + 0x83, 0xAB, 0x52, 0xE3, 0x83, 0xAC, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xB3, 0x61, 0xD8, 0xB5, + 0xD9, 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, + 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, + 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, + 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x86, + 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x86, 0xE0, // Bytes 2e40 - 2e7f - 0xA6, 0x03, 0xE6, 0x8B, 0x93, 0x03, 0xE7, 0xB3, - 0x96, 0x03, 0xE5, 0xAE, 0x85, 0x03, 0xE6, 0xB4, - 0x9E, 0x03, 0xE6, 0x9A, 0xB4, 0x03, 0xE8, 0xBC, - 0xBB, 0x03, 0xE9, 0x99, 0x8D, 0x03, 0xE5, 0xBB, - 0x93, 0x03, 0xE5, 0x85, 0x80, 0x03, 0xE5, 0x97, - 0x80, 0x03, 0xE5, 0xA1, 0x9A, 0x03, 0xE6, 0x99, - 0xB4, 0x03, 0xE5, 0x87, 0x9E, 0x03, 0xE7, 0x8C, - 0xAA, 0x03, 0xE7, 0x9B, 0x8A, 0x03, 0xE7, 0xA4, + 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x03, 0x3C, 0xCC, + 0xB8, 0x01, 0x03, 0x3D, 0xCC, 0xB8, 0x01, 0x03, + 0x3E, 0xCC, 0xB8, 0x01, 0x03, 0x41, 0xCC, 0x80, + 0xE6, 0x03, 0x41, 0xCC, 0x81, 0xE6, 0x03, 0x41, + 0xCC, 0x83, 0xE6, 0x03, 0x41, 0xCC, 0x84, 0xE6, + 0x03, 0x41, 0xCC, 0x89, 0xE6, 0x03, 0x41, 0xCC, + 0x8C, 0xE6, 0x03, 0x41, 0xCC, 0x8F, 0xE6, 0x03, + 0x41, 0xCC, 0x91, 0xE6, 0x03, 0x41, 0xCC, 0xA5, // Bytes 2e80 - 2ebf - 0xBC, 0x03, 0xE7, 0xA5, 0x9E, 0x03, 0xE7, 0xA5, - 0xA5, 0x03, 0xE7, 0xA6, 0x8F, 0x03, 0xE9, 0x9D, - 0x96, 0x03, 0xE7, 0xB2, 0xBE, 0x03, 0xE8, 0x98, - 0x92, 0x03, 0xE8, 0xAB, 0xB8, 0x03, 0xE9, 0x80, - 0xB8, 0x03, 0xE9, 0x83, 0xBD, 0x03, 0xE9, 0xA3, - 0xAF, 0x03, 0xE9, 0xA3, 0xBC, 0x03, 0xE9, 0xA4, - 0xA8, 0x03, 0xE9, 0xB6, 0xB4, 0x03, 0xE4, 0xBE, - 0xAE, 0x03, 0xE5, 0x83, 0xA7, 0x03, 0xE5, 0x85, + 0xDC, 0x03, 0x41, 0xCC, 0xA8, 0xCA, 0x03, 0x42, + 0xCC, 0x87, 0xE6, 0x03, 0x42, 0xCC, 0xA3, 0xDC, + 0x03, 0x42, 0xCC, 0xB1, 0xDC, 0x03, 0x43, 0xCC, + 0x81, 0xE6, 0x03, 0x43, 0xCC, 0x82, 0xE6, 0x03, + 0x43, 0xCC, 0x87, 0xE6, 0x03, 0x43, 0xCC, 0x8C, + 0xE6, 0x03, 0x44, 0xCC, 0x87, 0xE6, 0x03, 0x44, + 0xCC, 0x8C, 0xE6, 0x03, 0x44, 0xCC, 0xA3, 0xDC, + 0x03, 0x44, 0xCC, 0xA7, 0xCA, 0x03, 0x44, 0xCC, // Bytes 2ec0 - 2eff - 0x8D, 0x03, 0xE5, 0x8B, 0x89, 0x03, 0xE5, 0x8B, - 0xA4, 0x03, 0xE5, 0x8D, 0x91, 0x03, 0xE5, 0x96, - 0x9D, 0x03, 0xE5, 0x98, 0x86, 0x03, 0xE5, 0x99, - 0xA8, 0x03, 0xE5, 0xA1, 0x80, 0x03, 0xE5, 0xA2, - 0xA8, 0x03, 0xE5, 0xB1, 0xA4, 0x03, 0xE6, 0x82, - 0x94, 0x03, 0xE6, 0x85, 0xA8, 0x03, 0xE6, 0x86, - 0x8E, 0x03, 0xE6, 0x87, 0xB2, 0x03, 0xE6, 0x95, - 0x8F, 0x03, 0xE6, 0x97, 0xA2, 0x03, 0xE6, 0x9A, + 0xAD, 0xDC, 0x03, 0x44, 0xCC, 0xB1, 0xDC, 0x03, + 0x45, 0xCC, 0x80, 0xE6, 0x03, 0x45, 0xCC, 0x81, + 0xE6, 0x03, 0x45, 0xCC, 0x83, 0xE6, 0x03, 0x45, + 0xCC, 0x86, 0xE6, 0x03, 0x45, 0xCC, 0x87, 0xE6, + 0x03, 0x45, 0xCC, 0x88, 0xE6, 0x03, 0x45, 0xCC, + 0x89, 0xE6, 0x03, 0x45, 0xCC, 0x8C, 0xE6, 0x03, + 0x45, 0xCC, 0x8F, 0xE6, 0x03, 0x45, 0xCC, 0x91, + 0xE6, 0x03, 0x45, 0xCC, 0xA8, 0xCA, 0x03, 0x45, // Bytes 2f00 - 2f3f - 0x91, 0x03, 0xE6, 0xA2, 0x85, 0x03, 0xE6, 0xB5, - 0xB7, 0x03, 0xE6, 0xB8, 0x9A, 0x03, 0xE6, 0xBC, - 0xA2, 0x03, 0xE7, 0x85, 0xAE, 0x03, 0xE7, 0x88, - 0xAB, 0x03, 0xE7, 0x90, 0xA2, 0x03, 0xE7, 0xA2, - 0x91, 0x03, 0xE7, 0xA5, 0x89, 0x03, 0xE7, 0xA5, - 0x88, 0x03, 0xE7, 0xA5, 0x90, 0x03, 0xE7, 0xA5, - 0x96, 0x03, 0xE7, 0xA6, 0x8D, 0x03, 0xE7, 0xA6, - 0x8E, 0x03, 0xE7, 0xA9, 0x80, 0x03, 0xE7, 0xAA, + 0xCC, 0xAD, 0xDC, 0x03, 0x45, 0xCC, 0xB0, 0xDC, + 0x03, 0x46, 0xCC, 0x87, 0xE6, 0x03, 0x47, 0xCC, + 0x81, 0xE6, 0x03, 0x47, 0xCC, 0x82, 0xE6, 0x03, + 0x47, 0xCC, 0x84, 0xE6, 0x03, 0x47, 0xCC, 0x86, + 0xE6, 0x03, 0x47, 0xCC, 0x87, 0xE6, 0x03, 0x47, + 0xCC, 0x8C, 0xE6, 0x03, 0x47, 0xCC, 0xA7, 0xCA, + 0x03, 0x48, 0xCC, 0x82, 0xE6, 0x03, 0x48, 0xCC, + 0x87, 0xE6, 0x03, 0x48, 0xCC, 0x88, 0xE6, 0x03, // Bytes 2f40 - 2f7f - 0x81, 0x03, 0xE7, 0xAF, 0x80, 0x03, 0xE7, 0xB8, - 0x89, 0x03, 0xE7, 0xB9, 0x81, 0x03, 0xE7, 0xBD, - 0xB2, 0x03, 0xE8, 0x80, 0x85, 0x03, 0xE8, 0x87, - 0xAD, 0x03, 0xE8, 0x89, 0xB9, 0x03, 0xE8, 0x91, - 0x97, 0x03, 0xE8, 0xA4, 0x90, 0x03, 0xE8, 0xA6, - 0x96, 0x03, 0xE8, 0xAC, 0x81, 0x03, 0xE8, 0xAC, - 0xB9, 0x03, 0xE8, 0xB3, 0x93, 0x03, 0xE8, 0xB4, - 0x88, 0x03, 0xE8, 0xBE, 0xB6, 0x03, 0xE9, 0x9B, + 0x48, 0xCC, 0x8C, 0xE6, 0x03, 0x48, 0xCC, 0xA3, + 0xDC, 0x03, 0x48, 0xCC, 0xA7, 0xCA, 0x03, 0x48, + 0xCC, 0xAE, 0xDC, 0x03, 0x49, 0xCC, 0x80, 0xE6, + 0x03, 0x49, 0xCC, 0x81, 0xE6, 0x03, 0x49, 0xCC, + 0x82, 0xE6, 0x03, 0x49, 0xCC, 0x83, 0xE6, 0x03, + 0x49, 0xCC, 0x84, 0xE6, 0x03, 0x49, 0xCC, 0x86, + 0xE6, 0x03, 0x49, 0xCC, 0x87, 0xE6, 0x03, 0x49, + 0xCC, 0x89, 0xE6, 0x03, 0x49, 0xCC, 0x8C, 0xE6, // Bytes 2f80 - 2fbf - 0xA3, 0x03, 0xE9, 0x9F, 0xBF, 0x03, 0xE9, 0xA0, - 0xBB, 0x03, 0xE6, 0x81, 0xB5, 0x04, 0xF0, 0xA4, - 0x8B, 0xAE, 0x03, 0xE8, 0x88, 0x98, 0x03, 0xE4, - 0xB8, 0xA6, 0x03, 0xE5, 0x86, 0xB5, 0x03, 0xE5, - 0x85, 0xA8, 0x03, 0xE4, 0xBE, 0x80, 0x03, 0xE5, - 0x85, 0x85, 0x03, 0xE5, 0x86, 0x80, 0x03, 0xE5, - 0x8B, 0x87, 0x03, 0xE5, 0x8B, 0xBA, 0x03, 0xE5, - 0x95, 0x95, 0x03, 0xE5, 0x96, 0x99, 0x03, 0xE5, + 0x03, 0x49, 0xCC, 0x8F, 0xE6, 0x03, 0x49, 0xCC, + 0x91, 0xE6, 0x03, 0x49, 0xCC, 0xA3, 0xDC, 0x03, + 0x49, 0xCC, 0xA8, 0xCA, 0x03, 0x49, 0xCC, 0xB0, + 0xDC, 0x03, 0x4A, 0xCC, 0x82, 0xE6, 0x03, 0x4B, + 0xCC, 0x81, 0xE6, 0x03, 0x4B, 0xCC, 0x8C, 0xE6, + 0x03, 0x4B, 0xCC, 0xA3, 0xDC, 0x03, 0x4B, 0xCC, + 0xA7, 0xCA, 0x03, 0x4B, 0xCC, 0xB1, 0xDC, 0x03, + 0x4C, 0xCC, 0x81, 0xE6, 0x03, 0x4C, 0xCC, 0x8C, // Bytes 2fc0 - 2fff - 0x97, 0xA2, 0x03, 0xE5, 0xA2, 0xB3, 0x03, 0xE5, - 0xA5, 0x84, 0x03, 0xE5, 0xA5, 0x94, 0x03, 0xE5, - 0xA9, 0xA2, 0x03, 0xE5, 0xAC, 0xA8, 0x03, 0xE5, - 0xBB, 0x92, 0x03, 0xE5, 0xBB, 0x99, 0x03, 0xE5, - 0xBD, 0xA9, 0x03, 0xE5, 0xBE, 0xAD, 0x03, 0xE6, - 0x83, 0x98, 0x03, 0xE6, 0x85, 0x8E, 0x03, 0xE6, - 0x84, 0x88, 0x03, 0xE6, 0x85, 0xA0, 0x03, 0xE6, - 0x88, 0xB4, 0x03, 0xE6, 0x8F, 0x84, 0x03, 0xE6, + 0xE6, 0x03, 0x4C, 0xCC, 0xA7, 0xCA, 0x03, 0x4C, + 0xCC, 0xAD, 0xDC, 0x03, 0x4C, 0xCC, 0xB1, 0xDC, + 0x03, 0x4D, 0xCC, 0x81, 0xE6, 0x03, 0x4D, 0xCC, + 0x87, 0xE6, 0x03, 0x4D, 0xCC, 0xA3, 0xDC, 0x03, + 0x4E, 0xCC, 0x80, 0xE6, 0x03, 0x4E, 0xCC, 0x81, + 0xE6, 0x03, 0x4E, 0xCC, 0x83, 0xE6, 0x03, 0x4E, + 0xCC, 0x87, 0xE6, 0x03, 0x4E, 0xCC, 0x8C, 0xE6, + 0x03, 0x4E, 0xCC, 0xA3, 0xDC, 0x03, 0x4E, 0xCC, // Bytes 3000 - 303f - 0x90, 0x9C, 0x03, 0xE6, 0x91, 0x92, 0x03, 0xE6, - 0x95, 0x96, 0x03, 0xE6, 0x9C, 0x9B, 0x03, 0xE6, - 0x9D, 0x96, 0x03, 0xE6, 0xBB, 0x9B, 0x03, 0xE6, - 0xBB, 0x8B, 0x03, 0xE7, 0x80, 0x9E, 0x03, 0xE7, - 0x9E, 0xA7, 0x03, 0xE7, 0x88, 0xB5, 0x03, 0xE7, - 0x8A, 0xAF, 0x03, 0xE7, 0x91, 0xB1, 0x03, 0xE7, - 0x94, 0x86, 0x03, 0xE7, 0x94, 0xBB, 0x03, 0xE7, - 0x98, 0x9D, 0x03, 0xE7, 0x98, 0x9F, 0x03, 0xE7, + 0xA7, 0xCA, 0x03, 0x4E, 0xCC, 0xAD, 0xDC, 0x03, + 0x4E, 0xCC, 0xB1, 0xDC, 0x03, 0x4F, 0xCC, 0x80, + 0xE6, 0x03, 0x4F, 0xCC, 0x81, 0xE6, 0x03, 0x4F, + 0xCC, 0x86, 0xE6, 0x03, 0x4F, 0xCC, 0x89, 0xE6, + 0x03, 0x4F, 0xCC, 0x8B, 0xE6, 0x03, 0x4F, 0xCC, + 0x8C, 0xE6, 0x03, 0x4F, 0xCC, 0x8F, 0xE6, 0x03, + 0x4F, 0xCC, 0x91, 0xE6, 0x03, 0x50, 0xCC, 0x81, + 0xE6, 0x03, 0x50, 0xCC, 0x87, 0xE6, 0x03, 0x52, // Bytes 3040 - 307f - 0x9B, 0x9B, 0x03, 0xE7, 0x9B, 0xB4, 0x03, 0xE7, - 0x9D, 0x8A, 0x03, 0xE7, 0x9D, 0x80, 0x03, 0xE7, - 0xA3, 0x8C, 0x03, 0xE7, 0xAA, 0xB1, 0x03, 0xE7, - 0xB1, 0xBB, 0x03, 0xE7, 0xB5, 0x9B, 0x03, 0xE7, - 0xBC, 0xBE, 0x03, 0xE8, 0x8D, 0x92, 0x03, 0xE8, - 0x8F, 0xAF, 0x03, 0xE8, 0x9D, 0xB9, 0x03, 0xE8, - 0xA5, 0x81, 0x03, 0xE8, 0xA6, 0x86, 0x03, 0xE8, - 0xAA, 0xBF, 0x03, 0xE8, 0xAB, 0x8B, 0x03, 0xE8, + 0xCC, 0x81, 0xE6, 0x03, 0x52, 0xCC, 0x87, 0xE6, + 0x03, 0x52, 0xCC, 0x8C, 0xE6, 0x03, 0x52, 0xCC, + 0x8F, 0xE6, 0x03, 0x52, 0xCC, 0x91, 0xE6, 0x03, + 0x52, 0xCC, 0xA7, 0xCA, 0x03, 0x52, 0xCC, 0xB1, + 0xDC, 0x03, 0x53, 0xCC, 0x82, 0xE6, 0x03, 0x53, + 0xCC, 0x87, 0xE6, 0x03, 0x53, 0xCC, 0xA6, 0xDC, + 0x03, 0x53, 0xCC, 0xA7, 0xCA, 0x03, 0x54, 0xCC, + 0x87, 0xE6, 0x03, 0x54, 0xCC, 0x8C, 0xE6, 0x03, // Bytes 3080 - 30bf - 0xAB, 0xAD, 0x03, 0xE8, 0xAE, 0x8A, 0x03, 0xE8, - 0xBC, 0xB8, 0x03, 0xE9, 0x81, 0xB2, 0x03, 0xE9, - 0x86, 0x99, 0x03, 0xE9, 0x89, 0xB6, 0x03, 0xE9, - 0x99, 0xBC, 0x03, 0xE9, 0x9F, 0x9B, 0x03, 0xE9, - 0xA0, 0x8B, 0x03, 0xE9, 0xAC, 0x92, 0x04, 0xF0, - 0xA2, 0xA1, 0x8A, 0x04, 0xF0, 0xA2, 0xA1, 0x84, - 0x04, 0xF0, 0xA3, 0x8F, 0x95, 0x03, 0xE3, 0xAE, - 0x9D, 0x03, 0xE4, 0x80, 0x98, 0x03, 0xE4, 0x80, + 0x54, 0xCC, 0xA3, 0xDC, 0x03, 0x54, 0xCC, 0xA6, + 0xDC, 0x03, 0x54, 0xCC, 0xA7, 0xCA, 0x03, 0x54, + 0xCC, 0xAD, 0xDC, 0x03, 0x54, 0xCC, 0xB1, 0xDC, + 0x03, 0x55, 0xCC, 0x80, 0xE6, 0x03, 0x55, 0xCC, + 0x81, 0xE6, 0x03, 0x55, 0xCC, 0x82, 0xE6, 0x03, + 0x55, 0xCC, 0x86, 0xE6, 0x03, 0x55, 0xCC, 0x89, + 0xE6, 0x03, 0x55, 0xCC, 0x8A, 0xE6, 0x03, 0x55, + 0xCC, 0x8B, 0xE6, 0x03, 0x55, 0xCC, 0x8C, 0xE6, // Bytes 30c0 - 30ff - 0xB9, 0x04, 0xF0, 0xA5, 0x89, 0x89, 0x04, 0xF0, - 0xA5, 0xB3, 0x90, 0x04, 0xF0, 0xA7, 0xBB, 0x93, - 0x03, 0xE9, 0xBD, 0x83, 0x03, 0xE9, 0xBE, 0x8E, - 0x02, 0x66, 0x66, 0x02, 0x66, 0x69, 0x02, 0x66, - 0x6C, 0x03, 0x66, 0x66, 0x69, 0x03, 0x66, 0x66, - 0x6C, 0x02, 0x73, 0x74, 0x04, 0xD5, 0xB4, 0xD5, - 0xB6, 0x04, 0xD5, 0xB4, 0xD5, 0xA5, 0x04, 0xD5, - 0xB4, 0xD5, 0xAB, 0x04, 0xD5, 0xBE, 0xD5, 0xB6, + 0x03, 0x55, 0xCC, 0x8F, 0xE6, 0x03, 0x55, 0xCC, + 0x91, 0xE6, 0x03, 0x55, 0xCC, 0xA3, 0xDC, 0x03, + 0x55, 0xCC, 0xA4, 0xDC, 0x03, 0x55, 0xCC, 0xA8, + 0xCA, 0x03, 0x55, 0xCC, 0xAD, 0xDC, 0x03, 0x55, + 0xCC, 0xB0, 0xDC, 0x03, 0x56, 0xCC, 0x83, 0xE6, + 0x03, 0x56, 0xCC, 0xA3, 0xDC, 0x03, 0x57, 0xCC, + 0x80, 0xE6, 0x03, 0x57, 0xCC, 0x81, 0xE6, 0x03, + 0x57, 0xCC, 0x82, 0xE6, 0x03, 0x57, 0xCC, 0x87, // Bytes 3100 - 313f - 0x04, 0xD5, 0xB4, 0xD5, 0xAD, 0x04, 0xD7, 0x99, - 0xD6, 0xB4, 0x04, 0xD7, 0xB2, 0xD6, 0xB7, 0x02, - 0xD7, 0xA2, 0x02, 0xD7, 0x94, 0x02, 0xD7, 0x9B, - 0x02, 0xD7, 0x9C, 0x02, 0xD7, 0x9D, 0x02, 0xD7, - 0xA8, 0x02, 0xD7, 0xAA, 0x04, 0xD7, 0xA9, 0xD7, - 0x81, 0x04, 0xD7, 0xA9, 0xD7, 0x82, 0x06, 0xD7, - 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0x06, 0xD7, 0xA9, - 0xD6, 0xBC, 0xD7, 0x82, 0x04, 0xD7, 0x90, 0xD6, + 0xE6, 0x03, 0x57, 0xCC, 0x88, 0xE6, 0x03, 0x57, + 0xCC, 0xA3, 0xDC, 0x03, 0x58, 0xCC, 0x87, 0xE6, + 0x03, 0x58, 0xCC, 0x88, 0xE6, 0x03, 0x59, 0xCC, + 0x80, 0xE6, 0x03, 0x59, 0xCC, 0x81, 0xE6, 0x03, + 0x59, 0xCC, 0x82, 0xE6, 0x03, 0x59, 0xCC, 0x83, + 0xE6, 0x03, 0x59, 0xCC, 0x84, 0xE6, 0x03, 0x59, + 0xCC, 0x87, 0xE6, 0x03, 0x59, 0xCC, 0x88, 0xE6, + 0x03, 0x59, 0xCC, 0x89, 0xE6, 0x03, 0x59, 0xCC, // Bytes 3140 - 317f - 0xB7, 0x04, 0xD7, 0x90, 0xD6, 0xB8, 0x04, 0xD7, - 0x90, 0xD6, 0xBC, 0x04, 0xD7, 0x91, 0xD6, 0xBC, - 0x04, 0xD7, 0x92, 0xD6, 0xBC, 0x04, 0xD7, 0x93, - 0xD6, 0xBC, 0x04, 0xD7, 0x94, 0xD6, 0xBC, 0x04, - 0xD7, 0x95, 0xD6, 0xBC, 0x04, 0xD7, 0x96, 0xD6, - 0xBC, 0x04, 0xD7, 0x98, 0xD6, 0xBC, 0x04, 0xD7, - 0x99, 0xD6, 0xBC, 0x04, 0xD7, 0x9A, 0xD6, 0xBC, - 0x04, 0xD7, 0x9B, 0xD6, 0xBC, 0x04, 0xD7, 0x9C, + 0xA3, 0xDC, 0x03, 0x5A, 0xCC, 0x81, 0xE6, 0x03, + 0x5A, 0xCC, 0x82, 0xE6, 0x03, 0x5A, 0xCC, 0x87, + 0xE6, 0x03, 0x5A, 0xCC, 0x8C, 0xE6, 0x03, 0x5A, + 0xCC, 0xA3, 0xDC, 0x03, 0x5A, 0xCC, 0xB1, 0xDC, + 0x03, 0x61, 0xCC, 0x80, 0xE6, 0x03, 0x61, 0xCC, + 0x81, 0xE6, 0x03, 0x61, 0xCC, 0x83, 0xE6, 0x03, + 0x61, 0xCC, 0x84, 0xE6, 0x03, 0x61, 0xCC, 0x89, + 0xE6, 0x03, 0x61, 0xCC, 0x8C, 0xE6, 0x03, 0x61, // Bytes 3180 - 31bf - 0xD6, 0xBC, 0x04, 0xD7, 0x9E, 0xD6, 0xBC, 0x04, - 0xD7, 0xA0, 0xD6, 0xBC, 0x04, 0xD7, 0xA1, 0xD6, - 0xBC, 0x04, 0xD7, 0xA3, 0xD6, 0xBC, 0x04, 0xD7, - 0xA4, 0xD6, 0xBC, 0x04, 0xD7, 0xA6, 0xD6, 0xBC, - 0x04, 0xD7, 0xA7, 0xD6, 0xBC, 0x04, 0xD7, 0xA8, - 0xD6, 0xBC, 0x04, 0xD7, 0xA9, 0xD6, 0xBC, 0x04, - 0xD7, 0xAA, 0xD6, 0xBC, 0x04, 0xD7, 0x95, 0xD6, - 0xB9, 0x04, 0xD7, 0x91, 0xD6, 0xBF, 0x04, 0xD7, + 0xCC, 0x8F, 0xE6, 0x03, 0x61, 0xCC, 0x91, 0xE6, + 0x03, 0x61, 0xCC, 0xA5, 0xDC, 0x03, 0x61, 0xCC, + 0xA8, 0xCA, 0x03, 0x62, 0xCC, 0x87, 0xE6, 0x03, + 0x62, 0xCC, 0xA3, 0xDC, 0x03, 0x62, 0xCC, 0xB1, + 0xDC, 0x03, 0x63, 0xCC, 0x81, 0xE6, 0x03, 0x63, + 0xCC, 0x82, 0xE6, 0x03, 0x63, 0xCC, 0x87, 0xE6, + 0x03, 0x63, 0xCC, 0x8C, 0xE6, 0x03, 0x64, 0xCC, + 0x87, 0xE6, 0x03, 0x64, 0xCC, 0x8C, 0xE6, 0x03, // Bytes 31c0 - 31ff - 0x9B, 0xD6, 0xBF, 0x04, 0xD7, 0xA4, 0xD6, 0xBF, - 0x04, 0xD7, 0x90, 0xD7, 0x9C, 0x02, 0xD9, 0xB1, - 0x02, 0xD9, 0xBB, 0x02, 0xD9, 0xBE, 0x02, 0xDA, - 0x80, 0x02, 0xD9, 0xBA, 0x02, 0xD9, 0xBF, 0x02, - 0xD9, 0xB9, 0x02, 0xDA, 0xA4, 0x02, 0xDA, 0xA6, - 0x02, 0xDA, 0x84, 0x02, 0xDA, 0x83, 0x02, 0xDA, - 0x86, 0x02, 0xDA, 0x87, 0x02, 0xDA, 0x8D, 0x02, - 0xDA, 0x8C, 0x02, 0xDA, 0x8E, 0x02, 0xDA, 0x88, + 0x64, 0xCC, 0xA3, 0xDC, 0x03, 0x64, 0xCC, 0xA7, + 0xCA, 0x03, 0x64, 0xCC, 0xAD, 0xDC, 0x03, 0x64, + 0xCC, 0xB1, 0xDC, 0x03, 0x65, 0xCC, 0x80, 0xE6, + 0x03, 0x65, 0xCC, 0x81, 0xE6, 0x03, 0x65, 0xCC, + 0x83, 0xE6, 0x03, 0x65, 0xCC, 0x86, 0xE6, 0x03, + 0x65, 0xCC, 0x87, 0xE6, 0x03, 0x65, 0xCC, 0x88, + 0xE6, 0x03, 0x65, 0xCC, 0x89, 0xE6, 0x03, 0x65, + 0xCC, 0x8C, 0xE6, 0x03, 0x65, 0xCC, 0x8F, 0xE6, // Bytes 3200 - 323f - 0x02, 0xDA, 0x98, 0x02, 0xDA, 0x91, 0x02, 0xDA, - 0xA9, 0x02, 0xDA, 0xAF, 0x02, 0xDA, 0xB3, 0x02, - 0xDA, 0xB1, 0x02, 0xDA, 0xBA, 0x02, 0xDA, 0xBB, - 0x02, 0xDB, 0x81, 0x02, 0xDA, 0xBE, 0x02, 0xDB, - 0x92, 0x02, 0xDA, 0xAD, 0x02, 0xDB, 0x87, 0x02, - 0xDB, 0x86, 0x02, 0xDB, 0x88, 0x02, 0xDB, 0x8B, - 0x02, 0xDB, 0x85, 0x02, 0xDB, 0x89, 0x02, 0xDB, - 0x90, 0x02, 0xD9, 0x89, 0x06, 0xD9, 0x8A, 0xD9, + 0x03, 0x65, 0xCC, 0x91, 0xE6, 0x03, 0x65, 0xCC, + 0xA8, 0xCA, 0x03, 0x65, 0xCC, 0xAD, 0xDC, 0x03, + 0x65, 0xCC, 0xB0, 0xDC, 0x03, 0x66, 0xCC, 0x87, + 0xE6, 0x03, 0x67, 0xCC, 0x81, 0xE6, 0x03, 0x67, + 0xCC, 0x82, 0xE6, 0x03, 0x67, 0xCC, 0x84, 0xE6, + 0x03, 0x67, 0xCC, 0x86, 0xE6, 0x03, 0x67, 0xCC, + 0x87, 0xE6, 0x03, 0x67, 0xCC, 0x8C, 0xE6, 0x03, + 0x67, 0xCC, 0xA7, 0xCA, 0x03, 0x68, 0xCC, 0x82, // Bytes 3240 - 327f - 0x94, 0xD8, 0xA7, 0x06, 0xD9, 0x8A, 0xD9, 0x94, - 0xDB, 0x95, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, - 0x88, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87, - 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0x06, - 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88, 0x06, 0xD9, - 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0x06, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x89, 0x02, 0xDB, 0x8C, 0x06, - 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, 0x06, 0xD9, + 0xE6, 0x03, 0x68, 0xCC, 0x87, 0xE6, 0x03, 0x68, + 0xCC, 0x88, 0xE6, 0x03, 0x68, 0xCC, 0x8C, 0xE6, + 0x03, 0x68, 0xCC, 0xA3, 0xDC, 0x03, 0x68, 0xCC, + 0xA7, 0xCA, 0x03, 0x68, 0xCC, 0xAE, 0xDC, 0x03, + 0x68, 0xCC, 0xB1, 0xDC, 0x03, 0x69, 0xCC, 0x80, + 0xE6, 0x03, 0x69, 0xCC, 0x81, 0xE6, 0x03, 0x69, + 0xCC, 0x82, 0xE6, 0x03, 0x69, 0xCC, 0x83, 0xE6, + 0x03, 0x69, 0xCC, 0x84, 0xE6, 0x03, 0x69, 0xCC, // Bytes 3280 - 32bf - 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x06, 0xD9, 0x8A, - 0xD9, 0x94, 0xD9, 0x85, 0x06, 0xD9, 0x8A, 0xD9, - 0x94, 0xD9, 0x8A, 0x04, 0xD8, 0xA8, 0xD8, 0xAC, - 0x04, 0xD8, 0xA8, 0xD8, 0xAD, 0x04, 0xD8, 0xA8, - 0xD8, 0xAE, 0x04, 0xD8, 0xA8, 0xD9, 0x85, 0x04, - 0xD8, 0xA8, 0xD9, 0x89, 0x04, 0xD8, 0xA8, 0xD9, - 0x8A, 0x04, 0xD8, 0xAA, 0xD8, 0xAC, 0x04, 0xD8, - 0xAA, 0xD8, 0xAD, 0x04, 0xD8, 0xAA, 0xD8, 0xAE, + 0x86, 0xE6, 0x03, 0x69, 0xCC, 0x89, 0xE6, 0x03, + 0x69, 0xCC, 0x8C, 0xE6, 0x03, 0x69, 0xCC, 0x8F, + 0xE6, 0x03, 0x69, 0xCC, 0x91, 0xE6, 0x03, 0x69, + 0xCC, 0xA3, 0xDC, 0x03, 0x69, 0xCC, 0xA8, 0xCA, + 0x03, 0x69, 0xCC, 0xB0, 0xDC, 0x03, 0x6A, 0xCC, + 0x82, 0xE6, 0x03, 0x6A, 0xCC, 0x8C, 0xE6, 0x03, + 0x6B, 0xCC, 0x81, 0xE6, 0x03, 0x6B, 0xCC, 0x8C, + 0xE6, 0x03, 0x6B, 0xCC, 0xA3, 0xDC, 0x03, 0x6B, // Bytes 32c0 - 32ff - 0x04, 0xD8, 0xAA, 0xD9, 0x85, 0x04, 0xD8, 0xAA, - 0xD9, 0x89, 0x04, 0xD8, 0xAA, 0xD9, 0x8A, 0x04, - 0xD8, 0xAB, 0xD8, 0xAC, 0x04, 0xD8, 0xAB, 0xD9, - 0x85, 0x04, 0xD8, 0xAB, 0xD9, 0x89, 0x04, 0xD8, - 0xAB, 0xD9, 0x8A, 0x04, 0xD8, 0xAC, 0xD8, 0xAD, - 0x04, 0xD8, 0xAC, 0xD9, 0x85, 0x04, 0xD8, 0xAD, - 0xD8, 0xAC, 0x04, 0xD8, 0xAD, 0xD9, 0x85, 0x04, - 0xD8, 0xAE, 0xD8, 0xAC, 0x04, 0xD8, 0xAE, 0xD8, + 0xCC, 0xA7, 0xCA, 0x03, 0x6B, 0xCC, 0xB1, 0xDC, + 0x03, 0x6C, 0xCC, 0x81, 0xE6, 0x03, 0x6C, 0xCC, + 0x8C, 0xE6, 0x03, 0x6C, 0xCC, 0xA7, 0xCA, 0x03, + 0x6C, 0xCC, 0xAD, 0xDC, 0x03, 0x6C, 0xCC, 0xB1, + 0xDC, 0x03, 0x6D, 0xCC, 0x81, 0xE6, 0x03, 0x6D, + 0xCC, 0x87, 0xE6, 0x03, 0x6D, 0xCC, 0xA3, 0xDC, + 0x03, 0x6E, 0xCC, 0x80, 0xE6, 0x03, 0x6E, 0xCC, + 0x81, 0xE6, 0x03, 0x6E, 0xCC, 0x83, 0xE6, 0x03, // Bytes 3300 - 333f - 0xAD, 0x04, 0xD8, 0xAE, 0xD9, 0x85, 0x04, 0xD8, - 0xB3, 0xD8, 0xAC, 0x04, 0xD8, 0xB3, 0xD8, 0xAD, - 0x04, 0xD8, 0xB3, 0xD8, 0xAE, 0x04, 0xD8, 0xB3, - 0xD9, 0x85, 0x04, 0xD8, 0xB5, 0xD8, 0xAD, 0x04, - 0xD8, 0xB5, 0xD9, 0x85, 0x04, 0xD8, 0xB6, 0xD8, - 0xAC, 0x04, 0xD8, 0xB6, 0xD8, 0xAD, 0x04, 0xD8, - 0xB6, 0xD8, 0xAE, 0x04, 0xD8, 0xB6, 0xD9, 0x85, - 0x04, 0xD8, 0xB7, 0xD8, 0xAD, 0x04, 0xD8, 0xB7, + 0x6E, 0xCC, 0x87, 0xE6, 0x03, 0x6E, 0xCC, 0x8C, + 0xE6, 0x03, 0x6E, 0xCC, 0xA3, 0xDC, 0x03, 0x6E, + 0xCC, 0xA7, 0xCA, 0x03, 0x6E, 0xCC, 0xAD, 0xDC, + 0x03, 0x6E, 0xCC, 0xB1, 0xDC, 0x03, 0x6F, 0xCC, + 0x80, 0xE6, 0x03, 0x6F, 0xCC, 0x81, 0xE6, 0x03, + 0x6F, 0xCC, 0x86, 0xE6, 0x03, 0x6F, 0xCC, 0x89, + 0xE6, 0x03, 0x6F, 0xCC, 0x8B, 0xE6, 0x03, 0x6F, + 0xCC, 0x8C, 0xE6, 0x03, 0x6F, 0xCC, 0x8F, 0xE6, // Bytes 3340 - 337f - 0xD9, 0x85, 0x04, 0xD8, 0xB8, 0xD9, 0x85, 0x04, - 0xD8, 0xB9, 0xD8, 0xAC, 0x04, 0xD8, 0xB9, 0xD9, - 0x85, 0x04, 0xD8, 0xBA, 0xD8, 0xAC, 0x04, 0xD8, - 0xBA, 0xD9, 0x85, 0x04, 0xD9, 0x81, 0xD8, 0xAC, - 0x04, 0xD9, 0x81, 0xD8, 0xAD, 0x04, 0xD9, 0x81, - 0xD8, 0xAE, 0x04, 0xD9, 0x81, 0xD9, 0x85, 0x04, - 0xD9, 0x81, 0xD9, 0x89, 0x04, 0xD9, 0x81, 0xD9, - 0x8A, 0x04, 0xD9, 0x82, 0xD8, 0xAD, 0x04, 0xD9, + 0x03, 0x6F, 0xCC, 0x91, 0xE6, 0x03, 0x70, 0xCC, + 0x81, 0xE6, 0x03, 0x70, 0xCC, 0x87, 0xE6, 0x03, + 0x72, 0xCC, 0x81, 0xE6, 0x03, 0x72, 0xCC, 0x87, + 0xE6, 0x03, 0x72, 0xCC, 0x8C, 0xE6, 0x03, 0x72, + 0xCC, 0x8F, 0xE6, 0x03, 0x72, 0xCC, 0x91, 0xE6, + 0x03, 0x72, 0xCC, 0xA7, 0xCA, 0x03, 0x72, 0xCC, + 0xB1, 0xDC, 0x03, 0x73, 0xCC, 0x82, 0xE6, 0x03, + 0x73, 0xCC, 0x87, 0xE6, 0x03, 0x73, 0xCC, 0xA6, // Bytes 3380 - 33bf - 0x82, 0xD9, 0x85, 0x04, 0xD9, 0x82, 0xD9, 0x89, - 0x04, 0xD9, 0x82, 0xD9, 0x8A, 0x04, 0xD9, 0x83, - 0xD8, 0xA7, 0x04, 0xD9, 0x83, 0xD8, 0xAC, 0x04, - 0xD9, 0x83, 0xD8, 0xAD, 0x04, 0xD9, 0x83, 0xD8, - 0xAE, 0x04, 0xD9, 0x83, 0xD9, 0x84, 0x04, 0xD9, - 0x83, 0xD9, 0x85, 0x04, 0xD9, 0x83, 0xD9, 0x89, - 0x04, 0xD9, 0x83, 0xD9, 0x8A, 0x04, 0xD9, 0x84, - 0xD8, 0xAC, 0x04, 0xD9, 0x84, 0xD8, 0xAD, 0x04, + 0xDC, 0x03, 0x73, 0xCC, 0xA7, 0xCA, 0x03, 0x74, + 0xCC, 0x87, 0xE6, 0x03, 0x74, 0xCC, 0x88, 0xE6, + 0x03, 0x74, 0xCC, 0x8C, 0xE6, 0x03, 0x74, 0xCC, + 0xA3, 0xDC, 0x03, 0x74, 0xCC, 0xA6, 0xDC, 0x03, + 0x74, 0xCC, 0xA7, 0xCA, 0x03, 0x74, 0xCC, 0xAD, + 0xDC, 0x03, 0x74, 0xCC, 0xB1, 0xDC, 0x03, 0x75, + 0xCC, 0x80, 0xE6, 0x03, 0x75, 0xCC, 0x81, 0xE6, + 0x03, 0x75, 0xCC, 0x82, 0xE6, 0x03, 0x75, 0xCC, // Bytes 33c0 - 33ff - 0xD9, 0x84, 0xD8, 0xAE, 0x04, 0xD9, 0x84, 0xD9, - 0x85, 0x04, 0xD9, 0x84, 0xD9, 0x89, 0x04, 0xD9, - 0x84, 0xD9, 0x8A, 0x04, 0xD9, 0x85, 0xD8, 0xAC, - 0x04, 0xD9, 0x85, 0xD8, 0xAD, 0x04, 0xD9, 0x85, - 0xD8, 0xAE, 0x04, 0xD9, 0x85, 0xD9, 0x85, 0x04, - 0xD9, 0x85, 0xD9, 0x89, 0x04, 0xD9, 0x85, 0xD9, - 0x8A, 0x04, 0xD9, 0x86, 0xD8, 0xAC, 0x04, 0xD9, - 0x86, 0xD8, 0xAD, 0x04, 0xD9, 0x86, 0xD8, 0xAE, + 0x86, 0xE6, 0x03, 0x75, 0xCC, 0x89, 0xE6, 0x03, + 0x75, 0xCC, 0x8A, 0xE6, 0x03, 0x75, 0xCC, 0x8B, + 0xE6, 0x03, 0x75, 0xCC, 0x8C, 0xE6, 0x03, 0x75, + 0xCC, 0x8F, 0xE6, 0x03, 0x75, 0xCC, 0x91, 0xE6, + 0x03, 0x75, 0xCC, 0xA3, 0xDC, 0x03, 0x75, 0xCC, + 0xA4, 0xDC, 0x03, 0x75, 0xCC, 0xA8, 0xCA, 0x03, + 0x75, 0xCC, 0xAD, 0xDC, 0x03, 0x75, 0xCC, 0xB0, + 0xDC, 0x03, 0x76, 0xCC, 0x83, 0xE6, 0x03, 0x76, // Bytes 3400 - 343f - 0x04, 0xD9, 0x86, 0xD9, 0x85, 0x04, 0xD9, 0x86, - 0xD9, 0x89, 0x04, 0xD9, 0x86, 0xD9, 0x8A, 0x04, - 0xD9, 0x87, 0xD8, 0xAC, 0x04, 0xD9, 0x87, 0xD9, - 0x85, 0x04, 0xD9, 0x87, 0xD9, 0x89, 0x04, 0xD9, - 0x87, 0xD9, 0x8A, 0x04, 0xD9, 0x8A, 0xD8, 0xAC, - 0x04, 0xD9, 0x8A, 0xD8, 0xAD, 0x04, 0xD9, 0x8A, - 0xD8, 0xAE, 0x04, 0xD9, 0x8A, 0xD9, 0x85, 0x04, - 0xD9, 0x8A, 0xD9, 0x89, 0x04, 0xD9, 0x8A, 0xD9, + 0xCC, 0xA3, 0xDC, 0x03, 0x77, 0xCC, 0x80, 0xE6, + 0x03, 0x77, 0xCC, 0x81, 0xE6, 0x03, 0x77, 0xCC, + 0x82, 0xE6, 0x03, 0x77, 0xCC, 0x87, 0xE6, 0x03, + 0x77, 0xCC, 0x88, 0xE6, 0x03, 0x77, 0xCC, 0x8A, + 0xE6, 0x03, 0x77, 0xCC, 0xA3, 0xDC, 0x03, 0x78, + 0xCC, 0x87, 0xE6, 0x03, 0x78, 0xCC, 0x88, 0xE6, + 0x03, 0x79, 0xCC, 0x80, 0xE6, 0x03, 0x79, 0xCC, + 0x81, 0xE6, 0x03, 0x79, 0xCC, 0x82, 0xE6, 0x03, // Bytes 3440 - 347f - 0x8A, 0x04, 0xD8, 0xB0, 0xD9, 0xB0, 0x04, 0xD8, - 0xB1, 0xD9, 0xB0, 0x04, 0xD9, 0x89, 0xD9, 0xB0, - 0x05, 0x20, 0xD9, 0x8C, 0xD9, 0x91, 0x05, 0x20, - 0xD9, 0x8D, 0xD9, 0x91, 0x05, 0x20, 0xD9, 0x8E, - 0xD9, 0x91, 0x05, 0x20, 0xD9, 0x8F, 0xD9, 0x91, - 0x05, 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x05, 0x20, - 0xD9, 0x91, 0xD9, 0xB0, 0x06, 0xD9, 0x8A, 0xD9, - 0x94, 0xD8, 0xB1, 0x06, 0xD9, 0x8A, 0xD9, 0x94, + 0x79, 0xCC, 0x83, 0xE6, 0x03, 0x79, 0xCC, 0x84, + 0xE6, 0x03, 0x79, 0xCC, 0x87, 0xE6, 0x03, 0x79, + 0xCC, 0x88, 0xE6, 0x03, 0x79, 0xCC, 0x89, 0xE6, + 0x03, 0x79, 0xCC, 0x8A, 0xE6, 0x03, 0x79, 0xCC, + 0xA3, 0xDC, 0x03, 0x7A, 0xCC, 0x81, 0xE6, 0x03, + 0x7A, 0xCC, 0x82, 0xE6, 0x03, 0x7A, 0xCC, 0x87, + 0xE6, 0x03, 0x7A, 0xCC, 0x8C, 0xE6, 0x03, 0x7A, + 0xCC, 0xA3, 0xDC, 0x03, 0x7A, 0xCC, 0xB1, 0xDC, // Bytes 3480 - 34bf - 0xD8, 0xB2, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, - 0x86, 0x04, 0xD8, 0xA8, 0xD8, 0xB1, 0x04, 0xD8, - 0xA8, 0xD8, 0xB2, 0x04, 0xD8, 0xA8, 0xD9, 0x86, - 0x04, 0xD8, 0xAA, 0xD8, 0xB1, 0x04, 0xD8, 0xAA, - 0xD8, 0xB2, 0x04, 0xD8, 0xAA, 0xD9, 0x86, 0x04, - 0xD8, 0xAB, 0xD8, 0xB1, 0x04, 0xD8, 0xAB, 0xD8, - 0xB2, 0x04, 0xD8, 0xAB, 0xD9, 0x86, 0x04, 0xD9, - 0x85, 0xD8, 0xA7, 0x04, 0xD9, 0x86, 0xD8, 0xB1, + 0x04, 0xC2, 0xA8, 0xCC, 0x80, 0xE6, 0x04, 0xC2, + 0xA8, 0xCC, 0x81, 0xE6, 0x04, 0xC2, 0xA8, 0xCD, + 0x82, 0xE6, 0x04, 0xC3, 0x86, 0xCC, 0x81, 0xE6, + 0x04, 0xC3, 0x86, 0xCC, 0x84, 0xE6, 0x04, 0xC3, + 0x98, 0xCC, 0x81, 0xE6, 0x04, 0xC3, 0xA6, 0xCC, + 0x81, 0xE6, 0x04, 0xC3, 0xA6, 0xCC, 0x84, 0xE6, + 0x04, 0xC3, 0xB8, 0xCC, 0x81, 0xE6, 0x04, 0xC5, + 0xBF, 0xCC, 0x87, 0xE6, 0x04, 0xC6, 0xB7, 0xCC, // Bytes 34c0 - 34ff - 0x04, 0xD9, 0x86, 0xD8, 0xB2, 0x04, 0xD9, 0x86, - 0xD9, 0x86, 0x04, 0xD9, 0x8A, 0xD8, 0xB1, 0x04, - 0xD9, 0x8A, 0xD8, 0xB2, 0x04, 0xD9, 0x8A, 0xD9, - 0x86, 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, - 0x06, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x87, 0x04, - 0xD8, 0xA8, 0xD9, 0x87, 0x04, 0xD8, 0xAA, 0xD9, - 0x87, 0x04, 0xD8, 0xB5, 0xD8, 0xAE, 0x04, 0xD9, - 0x84, 0xD9, 0x87, 0x04, 0xD9, 0x86, 0xD9, 0x87, + 0x8C, 0xE6, 0x04, 0xCA, 0x92, 0xCC, 0x8C, 0xE6, + 0x04, 0xCE, 0x91, 0xCC, 0x80, 0xE6, 0x04, 0xCE, + 0x91, 0xCC, 0x81, 0xE6, 0x04, 0xCE, 0x91, 0xCC, + 0x84, 0xE6, 0x04, 0xCE, 0x91, 0xCC, 0x86, 0xE6, + 0x04, 0xCE, 0x91, 0xCD, 0x85, 0xF0, 0x04, 0xCE, + 0x95, 0xCC, 0x80, 0xE6, 0x04, 0xCE, 0x95, 0xCC, + 0x81, 0xE6, 0x04, 0xCE, 0x97, 0xCC, 0x80, 0xE6, + 0x04, 0xCE, 0x97, 0xCC, 0x81, 0xE6, 0x04, 0xCE, // Bytes 3500 - 353f - 0x04, 0xD9, 0x87, 0xD9, 0xB0, 0x04, 0xD9, 0x8A, - 0xD9, 0x87, 0x04, 0xD8, 0xAB, 0xD9, 0x87, 0x04, - 0xD8, 0xB3, 0xD9, 0x87, 0x04, 0xD8, 0xB4, 0xD9, - 0x85, 0x04, 0xD8, 0xB4, 0xD9, 0x87, 0x06, 0xD9, - 0x80, 0xD9, 0x8E, 0xD9, 0x91, 0x06, 0xD9, 0x80, - 0xD9, 0x8F, 0xD9, 0x91, 0x06, 0xD9, 0x80, 0xD9, - 0x90, 0xD9, 0x91, 0x04, 0xD8, 0xB7, 0xD9, 0x89, - 0x04, 0xD8, 0xB7, 0xD9, 0x8A, 0x04, 0xD8, 0xB9, + 0x97, 0xCD, 0x85, 0xF0, 0x04, 0xCE, 0x99, 0xCC, + 0x80, 0xE6, 0x04, 0xCE, 0x99, 0xCC, 0x81, 0xE6, + 0x04, 0xCE, 0x99, 0xCC, 0x84, 0xE6, 0x04, 0xCE, + 0x99, 0xCC, 0x86, 0xE6, 0x04, 0xCE, 0x99, 0xCC, + 0x88, 0xE6, 0x04, 0xCE, 0x9F, 0xCC, 0x80, 0xE6, + 0x04, 0xCE, 0x9F, 0xCC, 0x81, 0xE6, 0x04, 0xCE, + 0xA1, 0xCC, 0x94, 0xE6, 0x04, 0xCE, 0xA5, 0xCC, + 0x80, 0xE6, 0x04, 0xCE, 0xA5, 0xCC, 0x81, 0xE6, // Bytes 3540 - 357f - 0xD9, 0x89, 0x04, 0xD8, 0xB9, 0xD9, 0x8A, 0x04, - 0xD8, 0xBA, 0xD9, 0x89, 0x04, 0xD8, 0xBA, 0xD9, - 0x8A, 0x04, 0xD8, 0xB3, 0xD9, 0x89, 0x04, 0xD8, - 0xB3, 0xD9, 0x8A, 0x04, 0xD8, 0xB4, 0xD9, 0x89, - 0x04, 0xD8, 0xB4, 0xD9, 0x8A, 0x04, 0xD8, 0xAD, - 0xD9, 0x89, 0x04, 0xD8, 0xAD, 0xD9, 0x8A, 0x04, - 0xD8, 0xAC, 0xD9, 0x89, 0x04, 0xD8, 0xAC, 0xD9, - 0x8A, 0x04, 0xD8, 0xAE, 0xD9, 0x89, 0x04, 0xD8, + 0x04, 0xCE, 0xA5, 0xCC, 0x84, 0xE6, 0x04, 0xCE, + 0xA5, 0xCC, 0x86, 0xE6, 0x04, 0xCE, 0xA5, 0xCC, + 0x88, 0xE6, 0x04, 0xCE, 0xA9, 0xCC, 0x80, 0xE6, + 0x04, 0xCE, 0xA9, 0xCC, 0x81, 0xE6, 0x04, 0xCE, + 0xA9, 0xCD, 0x85, 0xF0, 0x04, 0xCE, 0xB1, 0xCC, + 0x84, 0xE6, 0x04, 0xCE, 0xB1, 0xCC, 0x86, 0xE6, + 0x04, 0xCE, 0xB1, 0xCD, 0x85, 0xF0, 0x04, 0xCE, + 0xB5, 0xCC, 0x80, 0xE6, 0x04, 0xCE, 0xB5, 0xCC, // Bytes 3580 - 35bf - 0xAE, 0xD9, 0x8A, 0x04, 0xD8, 0xB5, 0xD9, 0x89, - 0x04, 0xD8, 0xB5, 0xD9, 0x8A, 0x04, 0xD8, 0xB6, - 0xD9, 0x89, 0x04, 0xD8, 0xB6, 0xD9, 0x8A, 0x04, - 0xD8, 0xB4, 0xD8, 0xAC, 0x04, 0xD8, 0xB4, 0xD8, - 0xAD, 0x04, 0xD8, 0xB4, 0xD8, 0xAE, 0x04, 0xD8, - 0xB4, 0xD8, 0xB1, 0x04, 0xD8, 0xB3, 0xD8, 0xB1, - 0x04, 0xD8, 0xB5, 0xD8, 0xB1, 0x04, 0xD8, 0xB6, - 0xD8, 0xB1, 0x04, 0xD8, 0xA7, 0xD9, 0x8B, 0x06, + 0x81, 0xE6, 0x04, 0xCE, 0xB7, 0xCD, 0x85, 0xF0, + 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0xE6, 0x04, 0xCE, + 0xB9, 0xCC, 0x81, 0xE6, 0x04, 0xCE, 0xB9, 0xCC, + 0x84, 0xE6, 0x04, 0xCE, 0xB9, 0xCC, 0x86, 0xE6, + 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0xE6, 0x04, 0xCE, + 0xBF, 0xCC, 0x80, 0xE6, 0x04, 0xCE, 0xBF, 0xCC, + 0x81, 0xE6, 0x04, 0xCF, 0x81, 0xCC, 0x93, 0xE6, + 0x04, 0xCF, 0x81, 0xCC, 0x94, 0xE6, 0x04, 0xCF, // Bytes 35c0 - 35ff - 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, 0x06, 0xD8, - 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD8, 0xAA, - 0xD8, 0xAD, 0xD9, 0x85, 0x06, 0xD8, 0xAA, 0xD8, - 0xAE, 0xD9, 0x85, 0x06, 0xD8, 0xAA, 0xD9, 0x85, - 0xD8, 0xAC, 0x06, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, - 0xAD, 0x06, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, - 0x06, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0x06, - 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, + 0x85, 0xCC, 0x80, 0xE6, 0x04, 0xCF, 0x85, 0xCC, + 0x81, 0xE6, 0x04, 0xCF, 0x85, 0xCC, 0x84, 0xE6, + 0x04, 0xCF, 0x85, 0xCC, 0x86, 0xE6, 0x04, 0xCF, + 0x85, 0xCD, 0x82, 0xE6, 0x04, 0xCF, 0x89, 0xCD, + 0x85, 0xF0, 0x04, 0xCF, 0x92, 0xCC, 0x81, 0xE6, + 0x04, 0xCF, 0x92, 0xCC, 0x88, 0xE6, 0x04, 0xD0, + 0x86, 0xCC, 0x88, 0xE6, 0x04, 0xD0, 0x90, 0xCC, + 0x86, 0xE6, 0x04, 0xD0, 0x90, 0xCC, 0x88, 0xE6, // Bytes 3600 - 363f - 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD8, 0xB3, - 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD8, 0xB3, 0xD8, - 0xAC, 0xD8, 0xAD, 0x06, 0xD8, 0xB3, 0xD8, 0xAC, - 0xD9, 0x89, 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, - 0xAD, 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, - 0x06, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0x06, - 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, 0x06, 0xD8, - 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xB4, + 0x04, 0xD0, 0x93, 0xCC, 0x81, 0xE6, 0x04, 0xD0, + 0x95, 0xCC, 0x80, 0xE6, 0x04, 0xD0, 0x95, 0xCC, + 0x86, 0xE6, 0x04, 0xD0, 0x95, 0xCC, 0x88, 0xE6, + 0x04, 0xD0, 0x96, 0xCC, 0x86, 0xE6, 0x04, 0xD0, + 0x96, 0xCC, 0x88, 0xE6, 0x04, 0xD0, 0x97, 0xCC, + 0x88, 0xE6, 0x04, 0xD0, 0x98, 0xCC, 0x80, 0xE6, + 0x04, 0xD0, 0x98, 0xCC, 0x84, 0xE6, 0x04, 0xD0, + 0x98, 0xCC, 0x86, 0xE6, 0x04, 0xD0, 0x98, 0xCC, // Bytes 3640 - 367f - 0xD8, 0xAD, 0xD9, 0x85, 0x06, 0xD8, 0xB4, 0xD8, - 0xAC, 0xD9, 0x8A, 0x06, 0xD8, 0xB4, 0xD9, 0x85, - 0xD8, 0xAE, 0x06, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, - 0x85, 0x06, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, - 0x06, 0xD8, 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x06, - 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD8, - 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xB7, - 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xB9, 0xD8, + 0x88, 0xE6, 0x04, 0xD0, 0x9A, 0xCC, 0x81, 0xE6, + 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0xE6, 0x04, 0xD0, + 0xA3, 0xCC, 0x84, 0xE6, 0x04, 0xD0, 0xA3, 0xCC, + 0x86, 0xE6, 0x04, 0xD0, 0xA3, 0xCC, 0x88, 0xE6, + 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0xE6, 0x04, 0xD0, + 0xA7, 0xCC, 0x88, 0xE6, 0x04, 0xD0, 0xAB, 0xCC, + 0x88, 0xE6, 0x04, 0xD0, 0xAD, 0xCC, 0x88, 0xE6, + 0x04, 0xD0, 0xB0, 0xCC, 0x86, 0xE6, 0x04, 0xD0, // Bytes 3680 - 36bf - 0xAC, 0xD9, 0x85, 0x06, 0xD8, 0xB9, 0xD9, 0x85, - 0xD9, 0x85, 0x06, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, - 0x89, 0x06, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, - 0x06, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x06, - 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD9, - 0x81, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, 0x82, - 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD9, 0x82, 0xD9, - 0x85, 0xD9, 0x85, 0x06, 0xD9, 0x84, 0xD8, 0xAD, + 0xB0, 0xCC, 0x88, 0xE6, 0x04, 0xD0, 0xB3, 0xCC, + 0x81, 0xE6, 0x04, 0xD0, 0xB5, 0xCC, 0x80, 0xE6, + 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0xE6, 0x04, 0xD0, + 0xB5, 0xCC, 0x88, 0xE6, 0x04, 0xD0, 0xB6, 0xCC, + 0x86, 0xE6, 0x04, 0xD0, 0xB6, 0xCC, 0x88, 0xE6, + 0x04, 0xD0, 0xB7, 0xCC, 0x88, 0xE6, 0x04, 0xD0, + 0xB8, 0xCC, 0x80, 0xE6, 0x04, 0xD0, 0xB8, 0xCC, + 0x84, 0xE6, 0x04, 0xD0, 0xB8, 0xCC, 0x86, 0xE6, // Bytes 36c0 - 36ff - 0xD9, 0x85, 0x06, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, - 0x8A, 0x06, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, - 0x06, 0xD9, 0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0x06, - 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, - 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0x06, 0xD9, 0x85, - 0xD8, 0xAD, 0xD8, 0xAC, 0x06, 0xD9, 0x85, 0xD8, - 0xAD, 0xD9, 0x85, 0x06, 0xD9, 0x85, 0xD8, 0xAD, - 0xD9, 0x8A, 0x06, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, + 0x04, 0xD0, 0xB8, 0xCC, 0x88, 0xE6, 0x04, 0xD0, + 0xBA, 0xCC, 0x81, 0xE6, 0x04, 0xD0, 0xBE, 0xCC, + 0x88, 0xE6, 0x04, 0xD1, 0x83, 0xCC, 0x84, 0xE6, + 0x04, 0xD1, 0x83, 0xCC, 0x86, 0xE6, 0x04, 0xD1, + 0x83, 0xCC, 0x88, 0xE6, 0x04, 0xD1, 0x83, 0xCC, + 0x8B, 0xE6, 0x04, 0xD1, 0x87, 0xCC, 0x88, 0xE6, + 0x04, 0xD1, 0x8B, 0xCC, 0x88, 0xE6, 0x04, 0xD1, + 0x8D, 0xCC, 0x88, 0xE6, 0x04, 0xD1, 0x96, 0xCC, // Bytes 3700 - 373f - 0xAD, 0x06, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, - 0x06, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0x06, - 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, 0x06, 0xD9, - 0x85, 0xD8, 0xAC, 0xD8, 0xAE, 0x06, 0xD9, 0x87, - 0xD9, 0x85, 0xD8, 0xAC, 0x06, 0xD9, 0x87, 0xD9, - 0x85, 0xD9, 0x85, 0x06, 0xD9, 0x86, 0xD8, 0xAD, - 0xD9, 0x85, 0x06, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, - 0x89, 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, + 0x88, 0xE6, 0x04, 0xD1, 0xB4, 0xCC, 0x8F, 0xE6, + 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0xE6, 0x04, 0xD3, + 0x98, 0xCC, 0x88, 0xE6, 0x04, 0xD3, 0x99, 0xCC, + 0x88, 0xE6, 0x04, 0xD3, 0xA8, 0xCC, 0x88, 0xE6, + 0x04, 0xD3, 0xA9, 0xCC, 0x88, 0xE6, 0x04, 0xD8, + 0xA7, 0xD9, 0x93, 0xE6, 0x04, 0xD8, 0xA7, 0xD9, + 0x94, 0xE6, 0x04, 0xD8, 0xA7, 0xD9, 0x95, 0xDC, + 0x04, 0xD9, 0x88, 0xD9, 0x94, 0xE6, 0x04, 0xD9, // Bytes 3740 - 377f - 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0x06, - 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, - 0x86, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD9, 0x8A, - 0xD9, 0x85, 0xD9, 0x85, 0x06, 0xD8, 0xA8, 0xD8, - 0xAE, 0xD9, 0x8A, 0x06, 0xD8, 0xAA, 0xD8, 0xAC, - 0xD9, 0x8A, 0x06, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, - 0x89, 0x06, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, - 0x06, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89, 0x06, + 0x8A, 0xD9, 0x94, 0xE6, 0x04, 0xDB, 0x81, 0xD9, + 0x94, 0xE6, 0x04, 0xDB, 0x92, 0xD9, 0x94, 0xE6, + 0x04, 0xDB, 0x95, 0xD9, 0x94, 0xE6, 0x05, 0x41, + 0xCC, 0x82, 0xCC, 0x80, 0xE6, 0x05, 0x41, 0xCC, + 0x82, 0xCC, 0x81, 0xE6, 0x05, 0x41, 0xCC, 0x82, + 0xCC, 0x83, 0xE6, 0x05, 0x41, 0xCC, 0x82, 0xCC, + 0x89, 0xE6, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x80, + 0xE6, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x81, 0xE6, // Bytes 3780 - 37bf - 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, - 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x06, 0xD8, 0xAC, - 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xAC, 0xD8, - 0xAD, 0xD9, 0x89, 0x06, 0xD8, 0xAC, 0xD9, 0x85, - 0xD9, 0x89, 0x06, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, - 0x89, 0x06, 0xD8, 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, - 0x06, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, - 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, 0xD9, + 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x83, 0xE6, 0x05, + 0x41, 0xCC, 0x86, 0xCC, 0x89, 0xE6, 0x05, 0x41, + 0xCC, 0x87, 0xCC, 0x84, 0xE6, 0x05, 0x41, 0xCC, + 0x88, 0xCC, 0x84, 0xE6, 0x05, 0x41, 0xCC, 0x8A, + 0xCC, 0x81, 0xE6, 0x05, 0x41, 0xCC, 0xA3, 0xCC, + 0x82, 0xE6, 0x05, 0x41, 0xCC, 0xA3, 0xCC, 0x86, + 0xE6, 0x05, 0x43, 0xCC, 0xA7, 0xCC, 0x81, 0xE6, + 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x80, 0xE6, 0x05, // Bytes 37c0 - 37ff - 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, 0x84, - 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD8, - 0xAD, 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD8, 0xAC, - 0xD9, 0x8A, 0x06, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, - 0x8A, 0x06, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, - 0x06, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x06, - 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, 0xD8, - 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x83, + 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xE6, 0x05, 0x45, + 0xCC, 0x82, 0xCC, 0x83, 0xE6, 0x05, 0x45, 0xCC, + 0x82, 0xCC, 0x89, 0xE6, 0x05, 0x45, 0xCC, 0x84, + 0xCC, 0x80, 0xE6, 0x05, 0x45, 0xCC, 0x84, 0xCC, + 0x81, 0xE6, 0x05, 0x45, 0xCC, 0xA3, 0xCC, 0x82, + 0xE6, 0x05, 0x45, 0xCC, 0xA7, 0xCC, 0x86, 0xE6, + 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0x05, + 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xE6, 0x05, 0x4F, // Bytes 3800 - 383f - 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD9, 0x86, 0xD8, - 0xAC, 0xD8, 0xAD, 0x06, 0xD9, 0x85, 0xD8, 0xAE, - 0xD9, 0x8A, 0x06, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, - 0x85, 0x06, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, - 0x06, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x8A, 0x06, - 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, - 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0x06, 0xD9, 0x81, - 0xD9, 0x85, 0xD9, 0x8A, 0x06, 0xD8, 0xA8, 0xD8, + 0xCC, 0x82, 0xCC, 0x80, 0xE6, 0x05, 0x4F, 0xCC, + 0x82, 0xCC, 0x81, 0xE6, 0x05, 0x4F, 0xCC, 0x82, + 0xCC, 0x83, 0xE6, 0x05, 0x4F, 0xCC, 0x82, 0xCC, + 0x89, 0xE6, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x81, + 0xE6, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x84, 0xE6, + 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x88, 0xE6, 0x05, + 0x4F, 0xCC, 0x84, 0xCC, 0x80, 0xE6, 0x05, 0x4F, + 0xCC, 0x84, 0xCC, 0x81, 0xE6, 0x05, 0x4F, 0xCC, // Bytes 3840 - 387f - 0xAD, 0xD9, 0x8A, 0x06, 0xD8, 0xB3, 0xD8, 0xAE, - 0xD9, 0x8A, 0x06, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, - 0x8A, 0x06, 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, - 0x06, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92, 0x08, - 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, - 0x08, 0xD8, 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, - 0xB1, 0x08, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, - 0xD8, 0xAF, 0x08, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, + 0x87, 0xCC, 0x84, 0xE6, 0x05, 0x4F, 0xCC, 0x88, + 0xCC, 0x84, 0xE6, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + 0x80, 0xE6, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x81, + 0xE6, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x83, 0xE6, + 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x89, 0xE6, 0x05, + 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xDC, 0x05, 0x4F, + 0xCC, 0xA3, 0xCC, 0x82, 0xE6, 0x05, 0x4F, 0xCC, + 0xA8, 0xCC, 0x84, 0xE6, 0x05, 0x52, 0xCC, 0xA3, // Bytes 3880 - 38bf - 0xB9, 0xD9, 0x85, 0x08, 0xD8, 0xB1, 0xD8, 0xB3, - 0xD9, 0x88, 0xD9, 0x84, 0x08, 0xD8, 0xB9, 0xD9, - 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x08, 0xD9, 0x88, - 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x06, 0xD8, - 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x21, 0xD8, 0xB5, - 0xD9, 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, - 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, - 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, + 0xCC, 0x84, 0xE6, 0x05, 0x53, 0xCC, 0x81, 0xCC, + 0x87, 0xE6, 0x05, 0x53, 0xCC, 0x8C, 0xCC, 0x87, + 0xE6, 0x05, 0x53, 0xCC, 0xA3, 0xCC, 0x87, 0xE6, + 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81, 0xE6, 0x05, + 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xE6, 0x05, 0x55, + 0xCC, 0x88, 0xCC, 0x80, 0xE6, 0x05, 0x55, 0xCC, + 0x88, 0xCC, 0x81, 0xE6, 0x05, 0x55, 0xCC, 0x88, + 0xCC, 0x84, 0xE6, 0x05, 0x55, 0xCC, 0x88, 0xCC, // Bytes 38c0 - 38ff - 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x0F, - 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8, 0xAC, 0xD9, - 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x87, 0x08, - 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, - 0x01, 0x2C, 0x03, 0xE3, 0x80, 0x81, 0x03, 0xE3, - 0x80, 0x82, 0x01, 0x3A, 0x01, 0x21, 0x01, 0x3F, - 0x03, 0xE3, 0x80, 0x96, 0x03, 0xE3, 0x80, 0x97, - 0x03, 0xE2, 0x80, 0x94, 0x03, 0xE2, 0x80, 0x93, + 0x8C, 0xE6, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x80, + 0xE6, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x81, 0xE6, + 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x83, 0xE6, 0x05, + 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0xE6, 0x05, 0x55, + 0xCC, 0x9B, 0xCC, 0xA3, 0xDC, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x80, 0xE6, 0x05, 0x61, 0xCC, 0x82, + 0xCC, 0x81, 0xE6, 0x05, 0x61, 0xCC, 0x82, 0xCC, + 0x83, 0xE6, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x89, // Bytes 3900 - 393f - 0x01, 0x5F, 0x01, 0x7B, 0x01, 0x7D, 0x03, 0xE3, - 0x80, 0x94, 0x03, 0xE3, 0x80, 0x95, 0x03, 0xE3, - 0x80, 0x90, 0x03, 0xE3, 0x80, 0x91, 0x03, 0xE3, - 0x80, 0x8A, 0x03, 0xE3, 0x80, 0x8B, 0x03, 0xE3, - 0x80, 0x8C, 0x03, 0xE3, 0x80, 0x8D, 0x03, 0xE3, - 0x80, 0x8E, 0x03, 0xE3, 0x80, 0x8F, 0x01, 0x5B, - 0x01, 0x5D, 0x01, 0x23, 0x01, 0x26, 0x01, 0x2A, - 0x01, 0x2D, 0x01, 0x3C, 0x01, 0x3E, 0x01, 0x5C, + 0xE6, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x80, 0xE6, + 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x81, 0xE6, 0x05, + 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xE6, 0x05, 0x61, + 0xCC, 0x86, 0xCC, 0x89, 0xE6, 0x05, 0x61, 0xCC, + 0x87, 0xCC, 0x84, 0xE6, 0x05, 0x61, 0xCC, 0x88, + 0xCC, 0x84, 0xE6, 0x05, 0x61, 0xCC, 0x8A, 0xCC, + 0x81, 0xE6, 0x05, 0x61, 0xCC, 0xA3, 0xCC, 0x82, + 0xE6, 0x05, 0x61, 0xCC, 0xA3, 0xCC, 0x86, 0xE6, // Bytes 3940 - 397f - 0x01, 0x24, 0x01, 0x25, 0x01, 0x40, 0x03, 0x20, - 0xD9, 0x8B, 0x04, 0xD9, 0x80, 0xD9, 0x8B, 0x03, - 0x20, 0xD9, 0x8C, 0x03, 0x20, 0xD9, 0x8D, 0x03, - 0x20, 0xD9, 0x8E, 0x04, 0xD9, 0x80, 0xD9, 0x8E, - 0x03, 0x20, 0xD9, 0x8F, 0x04, 0xD9, 0x80, 0xD9, - 0x8F, 0x03, 0x20, 0xD9, 0x90, 0x04, 0xD9, 0x80, - 0xD9, 0x90, 0x03, 0x20, 0xD9, 0x91, 0x04, 0xD9, - 0x80, 0xD9, 0x91, 0x03, 0x20, 0xD9, 0x92, 0x04, + 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81, 0xE6, 0x05, + 0x65, 0xCC, 0x82, 0xCC, 0x80, 0xE6, 0x05, 0x65, + 0xCC, 0x82, 0xCC, 0x81, 0xE6, 0x05, 0x65, 0xCC, + 0x82, 0xCC, 0x83, 0xE6, 0x05, 0x65, 0xCC, 0x82, + 0xCC, 0x89, 0xE6, 0x05, 0x65, 0xCC, 0x84, 0xCC, + 0x80, 0xE6, 0x05, 0x65, 0xCC, 0x84, 0xCC, 0x81, + 0xE6, 0x05, 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xE6, + 0x05, 0x65, 0xCC, 0xA7, 0xCC, 0x86, 0xE6, 0x05, // Bytes 3980 - 39bf - 0xD9, 0x80, 0xD9, 0x92, 0x02, 0xD8, 0xA1, 0x02, - 0xD8, 0xA7, 0x02, 0xD8, 0xA8, 0x02, 0xD8, 0xA9, - 0x02, 0xD8, 0xAA, 0x02, 0xD8, 0xAB, 0x02, 0xD8, - 0xAC, 0x02, 0xD8, 0xAD, 0x02, 0xD8, 0xAE, 0x02, - 0xD8, 0xAF, 0x02, 0xD8, 0xB0, 0x02, 0xD8, 0xB1, - 0x02, 0xD8, 0xB2, 0x02, 0xD8, 0xB3, 0x02, 0xD8, - 0xB4, 0x02, 0xD8, 0xB5, 0x02, 0xD8, 0xB6, 0x02, - 0xD8, 0xB7, 0x02, 0xD8, 0xB8, 0x02, 0xD8, 0xB9, + 0x69, 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0x05, 0x6C, + 0xCC, 0xA3, 0xCC, 0x84, 0xE6, 0x05, 0x6F, 0xCC, + 0x82, 0xCC, 0x80, 0xE6, 0x05, 0x6F, 0xCC, 0x82, + 0xCC, 0x81, 0xE6, 0x05, 0x6F, 0xCC, 0x82, 0xCC, + 0x83, 0xE6, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x89, + 0xE6, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x81, 0xE6, + 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84, 0xE6, 0x05, + 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xE6, 0x05, 0x6F, // Bytes 39c0 - 39ff - 0x02, 0xD8, 0xBA, 0x02, 0xD9, 0x81, 0x02, 0xD9, - 0x82, 0x02, 0xD9, 0x83, 0x02, 0xD9, 0x84, 0x02, - 0xD9, 0x85, 0x02, 0xD9, 0x86, 0x02, 0xD9, 0x87, - 0x02, 0xD9, 0x88, 0x02, 0xD9, 0x8A, 0x06, 0xD9, - 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0x06, 0xD9, 0x84, - 0xD8, 0xA7, 0xD9, 0x94, 0x06, 0xD9, 0x84, 0xD8, - 0xA7, 0xD9, 0x95, 0x04, 0xD9, 0x84, 0xD8, 0xA7, - 0x01, 0x22, 0x01, 0x27, 0x01, 0x2F, 0x01, 0x5E, + 0xCC, 0x84, 0xCC, 0x80, 0xE6, 0x05, 0x6F, 0xCC, + 0x84, 0xCC, 0x81, 0xE6, 0x05, 0x6F, 0xCC, 0x87, + 0xCC, 0x84, 0xE6, 0x05, 0x6F, 0xCC, 0x88, 0xCC, + 0x84, 0xE6, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x80, + 0xE6, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xE6, + 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x83, 0xE6, 0x05, + 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xE6, 0x05, 0x6F, + 0xCC, 0x9B, 0xCC, 0xA3, 0xDC, 0x05, 0x6F, 0xCC, // Bytes 3a00 - 3a3f - 0x01, 0x7C, 0x01, 0x7E, 0x03, 0xE2, 0xA6, 0x85, - 0x03, 0xE2, 0xA6, 0x86, 0x03, 0xE3, 0x83, 0xBB, - 0x03, 0xE3, 0x82, 0xA1, 0x03, 0xE3, 0x82, 0xA3, - 0x03, 0xE3, 0x82, 0xA5, 0x03, 0xE3, 0x82, 0xA7, - 0x03, 0xE3, 0x82, 0xA9, 0x03, 0xE3, 0x83, 0xA3, - 0x03, 0xE3, 0x83, 0xA5, 0x03, 0xE3, 0x83, 0xA7, - 0x03, 0xE3, 0x83, 0x83, 0x03, 0xE3, 0x83, 0xBC, - 0x03, 0xE3, 0x83, 0xB3, 0x03, 0xE3, 0x82, 0x99, + 0xA3, 0xCC, 0x82, 0xE6, 0x05, 0x6F, 0xCC, 0xA8, + 0xCC, 0x84, 0xE6, 0x05, 0x72, 0xCC, 0xA3, 0xCC, + 0x84, 0xE6, 0x05, 0x73, 0xCC, 0x81, 0xCC, 0x87, + 0xE6, 0x05, 0x73, 0xCC, 0x8C, 0xCC, 0x87, 0xE6, + 0x05, 0x73, 0xCC, 0xA3, 0xCC, 0x87, 0xE6, 0x05, + 0x75, 0xCC, 0x83, 0xCC, 0x81, 0xE6, 0x05, 0x75, + 0xCC, 0x84, 0xCC, 0x88, 0xE6, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x80, 0xE6, 0x05, 0x75, 0xCC, 0x88, // Bytes 3a40 - 3a7f - 0x03, 0xE3, 0x82, 0x9A, 0x02, 0xC2, 0xA2, 0x02, - 0xC2, 0xA3, 0x02, 0xC2, 0xAC, 0x02, 0xC2, 0xA6, - 0x02, 0xC2, 0xA5, 0x03, 0xE2, 0x82, 0xA9, 0x03, - 0xE2, 0x94, 0x82, 0x03, 0xE2, 0x86, 0x90, 0x03, - 0xE2, 0x86, 0x91, 0x03, 0xE2, 0x86, 0x92, 0x03, - 0xE2, 0x86, 0x93, 0x03, 0xE2, 0x96, 0xA0, 0x03, - 0xE2, 0x97, 0x8B, 0x08, 0xF0, 0x91, 0x82, 0x99, - 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, 0x91, 0x82, + 0xCC, 0x81, 0xE6, 0x05, 0x75, 0xCC, 0x88, 0xCC, + 0x84, 0xE6, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x8C, + 0xE6, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xE6, + 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x81, 0xE6, 0x05, + 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xE6, 0x05, 0x75, + 0xCC, 0x9B, 0xCC, 0x89, 0xE6, 0x05, 0x75, 0xCC, + 0x9B, 0xCC, 0xA3, 0xDC, 0x05, 0xE1, 0xBE, 0xBF, + 0xCC, 0x80, 0xE6, 0x05, 0xE1, 0xBE, 0xBF, 0xCC, // Bytes 3a80 - 3abf - 0x9B, 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, 0x91, - 0x82, 0xA5, 0xF0, 0x91, 0x82, 0xBA, 0x08, 0xF0, - 0x9D, 0x85, 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0x08, - 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, - 0x0C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, - 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x0C, 0xF0, 0x9D, - 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, - 0x85, 0xAF, 0x0C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x81, 0xE6, 0x05, 0xE1, 0xBE, 0xBF, 0xCD, 0x82, + 0xE6, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x80, 0xE6, + 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, 0xE6, 0x05, + 0xE1, 0xBF, 0xBE, 0xCD, 0x82, 0xE6, 0x05, 0xE2, + 0x86, 0x90, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x86, + 0x92, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x86, 0x94, + 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x87, 0x90, 0xCC, + 0xB8, 0x01, 0x05, 0xE2, 0x87, 0x92, 0xCC, 0xB8, // Bytes 3ac0 - 3aff - 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0x0C, - 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, - 0xF0, 0x9D, 0x85, 0xB1, 0x0C, 0xF0, 0x9D, 0x85, - 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, - 0xB2, 0x08, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, - 0x85, 0xA5, 0x08, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, - 0x9D, 0x85, 0xA5, 0x0C, 0xF0, 0x9D, 0x86, 0xB9, - 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, + 0x01, 0x05, 0xE2, 0x87, 0x94, 0xCC, 0xB8, 0x01, + 0x05, 0xE2, 0x88, 0x83, 0xCC, 0xB8, 0x01, 0x05, + 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x01, 0x05, 0xE2, + 0x88, 0x8B, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x88, + 0xA3, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x88, 0xA5, + 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x88, 0xBC, 0xCC, + 0xB8, 0x01, 0x05, 0xE2, 0x89, 0x83, 0xCC, 0xB8, + 0x01, 0x05, 0xE2, 0x89, 0x85, 0xCC, 0xB8, 0x01, // Bytes 3b00 - 3b3f - 0x0C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, - 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0x0C, 0xF0, 0x9D, - 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, - 0x85, 0xAF, 0x0C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, - 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0x02, - 0xC4, 0xB1, 0x02, 0xC8, 0xB7, 0x02, 0xCE, 0x91, - 0x02, 0xCE, 0x92, 0x02, 0xCE, 0x94, 0x02, 0xCE, - 0x95, 0x02, 0xCE, 0x96, 0x02, 0xCE, 0x97, 0x02, + 0x05, 0xE2, 0x89, 0x88, 0xCC, 0xB8, 0x01, 0x05, + 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0x01, 0x05, 0xE2, + 0x89, 0xA1, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x89, + 0xA4, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x89, 0xA5, + 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x89, 0xB2, 0xCC, + 0xB8, 0x01, 0x05, 0xE2, 0x89, 0xB3, 0xCC, 0xB8, + 0x01, 0x05, 0xE2, 0x89, 0xB6, 0xCC, 0xB8, 0x01, + 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8, 0x01, 0x05, // Bytes 3b40 - 3b7f - 0xCE, 0x99, 0x02, 0xCE, 0x9A, 0x02, 0xCE, 0x9B, - 0x02, 0xCE, 0x9C, 0x02, 0xCE, 0x9D, 0x02, 0xCE, - 0x9E, 0x02, 0xCE, 0x9F, 0x02, 0xCE, 0xA1, 0x02, - 0xCE, 0xA4, 0x02, 0xCE, 0xA6, 0x02, 0xCE, 0xA7, - 0x02, 0xCE, 0xA8, 0x03, 0xE2, 0x88, 0x87, 0x02, - 0xCE, 0xB1, 0x02, 0xCE, 0xB6, 0x02, 0xCE, 0xB7, - 0x02, 0xCE, 0xBB, 0x02, 0xCE, 0xBD, 0x02, 0xCE, - 0xBE, 0x02, 0xCE, 0xBF, 0x02, 0xCF, 0x83, 0x02, + 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x01, 0x05, 0xE2, + 0x89, 0xBB, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x89, + 0xBC, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x89, 0xBD, + 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x8A, 0x82, 0xCC, + 0xB8, 0x01, 0x05, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, + 0x01, 0x05, 0xE2, 0x8A, 0x86, 0xCC, 0xB8, 0x01, + 0x05, 0xE2, 0x8A, 0x87, 0xCC, 0xB8, 0x01, 0x05, + 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x01, 0x05, 0xE2, // Bytes 3b80 - 3bbf - 0xCF, 0x84, 0x02, 0xCF, 0x85, 0x02, 0xCF, 0x88, - 0x02, 0xCF, 0x89, 0x03, 0xE2, 0x88, 0x82, 0x02, - 0xCF, 0x9C, 0x02, 0xCF, 0x9D, 0x02, 0x30, 0x2E, - 0x02, 0x30, 0x2C, 0x02, 0x31, 0x2C, 0x02, 0x32, - 0x2C, 0x02, 0x33, 0x2C, 0x02, 0x34, 0x2C, 0x02, - 0x35, 0x2C, 0x02, 0x36, 0x2C, 0x02, 0x37, 0x2C, - 0x02, 0x38, 0x2C, 0x02, 0x39, 0x2C, 0x03, 0x28, - 0x41, 0x29, 0x03, 0x28, 0x42, 0x29, 0x03, 0x28, + 0x8A, 0x92, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x8A, + 0xA2, 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x8A, 0xA8, + 0xCC, 0xB8, 0x01, 0x05, 0xE2, 0x8A, 0xA9, 0xCC, + 0xB8, 0x01, 0x05, 0xE2, 0x8A, 0xAB, 0xCC, 0xB8, + 0x01, 0x05, 0xE2, 0x8A, 0xB2, 0xCC, 0xB8, 0x01, + 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8, 0x01, 0x05, + 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x01, 0x05, 0xE2, + 0x8A, 0xB5, 0xCC, 0xB8, 0x01, 0x06, 0xCE, 0x91, // Bytes 3bc0 - 3bff - 0x43, 0x29, 0x03, 0x28, 0x44, 0x29, 0x03, 0x28, - 0x45, 0x29, 0x03, 0x28, 0x46, 0x29, 0x03, 0x28, - 0x47, 0x29, 0x03, 0x28, 0x48, 0x29, 0x03, 0x28, - 0x49, 0x29, 0x03, 0x28, 0x4A, 0x29, 0x03, 0x28, - 0x4B, 0x29, 0x03, 0x28, 0x4C, 0x29, 0x03, 0x28, - 0x4D, 0x29, 0x03, 0x28, 0x4E, 0x29, 0x03, 0x28, - 0x4F, 0x29, 0x03, 0x28, 0x50, 0x29, 0x03, 0x28, - 0x51, 0x29, 0x03, 0x28, 0x52, 0x29, 0x03, 0x28, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0x91, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0x95, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x95, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0x95, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x95, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0x97, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0x97, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0x99, // Bytes 3c00 - 3c3f - 0x53, 0x29, 0x03, 0x28, 0x54, 0x29, 0x03, 0x28, - 0x55, 0x29, 0x03, 0x28, 0x56, 0x29, 0x03, 0x28, - 0x57, 0x29, 0x03, 0x28, 0x58, 0x29, 0x03, 0x28, - 0x59, 0x29, 0x03, 0x28, 0x5A, 0x29, 0x07, 0xE3, - 0x80, 0x94, 0x53, 0xE3, 0x80, 0x95, 0x02, 0x43, - 0x44, 0x02, 0x57, 0x5A, 0x02, 0x48, 0x56, 0x02, - 0x53, 0x44, 0x02, 0x53, 0x53, 0x03, 0x50, 0x50, - 0x56, 0x02, 0x57, 0x43, 0x02, 0x44, 0x4A, 0x06, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x99, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0x99, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0x99, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x99, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0x99, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0x9F, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x9F, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0x9F, // Bytes 3c40 - 3c7f - 0xE3, 0x81, 0xBB, 0xE3, 0x81, 0x8B, 0x06, 0xE3, - 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x03, 0xE5, 0xAD, - 0x97, 0x03, 0xE5, 0x8F, 0x8C, 0x03, 0xE5, 0xA4, - 0x9A, 0x03, 0xE8, 0xA7, 0xA3, 0x03, 0xE4, 0xBA, - 0xA4, 0x03, 0xE6, 0x98, 0xA0, 0x03, 0xE7, 0x84, - 0xA1, 0x03, 0xE5, 0x89, 0x8D, 0x03, 0xE5, 0xBE, - 0x8C, 0x03, 0xE5, 0x86, 0x8D, 0x03, 0xE6, 0x96, - 0xB0, 0x03, 0xE5, 0x88, 0x9D, 0x03, 0xE7, 0xB5, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0x9F, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xA5, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xA5, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xA5, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0xA9, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xA9, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB1, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB1, // Bytes 3c80 - 3cbf - 0x82, 0x03, 0xE8, 0xB2, 0xA9, 0x03, 0xE5, 0xA3, - 0xB0, 0x03, 0xE5, 0x90, 0xB9, 0x03, 0xE6, 0xBC, - 0x94, 0x03, 0xE6, 0x8A, 0x95, 0x03, 0xE6, 0x8D, - 0x95, 0x03, 0xE9, 0x81, 0x8A, 0x03, 0xE6, 0x8C, - 0x87, 0x03, 0xE6, 0x89, 0x93, 0x03, 0xE7, 0xA6, - 0x81, 0x03, 0xE7, 0xA9, 0xBA, 0x03, 0xE5, 0x90, - 0x88, 0x03, 0xE6, 0xBA, 0x80, 0x03, 0xE7, 0x94, - 0xB3, 0x03, 0xE5, 0x89, 0xB2, 0x03, 0xE5, 0x96, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB1, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB1, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB1, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB5, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xB5, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xB5, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xB5, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xB7, // Bytes 3cc0 - 3cff - 0xB6, 0x09, 0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, - 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE4, - 0xB8, 0x89, 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, - 0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x09, - 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89, 0xE3, 0x80, - 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9, - 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE6, - 0x89, 0x93, 0xE3, 0x80, 0x95, 0x09, 0xE3, 0x80, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB7, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB7, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB7, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB7, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x06, 0xCE, 0xB9, + 0xCC, 0x88, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x88, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0xB9, // Bytes 3d00 - 3d3f - 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, 0x09, - 0xE3, 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80, - 0x95, 0x09, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, - 0xE3, 0x80, 0x95, 0x03, 0xE5, 0xBE, 0x97, 0x03, - 0xE5, 0x8F, 0xAF, 0x03, 0xE4, 0xB8, 0xBD, 0x03, - 0xE4, 0xB8, 0xB8, 0x03, 0xE4, 0xB9, 0x81, 0x04, - 0xF0, 0xA0, 0x84, 0xA2, 0x03, 0xE4, 0xBD, 0xA0, - 0x03, 0xE4, 0xBE, 0xBB, 0x03, 0xE5, 0x80, 0x82, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xB9, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x06, 0xCE, 0xBF, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xBF, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCE, 0xBF, // Bytes 3d40 - 3d7f - 0x03, 0xE5, 0x81, 0xBA, 0x03, 0xE5, 0x82, 0x99, - 0x03, 0xE5, 0x83, 0x8F, 0x03, 0xE3, 0x92, 0x9E, - 0x04, 0xF0, 0xA0, 0x98, 0xBA, 0x03, 0xE5, 0x85, - 0x94, 0x03, 0xE5, 0x85, 0xA4, 0x03, 0xE5, 0x85, - 0xB7, 0x04, 0xF0, 0xA0, 0x94, 0x9C, 0x03, 0xE3, - 0x92, 0xB9, 0x03, 0xE5, 0x85, 0xA7, 0x04, 0xF0, - 0xA0, 0x95, 0x8B, 0x03, 0xE5, 0x86, 0x97, 0x03, - 0xE5, 0x86, 0xA4, 0x03, 0xE4, 0xBB, 0x8C, 0x03, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCE, 0xBF, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x88, 0xCC, 0x80, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x88, 0xCD, 0x82, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x06, 0xCF, 0x85, // Bytes 3d80 - 3dbf - 0xE5, 0x86, 0xAC, 0x04, 0xF0, 0xA9, 0x87, 0x9F, - 0x03, 0xE5, 0x88, 0x83, 0x03, 0xE3, 0x93, 0x9F, - 0x03, 0xE5, 0x88, 0xBB, 0x03, 0xE5, 0x89, 0x86, - 0x03, 0xE5, 0x89, 0xB7, 0x03, 0xE3, 0x94, 0x95, - 0x03, 0xE5, 0x8C, 0x85, 0x03, 0xE5, 0x8C, 0x86, - 0x03, 0xE5, 0x8D, 0x89, 0x03, 0xE5, 0x8D, 0x9A, - 0x03, 0xE5, 0x8D, 0xB3, 0x03, 0xE5, 0x8D, 0xBD, - 0x03, 0xE5, 0x8D, 0xBF, 0x04, 0xF0, 0xA0, 0xA8, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x06, 0xCF, 0x85, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x06, 0xCF, 0x89, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x06, 0xCF, 0x89, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x06, 0xCF, 0x89, + 0xCC, 0x93, 0xCD, 0x85, 0xF0, 0x06, 0xCF, 0x89, + 0xCC, 0x94, 0xCD, 0x85, 0xF0, 0x06, 0xCF, 0x89, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x06, 0xE0, 0xA4, // Bytes 3dc0 - 3dff - 0xAC, 0x03, 0xE7, 0x81, 0xB0, 0x03, 0xE5, 0x8F, - 0x8A, 0x03, 0xE5, 0x8F, 0x9F, 0x04, 0xF0, 0xA0, - 0xAD, 0xA3, 0x03, 0xE5, 0x8F, 0xAB, 0x03, 0xE5, - 0x8F, 0xB1, 0x03, 0xE5, 0x90, 0x86, 0x03, 0xE5, - 0x92, 0x9E, 0x03, 0xE5, 0x90, 0xB8, 0x03, 0xE5, - 0x91, 0x88, 0x03, 0xE5, 0x91, 0xA8, 0x03, 0xE5, - 0x92, 0xA2, 0x03, 0xE5, 0x93, 0xB6, 0x03, 0xE5, - 0x94, 0x90, 0x03, 0xE5, 0x95, 0x93, 0x03, 0xE5, + 0xA8, 0xE0, 0xA4, 0xBC, 0x07, 0x06, 0xE0, 0xA4, + 0xB0, 0xE0, 0xA4, 0xBC, 0x07, 0x06, 0xE0, 0xA4, + 0xB3, 0xE0, 0xA4, 0xBC, 0x07, 0x06, 0xE0, 0xB1, + 0x86, 0xE0, 0xB1, 0x96, 0x5B, 0x06, 0xE0, 0xB7, + 0x99, 0xE0, 0xB7, 0x8A, 0x09, 0x06, 0xE3, 0x81, + 0x86, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x8B, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x8D, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, // Bytes 3e00 - 3e3f - 0x95, 0xA3, 0x03, 0xE5, 0x96, 0x84, 0x03, 0xE5, - 0x96, 0xAB, 0x03, 0xE5, 0x96, 0xB3, 0x03, 0xE5, - 0x97, 0x82, 0x03, 0xE5, 0x9C, 0x96, 0x03, 0xE5, - 0x9C, 0x97, 0x03, 0xE5, 0x99, 0x91, 0x03, 0xE5, - 0x99, 0xB4, 0x03, 0xE5, 0xA3, 0xAE, 0x03, 0xE5, - 0x9F, 0x8E, 0x03, 0xE5, 0x9F, 0xB4, 0x03, 0xE5, - 0xA0, 0x8D, 0x03, 0xE5, 0x9E, 0x8B, 0x03, 0xE5, - 0xA0, 0xB2, 0x03, 0xE5, 0xA0, 0xB1, 0x03, 0xE5, + 0x8F, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x91, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x93, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x95, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x97, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x99, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x9B, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0x9D, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, // Bytes 3e40 - 3e7f - 0xA2, 0xAC, 0x04, 0xF0, 0xA1, 0x93, 0xA4, 0x03, - 0xE5, 0xA3, 0xB2, 0x03, 0xE5, 0xA3, 0xB7, 0x03, - 0xE5, 0xA4, 0x86, 0x03, 0xE5, 0xA4, 0xA2, 0x03, - 0xE5, 0xA5, 0xA2, 0x04, 0xF0, 0xA1, 0x9A, 0xA8, - 0x04, 0xF0, 0xA1, 0x9B, 0xAA, 0x03, 0xE5, 0xA7, - 0xAC, 0x03, 0xE5, 0xA8, 0x9B, 0x03, 0xE5, 0xA8, - 0xA7, 0x03, 0xE5, 0xA7, 0x98, 0x03, 0xE5, 0xA9, - 0xA6, 0x03, 0xE3, 0x9B, 0xAE, 0x03, 0xE3, 0x9B, + 0x9F, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xA1, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xA4, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xA6, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xA8, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xAF, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xAF, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x81, + 0xB2, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, // Bytes 3e80 - 3ebf - 0xBC, 0x03, 0xE5, 0xAC, 0x88, 0x03, 0xE5, 0xAC, - 0xBE, 0x04, 0xF0, 0xA1, 0xA7, 0x88, 0x03, 0xE5, - 0xAF, 0x83, 0x03, 0xE5, 0xAF, 0x98, 0x03, 0xE5, - 0xAF, 0xB3, 0x04, 0xF0, 0xA1, 0xAC, 0x98, 0x03, - 0xE5, 0xAF, 0xBF, 0x03, 0xE5, 0xB0, 0x86, 0x03, - 0xE5, 0xBD, 0x93, 0x03, 0xE3, 0x9E, 0x81, 0x03, - 0xE5, 0xB1, 0xA0, 0x03, 0xE5, 0xB3, 0x80, 0x03, - 0xE5, 0xB2, 0x8D, 0x04, 0xF0, 0xA1, 0xB7, 0xA4, + 0xB2, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x81, + 0xB5, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xB5, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x81, + 0xB8, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xB8, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x81, + 0xBB, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x81, + 0xBB, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x82, + 0x9D, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, // Bytes 3ec0 - 3eff - 0x03, 0xE5, 0xB5, 0x83, 0x04, 0xF0, 0xA1, 0xB7, - 0xA6, 0x03, 0xE5, 0xB5, 0xAE, 0x03, 0xE5, 0xB5, - 0xAB, 0x03, 0xE5, 0xB5, 0xBC, 0x03, 0xE5, 0xB7, - 0xA1, 0x03, 0xE5, 0xB7, 0xA2, 0x03, 0xE3, 0xA0, - 0xAF, 0x03, 0xE5, 0xB7, 0xBD, 0x03, 0xE5, 0xB8, - 0xA8, 0x03, 0xE5, 0xB8, 0xBD, 0x03, 0xE5, 0xB9, - 0xA9, 0x03, 0xE3, 0xA1, 0xA2, 0x04, 0xF0, 0xA2, - 0x86, 0x83, 0x03, 0xE3, 0xA1, 0xBC, 0x03, 0xE5, + 0xA6, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xAB, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xAD, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xB1, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xB3, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xB5, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xB7, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, // Bytes 3f00 - 3f3f - 0xBA, 0xB0, 0x03, 0xE5, 0xBA, 0xB3, 0x03, 0xE5, - 0xBA, 0xB6, 0x04, 0xF0, 0xAA, 0x8E, 0x92, 0x04, - 0xF0, 0xA2, 0x8C, 0xB1, 0x03, 0xE8, 0x88, 0x81, - 0x03, 0xE5, 0xBC, 0xA2, 0x03, 0xE3, 0xA3, 0x87, - 0x04, 0xF0, 0xA3, 0x8A, 0xB8, 0x04, 0xF0, 0xA6, - 0x87, 0x9A, 0x03, 0xE5, 0xBD, 0xA2, 0x03, 0xE5, - 0xBD, 0xAB, 0x03, 0xE3, 0xA3, 0xA3, 0x03, 0xE5, - 0xBE, 0x9A, 0x03, 0xE5, 0xBF, 0x8D, 0x03, 0xE5, + 0xB9, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xBB, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xBD, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x82, + 0xBF, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x81, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x84, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x86, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x88, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, // Bytes 3f40 - 3f7f - 0xBF, 0x97, 0x03, 0xE5, 0xBF, 0xB9, 0x03, 0xE6, - 0x82, 0x81, 0x03, 0xE3, 0xA4, 0xBA, 0x03, 0xE3, - 0xA4, 0x9C, 0x04, 0xF0, 0xA2, 0x9B, 0x94, 0x03, - 0xE6, 0x83, 0x87, 0x03, 0xE6, 0x85, 0x88, 0x03, - 0xE6, 0x85, 0x8C, 0x03, 0xE6, 0x85, 0xBA, 0x03, - 0xE6, 0x86, 0xB2, 0x03, 0xE6, 0x86, 0xA4, 0x03, - 0xE6, 0x86, 0xAF, 0x03, 0xE6, 0x87, 0x9E, 0x03, - 0xE6, 0x88, 0x90, 0x03, 0xE6, 0x88, 0x9B, 0x03, + 0x8F, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x83, + 0x92, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x92, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x83, + 0x95, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x95, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x83, // Bytes 3f80 - 3fbf - 0xE6, 0x89, 0x9D, 0x03, 0xE6, 0x8A, 0xB1, 0x03, - 0xE6, 0x8B, 0x94, 0x03, 0xE6, 0x8D, 0x90, 0x04, - 0xF0, 0xA2, 0xAC, 0x8C, 0x03, 0xE6, 0x8C, 0xBD, - 0x03, 0xE6, 0x8B, 0xBC, 0x03, 0xE6, 0x8D, 0xA8, - 0x03, 0xE6, 0x8E, 0x83, 0x03, 0xE6, 0x8F, 0xA4, - 0x04, 0xF0, 0xA2, 0xAF, 0xB1, 0x03, 0xE6, 0x90, - 0xA2, 0x03, 0xE6, 0x8F, 0x85, 0x03, 0xE6, 0x8E, - 0xA9, 0x03, 0xE3, 0xA8, 0xAE, 0x03, 0xE6, 0x91, + 0x9B, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0x9B, 0xE3, 0x82, 0x9A, 0x08, 0x06, 0xE3, 0x83, + 0xAF, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0xB0, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0xB1, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0xB2, 0xE3, 0x82, 0x99, 0x08, 0x06, 0xE3, 0x83, + 0xBD, 0xE3, 0x82, 0x99, 0x08, 0x08, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, // Bytes 3fc0 - 3fff - 0xA9, 0x03, 0xE6, 0x91, 0xBE, 0x03, 0xE6, 0x92, - 0x9D, 0x03, 0xE6, 0x91, 0xB7, 0x03, 0xE3, 0xA9, - 0xAC, 0x03, 0xE6, 0x95, 0xAC, 0x04, 0xF0, 0xA3, - 0x80, 0x8A, 0x03, 0xE6, 0x97, 0xA3, 0x03, 0xE6, - 0x9B, 0xB8, 0x03, 0xE6, 0x99, 0x89, 0x03, 0xE3, - 0xAC, 0x99, 0x03, 0xE3, 0xAC, 0x88, 0x03, 0xE3, - 0xAB, 0xA4, 0x03, 0xE5, 0x86, 0x92, 0x03, 0xE5, - 0x86, 0x95, 0x03, 0xE6, 0x9C, 0x80, 0x03, 0xE6, + 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x82, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0x91, 0xCC, 0x94, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0x91, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0x97, 0xCC, 0x93, // Bytes 4000 - 403f - 0x9A, 0x9C, 0x03, 0xE8, 0x82, 0xAD, 0x03, 0xE4, - 0x8F, 0x99, 0x03, 0xE6, 0x9C, 0xA1, 0x03, 0xE6, - 0x9D, 0x9E, 0x03, 0xE6, 0x9D, 0x93, 0x04, 0xF0, - 0xA3, 0x8F, 0x83, 0x03, 0xE3, 0xAD, 0x89, 0x03, - 0xE6, 0x9F, 0xBA, 0x03, 0xE6, 0x9E, 0x85, 0x03, - 0xE6, 0xA1, 0x92, 0x04, 0xF0, 0xA3, 0x91, 0xAD, - 0x03, 0xE6, 0xA2, 0x8E, 0x03, 0xE6, 0xA0, 0x9F, - 0x03, 0xE6, 0xA4, 0x94, 0x03, 0xE6, 0xA5, 0x82, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0x97, + 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0x97, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, // Bytes 4040 - 407f - 0x03, 0xE6, 0xA6, 0xA3, 0x03, 0xE6, 0xA7, 0xAA, - 0x03, 0xE6, 0xAA, 0xA8, 0x04, 0xF0, 0xA3, 0x9A, - 0xA3, 0x03, 0xE6, 0xAB, 0x9B, 0x03, 0xE3, 0xB0, - 0x98, 0x03, 0xE6, 0xAC, 0xA1, 0x04, 0xF0, 0xA3, - 0xA2, 0xA7, 0x03, 0xE6, 0xAD, 0x94, 0x03, 0xE3, - 0xB1, 0x8E, 0x03, 0xE6, 0xAD, 0xB2, 0x03, 0xE6, - 0xAE, 0x9F, 0x03, 0xE6, 0xAE, 0xBB, 0x04, 0xF0, - 0xA3, 0xAA, 0x8D, 0x04, 0xF0, 0xA1, 0xB4, 0x8B, + 0xF0, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x82, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xA9, 0xCC, 0x94, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xA9, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x80, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB1, 0xCC, 0x93, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB1, // Bytes 4080 - 40bf - 0x04, 0xF0, 0xA3, 0xAB, 0xBA, 0x03, 0xE6, 0xB1, - 0x8E, 0x04, 0xF0, 0xA3, 0xB2, 0xBC, 0x03, 0xE6, - 0xB2, 0xBF, 0x03, 0xE6, 0xB3, 0x8D, 0x03, 0xE6, - 0xB1, 0xA7, 0x03, 0xE6, 0xB4, 0x96, 0x03, 0xE6, - 0xB4, 0xBE, 0x03, 0xE6, 0xB5, 0xA9, 0x03, 0xE6, - 0xB5, 0xB8, 0x03, 0xE6, 0xB6, 0x85, 0x04, 0xF0, - 0xA3, 0xB4, 0x9E, 0x03, 0xE6, 0xB4, 0xB4, 0x03, - 0xE6, 0xB8, 0xAF, 0x03, 0xE6, 0xB9, 0xAE, 0x03, + 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB1, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, + 0xF0, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, // Bytes 40c0 - 40ff - 0xE3, 0xB4, 0xB3, 0x03, 0xE6, 0xBB, 0x87, 0x04, - 0xF0, 0xA3, 0xBB, 0x91, 0x03, 0xE6, 0xB7, 0xB9, - 0x03, 0xE6, 0xBD, 0xAE, 0x04, 0xF0, 0xA3, 0xBD, - 0x9E, 0x04, 0xF0, 0xA3, 0xBE, 0x8E, 0x03, 0xE6, - 0xBF, 0x86, 0x03, 0xE7, 0x80, 0xB9, 0x03, 0xE7, - 0x80, 0x9B, 0x03, 0xE3, 0xB6, 0x96, 0x03, 0xE7, - 0x81, 0x8A, 0x03, 0xE7, 0x81, 0xBD, 0x03, 0xE7, - 0x81, 0xB7, 0x03, 0xE7, 0x82, 0xAD, 0x04, 0xF0, + 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB7, 0xCC, 0x94, + 0xCC, 0x80, 0xCD, 0x85, 0xF0, 0x08, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, + 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, + 0xF0, 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x80, + 0xCD, 0x85, 0xF0, 0x08, 0xCF, 0x89, 0xCC, 0x93, + 0xCC, 0x81, 0xCD, 0x85, 0xF0, 0x08, 0xCF, 0x89, + 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, // Bytes 4100 - 413f - 0xA0, 0x94, 0xA5, 0x03, 0xE7, 0x85, 0x85, 0x04, - 0xF0, 0xA4, 0x89, 0xA3, 0x03, 0xE7, 0x86, 0x9C, - 0x04, 0xF0, 0xA4, 0x8E, 0xAB, 0x03, 0xE7, 0x88, - 0xA8, 0x03, 0xE7, 0x89, 0x90, 0x04, 0xF0, 0xA4, - 0x98, 0x88, 0x03, 0xE7, 0x8A, 0x80, 0x03, 0xE7, - 0x8A, 0x95, 0x04, 0xF0, 0xA4, 0x9C, 0xB5, 0x04, - 0xF0, 0xA4, 0xA0, 0x94, 0x03, 0xE7, 0x8D, 0xBA, - 0x03, 0xE7, 0x8E, 0x8B, 0x03, 0xE3, 0xBA, 0xAC, + 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, + 0xF0, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, + 0xCD, 0x85, 0xF0, 0x08, 0xCF, 0x89, 0xCC, 0x94, + 0xCD, 0x82, 0xCD, 0x85, 0xF0, 0x08, 0xF0, 0x91, + 0x82, 0x99, 0xF0, 0x91, 0x82, 0xBA, 0x07, 0x08, + 0xF0, 0x91, 0x82, 0x9B, 0xF0, 0x91, 0x82, 0xBA, + 0x07, 0x08, 0xF0, 0x91, 0x82, 0xA5, 0xF0, 0x91, + 0x82, 0xBA, 0x07, 0x09, 0xE0, 0xB7, 0x99, 0xE0, // Bytes 4140 - 417f - 0x03, 0xE7, 0x8E, 0xA5, 0x03, 0xE3, 0xBA, 0xB8, - 0x03, 0xE7, 0x91, 0x87, 0x03, 0xE7, 0x91, 0x9C, - 0x03, 0xE7, 0x92, 0x85, 0x03, 0xE7, 0x93, 0x8A, - 0x03, 0xE3, 0xBC, 0x9B, 0x03, 0xE7, 0x94, 0xA4, - 0x04, 0xF0, 0xA4, 0xB0, 0xB6, 0x03, 0xE7, 0x94, - 0xBE, 0x04, 0xF0, 0xA4, 0xB2, 0x92, 0x04, 0xF0, - 0xA2, 0x86, 0x9F, 0x03, 0xE7, 0x98, 0x90, 0x04, - 0xF0, 0xA4, 0xBE, 0xA1, 0x04, 0xF0, 0xA4, 0xBE, + 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0x09, 0x43, 0x20, + 0xCC, 0x81, 0xE6, 0x43, 0x20, 0xCC, 0x83, 0xE6, + 0x43, 0x20, 0xCC, 0x84, 0xE6, 0x43, 0x20, 0xCC, + 0x85, 0xE6, 0x43, 0x20, 0xCC, 0x86, 0xE6, 0x43, + 0x20, 0xCC, 0x87, 0xE6, 0x43, 0x20, 0xCC, 0x88, + 0xE6, 0x43, 0x20, 0xCC, 0x8A, 0xE6, 0x43, 0x20, + 0xCC, 0x8B, 0xE6, 0x43, 0x20, 0xCC, 0x93, 0xE6, + 0x43, 0x20, 0xCC, 0x94, 0xE6, 0x43, 0x20, 0xCC, // Bytes 4180 - 41bf - 0xB8, 0x04, 0xF0, 0xA5, 0x81, 0x84, 0x03, 0xE3, - 0xBF, 0xBC, 0x03, 0xE4, 0x80, 0x88, 0x04, 0xF0, - 0xA5, 0x83, 0xB3, 0x04, 0xF0, 0xA5, 0x83, 0xB2, - 0x04, 0xF0, 0xA5, 0x84, 0x99, 0x04, 0xF0, 0xA5, - 0x84, 0xB3, 0x03, 0xE7, 0x9C, 0x9E, 0x03, 0xE7, - 0x9C, 0x9F, 0x03, 0xE7, 0x9E, 0x8B, 0x03, 0xE4, - 0x81, 0x86, 0x03, 0xE4, 0x82, 0x96, 0x04, 0xF0, - 0xA5, 0x90, 0x9D, 0x03, 0xE7, 0xA1, 0x8E, 0x03, + 0xA7, 0xCA, 0x43, 0x20, 0xCC, 0xA8, 0xCA, 0x43, + 0x20, 0xCC, 0xB3, 0xDC, 0x43, 0x20, 0xCD, 0x82, + 0xE6, 0x43, 0x20, 0xCD, 0x85, 0xF0, 0x43, 0x20, + 0xD9, 0x8B, 0x1B, 0x43, 0x20, 0xD9, 0x8C, 0x1C, + 0x43, 0x20, 0xD9, 0x8D, 0x1D, 0x43, 0x20, 0xD9, + 0x8E, 0x1E, 0x43, 0x20, 0xD9, 0x8F, 0x1F, 0x43, + 0x20, 0xD9, 0x90, 0x20, 0x43, 0x20, 0xD9, 0x91, + 0x21, 0x43, 0x20, 0xD9, 0x92, 0x22, 0x43, 0x41, // Bytes 41c0 - 41ff - 0xE4, 0x83, 0xA3, 0x04, 0xF0, 0xA5, 0x98, 0xA6, - 0x04, 0xF0, 0xA5, 0x9A, 0x9A, 0x04, 0xF0, 0xA5, - 0x9B, 0x85, 0x03, 0xE7, 0xA7, 0xAB, 0x03, 0xE4, - 0x84, 0xAF, 0x03, 0xE7, 0xA9, 0x8A, 0x03, 0xE7, - 0xA9, 0x8F, 0x04, 0xF0, 0xA5, 0xA5, 0xBC, 0x04, - 0xF0, 0xA5, 0xAA, 0xA7, 0x03, 0xE7, 0xAB, 0xAE, - 0x03, 0xE4, 0x88, 0x82, 0x04, 0xF0, 0xA5, 0xAE, - 0xAB, 0x03, 0xE7, 0xAF, 0x86, 0x03, 0xE7, 0xAF, + 0xCC, 0x8A, 0xE6, 0x43, 0x73, 0xCC, 0x87, 0xE6, + 0x44, 0x20, 0xE3, 0x82, 0x99, 0x08, 0x44, 0x20, + 0xE3, 0x82, 0x9A, 0x08, 0x44, 0x44, 0x5A, 0xCC, + 0x8C, 0xE6, 0x44, 0x44, 0x7A, 0xCC, 0x8C, 0xE6, + 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xE6, 0x44, 0xC2, + 0xA8, 0xCC, 0x81, 0xE6, 0x44, 0xCE, 0x91, 0xCC, + 0x81, 0xE6, 0x44, 0xCE, 0x95, 0xCC, 0x81, 0xE6, + 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xE6, 0x44, 0xCE, // Bytes 4200 - 423f - 0x89, 0x03, 0xE4, 0x88, 0xA7, 0x04, 0xF0, 0xA5, - 0xB2, 0x80, 0x03, 0xE7, 0xB3, 0x92, 0x03, 0xE4, - 0x8A, 0xA0, 0x03, 0xE7, 0xB3, 0xA8, 0x03, 0xE7, - 0xB3, 0xA3, 0x03, 0xE7, 0xB4, 0x80, 0x04, 0xF0, - 0xA5, 0xBE, 0x86, 0x03, 0xE7, 0xB5, 0xA3, 0x03, - 0xE4, 0x8C, 0x81, 0x03, 0xE7, 0xB7, 0x87, 0x03, - 0xE7, 0xB8, 0x82, 0x03, 0xE7, 0xB9, 0x85, 0x03, - 0xE4, 0x8C, 0xB4, 0x04, 0xF0, 0xA6, 0x88, 0xA8, + 0x99, 0xCC, 0x81, 0xE6, 0x44, 0xCE, 0x9F, 0xCC, + 0x81, 0xE6, 0x44, 0xCE, 0xA5, 0xCC, 0x81, 0xE6, + 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xE6, 0x44, 0xCE, + 0xA9, 0xCC, 0x81, 0xE6, 0x44, 0xCE, 0xB1, 0xCC, + 0x81, 0xE6, 0x44, 0xCE, 0xB5, 0xCC, 0x81, 0xE6, + 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xE6, 0x44, 0xCE, + 0xB9, 0xCC, 0x81, 0xE6, 0x44, 0xCE, 0xBF, 0xCC, + 0x81, 0xE6, 0x44, 0xCF, 0x85, 0xCC, 0x81, 0xE6, // Bytes 4240 - 427f - 0x04, 0xF0, 0xA6, 0x89, 0x87, 0x03, 0xE4, 0x8D, - 0x99, 0x04, 0xF0, 0xA6, 0x8B, 0x99, 0x03, 0xE7, - 0xBD, 0xBA, 0x04, 0xF0, 0xA6, 0x8C, 0xBE, 0x03, - 0xE7, 0xBE, 0x95, 0x03, 0xE7, 0xBF, 0xBA, 0x04, - 0xF0, 0xA6, 0x93, 0x9A, 0x04, 0xF0, 0xA6, 0x94, - 0xA3, 0x03, 0xE8, 0x81, 0xA0, 0x04, 0xF0, 0xA6, - 0x96, 0xA8, 0x03, 0xE8, 0x81, 0xB0, 0x04, 0xF0, - 0xA3, 0x8D, 0x9F, 0x03, 0xE4, 0x8F, 0x95, 0x03, + 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xE6, 0x44, 0xD7, + 0x90, 0xD6, 0xB7, 0x11, 0x44, 0xD7, 0x90, 0xD6, + 0xB8, 0x12, 0x44, 0xD7, 0x90, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x15, 0x44, 0xD7, + 0x91, 0xD6, 0xBF, 0x17, 0x44, 0xD7, 0x92, 0xD6, + 0xBC, 0x15, 0x44, 0xD7, 0x93, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x15, 0x44, 0xD7, + 0x95, 0xD6, 0xB9, 0x13, 0x44, 0xD7, 0x95, 0xD6, // Bytes 4280 - 42bf - 0xE8, 0x82, 0xB2, 0x03, 0xE8, 0x84, 0x83, 0x03, - 0xE4, 0x90, 0x8B, 0x03, 0xE8, 0x84, 0xBE, 0x03, - 0xE5, 0xAA, 0xB5, 0x04, 0xF0, 0xA6, 0x9E, 0xA7, - 0x04, 0xF0, 0xA6, 0x9E, 0xB5, 0x04, 0xF0, 0xA3, - 0x8E, 0x93, 0x04, 0xF0, 0xA3, 0x8E, 0x9C, 0x03, - 0xE8, 0x88, 0x84, 0x03, 0xE8, 0xBE, 0x9E, 0x03, - 0xE4, 0x91, 0xAB, 0x03, 0xE8, 0x8A, 0x91, 0x03, - 0xE8, 0x8A, 0x8B, 0x03, 0xE8, 0x8A, 0x9D, 0x03, + 0xBC, 0x15, 0x44, 0xD7, 0x96, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x15, 0x44, 0xD7, + 0x99, 0xD6, 0xB4, 0x0E, 0x44, 0xD7, 0x99, 0xD6, + 0xBC, 0x15, 0x44, 0xD7, 0x9A, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x15, 0x44, 0xD7, + 0x9B, 0xD6, 0xBF, 0x17, 0x44, 0xD7, 0x9C, 0xD6, + 0xBC, 0x15, 0x44, 0xD7, 0x9E, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x15, 0x44, 0xD7, // Bytes 42c0 - 42ff - 0xE5, 0x8A, 0xB3, 0x03, 0xE8, 0x8A, 0xB1, 0x03, - 0xE8, 0x8A, 0xB3, 0x03, 0xE8, 0x8A, 0xBD, 0x03, - 0xE8, 0x8B, 0xA6, 0x04, 0xF0, 0xA6, 0xAC, 0xBC, - 0x03, 0xE8, 0x8C, 0x9D, 0x03, 0xE8, 0x8D, 0xA3, - 0x03, 0xE8, 0x8E, 0xAD, 0x03, 0xE8, 0x8C, 0xA3, - 0x03, 0xE8, 0x8E, 0xBD, 0x03, 0xE8, 0x8F, 0xA7, - 0x03, 0xE8, 0x8D, 0x93, 0x03, 0xE8, 0x8F, 0x8A, - 0x03, 0xE8, 0x8F, 0x8C, 0x03, 0xE8, 0x8F, 0x9C, + 0xA1, 0xD6, 0xBC, 0x15, 0x44, 0xD7, 0xA3, 0xD6, + 0xBC, 0x15, 0x44, 0xD7, 0xA4, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x17, 0x44, 0xD7, + 0xA6, 0xD6, 0xBC, 0x15, 0x44, 0xD7, 0xA7, 0xD6, + 0xBC, 0x15, 0x44, 0xD7, 0xA8, 0xD6, 0xBC, 0x15, + 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x15, 0x44, 0xD7, + 0xA9, 0xD7, 0x81, 0x18, 0x44, 0xD7, 0xA9, 0xD7, + 0x82, 0x19, 0x44, 0xD7, 0xAA, 0xD6, 0xBC, 0x15, // Bytes 4300 - 433f - 0x04, 0xF0, 0xA6, 0xB0, 0xB6, 0x04, 0xF0, 0xA6, - 0xB5, 0xAB, 0x04, 0xF0, 0xA6, 0xB3, 0x95, 0x03, - 0xE4, 0x94, 0xAB, 0x03, 0xE8, 0x93, 0xB1, 0x03, - 0xE8, 0x93, 0xB3, 0x03, 0xE8, 0x94, 0x96, 0x04, - 0xF0, 0xA7, 0x8F, 0x8A, 0x03, 0xE8, 0x95, 0xA4, - 0x04, 0xF0, 0xA6, 0xBC, 0xAC, 0x03, 0xE4, 0x95, - 0x9D, 0x03, 0xE4, 0x95, 0xA1, 0x04, 0xF0, 0xA6, - 0xBE, 0xB1, 0x04, 0xF0, 0xA7, 0x83, 0x92, 0x03, + 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x11, 0x44, 0xD8, + 0xA7, 0xD9, 0x8B, 0x1B, 0x44, 0xD8, 0xA7, 0xD9, + 0x93, 0xE6, 0x44, 0xD8, 0xA7, 0xD9, 0x94, 0xE6, + 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xDC, 0x44, 0xD8, + 0xB0, 0xD9, 0xB0, 0x23, 0x44, 0xD8, 0xB1, 0xD9, + 0xB0, 0x23, 0x44, 0xD9, 0x80, 0xD9, 0x8B, 0x1B, + 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x1E, 0x44, 0xD9, + 0x80, 0xD9, 0x8F, 0x1F, 0x44, 0xD9, 0x80, 0xD9, // Bytes 4340 - 437f - 0xE4, 0x95, 0xAB, 0x03, 0xE8, 0x99, 0x90, 0x03, - 0xE8, 0x99, 0xA7, 0x03, 0xE8, 0x99, 0xA9, 0x03, - 0xE8, 0x9A, 0xA9, 0x03, 0xE8, 0x9A, 0x88, 0x03, - 0xE8, 0x9C, 0x8E, 0x03, 0xE8, 0x9B, 0xA2, 0x03, - 0xE8, 0x9C, 0xA8, 0x03, 0xE8, 0x9D, 0xAB, 0x03, - 0xE8, 0x9E, 0x86, 0x03, 0xE4, 0x97, 0x97, 0x03, - 0xE8, 0x9F, 0xA1, 0x03, 0xE8, 0xA0, 0x81, 0x03, - 0xE4, 0x97, 0xB9, 0x03, 0xE8, 0xA1, 0xA0, 0x04, + 0x90, 0x20, 0x44, 0xD9, 0x80, 0xD9, 0x91, 0x21, + 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x22, 0x44, 0xD9, + 0x87, 0xD9, 0xB0, 0x23, 0x44, 0xD9, 0x88, 0xD9, + 0x94, 0xE6, 0x44, 0xD9, 0x89, 0xD9, 0xB0, 0x23, + 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xE6, 0x44, 0xDB, + 0x92, 0xD9, 0x94, 0xE6, 0x44, 0xDB, 0x95, 0xD9, + 0x94, 0xE6, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x80, + 0xE6, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x81, 0xE6, // Bytes 4380 - 43bf - 0xF0, 0xA7, 0x99, 0xA7, 0x03, 0xE8, 0xA3, 0x97, - 0x03, 0xE8, 0xA3, 0x9E, 0x03, 0xE4, 0x98, 0xB5, - 0x03, 0xE8, 0xA3, 0xBA, 0x03, 0xE3, 0x92, 0xBB, - 0x04, 0xF0, 0xA7, 0xA2, 0xAE, 0x04, 0xF0, 0xA7, - 0xA5, 0xA6, 0x03, 0xE4, 0x9A, 0xBE, 0x03, 0xE4, - 0x9B, 0x87, 0x03, 0xE8, 0xAA, 0xA0, 0x04, 0xF0, - 0xA7, 0xB2, 0xA8, 0x03, 0xE8, 0xB2, 0xAB, 0x03, - 0xE8, 0xB3, 0x81, 0x03, 0xE8, 0xB4, 0x9B, 0x03, + 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xE6, 0x45, + 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x45, 0x20, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x45, 0x20, 0xCC, + 0x93, 0xCD, 0x82, 0xE6, 0x45, 0x20, 0xCC, 0x94, + 0xCC, 0x80, 0xE6, 0x45, 0x20, 0xCC, 0x94, 0xCC, + 0x81, 0xE6, 0x45, 0x20, 0xCC, 0x94, 0xCD, 0x82, + 0xE6, 0x45, 0x20, 0xD9, 0x8C, 0xD9, 0x91, 0x21, + 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, 0x21, 0x45, // Bytes 43c0 - 43ff - 0xE8, 0xB5, 0xB7, 0x04, 0xF0, 0xA7, 0xBC, 0xAF, - 0x04, 0xF0, 0xA0, 0xA0, 0x84, 0x03, 0xE8, 0xB7, - 0x8B, 0x03, 0xE8, 0xB6, 0xBC, 0x03, 0xE8, 0xB7, - 0xB0, 0x04, 0xF0, 0xA0, 0xA3, 0x9E, 0x03, 0xE8, - 0xBB, 0x94, 0x04, 0xF0, 0xA8, 0x97, 0x92, 0x04, - 0xF0, 0xA8, 0x97, 0xAD, 0x03, 0xE9, 0x82, 0x94, - 0x03, 0xE9, 0x83, 0xB1, 0x03, 0xE9, 0x84, 0x91, - 0x04, 0xF0, 0xA8, 0x9C, 0xAE, 0x03, 0xE9, 0x84, + 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x21, 0x45, 0x20, + 0xD9, 0x8F, 0xD9, 0x91, 0x21, 0x45, 0x20, 0xD9, + 0x90, 0xD9, 0x91, 0x21, 0x45, 0x20, 0xD9, 0x91, + 0xD9, 0xB0, 0x23, 0x45, 0xE2, 0xAB, 0x9D, 0xCC, + 0xB8, 0x01, 0x46, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, + 0x81, 0xE6, 0x46, 0xCF, 0x85, 0xCC, 0x88, 0xCC, + 0x81, 0xE6, 0x46, 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, + 0x81, 0x18, 0x46, 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, // Bytes 4400 - 443f - 0x9B, 0x03, 0xE9, 0x88, 0xB8, 0x03, 0xE9, 0x8B, - 0x97, 0x03, 0xE9, 0x8B, 0x98, 0x03, 0xE9, 0x89, - 0xBC, 0x03, 0xE9, 0x8F, 0xB9, 0x03, 0xE9, 0x90, - 0x95, 0x04, 0xF0, 0xA8, 0xAF, 0xBA, 0x03, 0xE9, - 0x96, 0x8B, 0x03, 0xE4, 0xA6, 0x95, 0x03, 0xE9, - 0x96, 0xB7, 0x04, 0xF0, 0xA8, 0xB5, 0xB7, 0x03, - 0xE4, 0xA7, 0xA6, 0x03, 0xE9, 0x9B, 0x83, 0x03, - 0xE5, 0xB6, 0xB2, 0x03, 0xE9, 0x9C, 0xA3, 0x04, + 0x82, 0x19, 0x46, 0xD9, 0x80, 0xD9, 0x8E, 0xD9, + 0x91, 0x21, 0x46, 0xD9, 0x80, 0xD9, 0x8F, 0xD9, + 0x91, 0x21, 0x46, 0xD9, 0x80, 0xD9, 0x90, 0xD9, + 0x91, 0x21, 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, + 0x93, 0xE6, 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, + 0x94, 0xE6, 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, + 0x95, 0xDC, 0x46, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0x96, 0xE0, 0xA4, // Bytes 4440 - 447f - 0xF0, 0xA9, 0x85, 0x85, 0x04, 0xF0, 0xA9, 0x88, - 0x9A, 0x03, 0xE4, 0xA9, 0xAE, 0x03, 0xE4, 0xA9, - 0xB6, 0x03, 0xE9, 0x9F, 0xA0, 0x04, 0xF0, 0xA9, - 0x90, 0x8A, 0x03, 0xE4, 0xAA, 0xB2, 0x04, 0xF0, - 0xA9, 0x92, 0x96, 0x03, 0xE9, 0xA0, 0xA9, 0x04, - 0xF0, 0xA9, 0x96, 0xB6, 0x03, 0xE9, 0xA3, 0xA2, - 0x03, 0xE4, 0xAC, 0xB3, 0x03, 0xE9, 0xA4, 0xA9, - 0x03, 0xE9, 0xA6, 0xA7, 0x03, 0xE9, 0xA7, 0x82, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0x97, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0x9C, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, + 0xBC, 0x07, 0x46, 0xE0, 0xA6, 0xA1, 0xE0, 0xA6, + 0xBC, 0x07, 0x46, 0xE0, 0xA6, 0xA2, 0xE0, 0xA6, // Bytes 4480 - 44bf - 0x03, 0xE9, 0xA7, 0xBE, 0x03, 0xE4, 0xAF, 0x8E, - 0x04, 0xF0, 0xA9, 0xAC, 0xB0, 0x03, 0xE9, 0xB1, - 0x80, 0x03, 0xE9, 0xB3, 0xBD, 0x03, 0xE4, 0xB3, - 0x8E, 0x03, 0xE4, 0xB3, 0xAD, 0x03, 0xE9, 0xB5, - 0xA7, 0x04, 0xF0, 0xAA, 0x83, 0x8E, 0x03, 0xE4, - 0xB3, 0xB8, 0x04, 0xF0, 0xAA, 0x84, 0x85, 0x04, - 0xF0, 0xAA, 0x88, 0x8E, 0x04, 0xF0, 0xAA, 0x8A, - 0x91, 0x03, 0xE4, 0xB5, 0x96, 0x03, 0xE9, 0xBB, + 0xBC, 0x07, 0x46, 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0x96, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0x97, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0x9C, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0xAB, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, + 0xBC, 0x07, 0x46, 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, // Bytes 44c0 - 44ff - 0xBE, 0x03, 0xE9, 0xBC, 0x85, 0x03, 0xE9, 0xBC, - 0x8F, 0x03, 0xE9, 0xBC, 0x96, 0x04, 0xF0, 0xAA, - 0x98, 0x80, + 0xBC, 0x07, 0x46, 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, + 0xBC, 0x07, 0x46, 0xE0, 0xBE, 0xB2, 0xE0, 0xBE, + 0x80, 0x82, 0x46, 0xE0, 0xBE, 0xB3, 0xE0, 0xBE, + 0x80, 0x82, 0x46, 0xE3, 0x83, 0x86, 0xE3, 0x82, + 0x99, 0x08, 0x48, 0xF0, 0x9D, 0x85, 0x97, 0xF0, + 0x9D, 0x85, 0xA5, 0xD8, 0x48, 0xF0, 0x9D, 0x85, + 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xD8, 0x48, 0xF0, + 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xD8, + // Bytes 4500 - 453f + 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, + 0xA5, 0xD8, 0x49, 0xE0, 0xBE, 0xB2, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBE, 0x80, 0x82, 0x49, 0xE0, 0xBE, + 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x82, + 0x49, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0x08, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, + 0x82, 0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, + 0x08, 0x4C, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, + // Bytes 4540 - 457f + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x08, 0x4C, + 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x88, 0xE3, 0x82, 0x99, 0x08, 0x4C, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAE, 0xD8, 0x4C, 0xF0, 0x9D, 0x85, 0x98, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, + 0xD8, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xD8, 0x4C, + // Bytes 4580 - 45bf + 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, + 0xF0, 0x9D, 0x85, 0xB1, 0xD8, 0x4C, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xB2, 0xD8, 0x4C, 0xF0, 0x9D, 0x86, 0xB9, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, + 0xD8, 0x4C, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xD8, 0x4C, + 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, + // Bytes 45c0 - 45ff + 0xF0, 0x9D, 0x85, 0xAE, 0xD8, 0x4C, 0xF0, 0x9D, + 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAF, 0xD8, 0x4F, 0xE3, 0x82, 0xA4, 0xE3, + 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, + 0xE3, 0x82, 0x99, 0x08, 0x4F, 0xE3, 0x82, 0xB7, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x08, 0x4F, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + // Bytes 4600 - 463f + 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x08, 0x4F, 0xE3, + 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x08, 0x52, + 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x08, 0x52, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x08, 0x83, + // Bytes 4640 - 467f + 0x41, 0xCC, 0x82, 0xE6, 0x83, 0x41, 0xCC, 0x86, + 0xE6, 0x83, 0x41, 0xCC, 0x87, 0xE6, 0x83, 0x41, + 0xCC, 0x88, 0xE6, 0x83, 0x41, 0xCC, 0x8A, 0xE6, + 0x83, 0x41, 0xCC, 0xA3, 0xDC, 0x83, 0x43, 0xCC, + 0xA7, 0xCA, 0x83, 0x45, 0xCC, 0x82, 0xE6, 0x83, + 0x45, 0xCC, 0x84, 0xE6, 0x83, 0x45, 0xCC, 0xA3, + 0xDC, 0x83, 0x45, 0xCC, 0xA7, 0xCA, 0x83, 0x49, + 0xCC, 0x88, 0xE6, 0x83, 0x4C, 0xCC, 0xA3, 0xDC, + // Bytes 4680 - 46bf + 0x83, 0x4F, 0xCC, 0x82, 0xE6, 0x83, 0x4F, 0xCC, + 0x83, 0xE6, 0x83, 0x4F, 0xCC, 0x84, 0xE6, 0x83, + 0x4F, 0xCC, 0x87, 0xE6, 0x83, 0x4F, 0xCC, 0x88, + 0xE6, 0x83, 0x4F, 0xCC, 0x9B, 0xD8, 0x83, 0x4F, + 0xCC, 0xA3, 0xDC, 0x83, 0x4F, 0xCC, 0xA8, 0xCA, + 0x83, 0x52, 0xCC, 0xA3, 0xDC, 0x83, 0x53, 0xCC, + 0x81, 0xE6, 0x83, 0x53, 0xCC, 0x8C, 0xE6, 0x83, + 0x53, 0xCC, 0xA3, 0xDC, 0x83, 0x55, 0xCC, 0x83, + // Bytes 46c0 - 46ff + 0xE6, 0x83, 0x55, 0xCC, 0x84, 0xE6, 0x83, 0x55, + 0xCC, 0x88, 0xE6, 0x83, 0x55, 0xCC, 0x9B, 0xD8, + 0x83, 0x61, 0xCC, 0x82, 0xE6, 0x83, 0x61, 0xCC, + 0x86, 0xE6, 0x83, 0x61, 0xCC, 0x87, 0xE6, 0x83, + 0x61, 0xCC, 0x88, 0xE6, 0x83, 0x61, 0xCC, 0x8A, + 0xE6, 0x83, 0x61, 0xCC, 0xA3, 0xDC, 0x83, 0x63, + 0xCC, 0xA7, 0xCA, 0x83, 0x65, 0xCC, 0x82, 0xE6, + 0x83, 0x65, 0xCC, 0x84, 0xE6, 0x83, 0x65, 0xCC, + // Bytes 4700 - 473f + 0xA3, 0xDC, 0x83, 0x65, 0xCC, 0xA7, 0xCA, 0x83, + 0x69, 0xCC, 0x88, 0xE6, 0x83, 0x6C, 0xCC, 0xA3, + 0xDC, 0x83, 0x6F, 0xCC, 0x82, 0xE6, 0x83, 0x6F, + 0xCC, 0x83, 0xE6, 0x83, 0x6F, 0xCC, 0x84, 0xE6, + 0x83, 0x6F, 0xCC, 0x87, 0xE6, 0x83, 0x6F, 0xCC, + 0x88, 0xE6, 0x83, 0x6F, 0xCC, 0x9B, 0xD8, 0x83, + 0x6F, 0xCC, 0xA3, 0xDC, 0x83, 0x6F, 0xCC, 0xA8, + 0xCA, 0x83, 0x72, 0xCC, 0xA3, 0xDC, 0x83, 0x73, + // Bytes 4740 - 477f + 0xCC, 0x81, 0xE6, 0x83, 0x73, 0xCC, 0x8C, 0xE6, + 0x83, 0x73, 0xCC, 0xA3, 0xDC, 0x83, 0x75, 0xCC, + 0x83, 0xE6, 0x83, 0x75, 0xCC, 0x84, 0xE6, 0x83, + 0x75, 0xCC, 0x88, 0xE6, 0x83, 0x75, 0xCC, 0x9B, + 0xD8, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xE6, 0x84, + 0xCE, 0x91, 0xCC, 0x94, 0xE6, 0x84, 0xCE, 0x95, + 0xCC, 0x93, 0xE6, 0x84, 0xCE, 0x95, 0xCC, 0x94, + 0xE6, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xE6, 0x84, + // Bytes 4780 - 47bf + 0xCE, 0x97, 0xCC, 0x94, 0xE6, 0x84, 0xCE, 0x99, + 0xCC, 0x93, 0xE6, 0x84, 0xCE, 0x99, 0xCC, 0x94, + 0xE6, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xE6, 0x84, + 0xCE, 0x9F, 0xCC, 0x94, 0xE6, 0x84, 0xCE, 0xA5, + 0xCC, 0x94, 0xE6, 0x84, 0xCE, 0xA9, 0xCC, 0x93, + 0xE6, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xE6, 0x84, + 0xCE, 0xB1, 0xCC, 0x80, 0xE6, 0x84, 0xCE, 0xB1, + 0xCC, 0x81, 0xE6, 0x84, 0xCE, 0xB1, 0xCC, 0x93, + // Bytes 47c0 - 47ff + 0xE6, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xE6, 0x84, + 0xCE, 0xB1, 0xCD, 0x82, 0xE6, 0x84, 0xCE, 0xB5, + 0xCC, 0x93, 0xE6, 0x84, 0xCE, 0xB5, 0xCC, 0x94, + 0xE6, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xE6, 0x84, + 0xCE, 0xB7, 0xCC, 0x81, 0xE6, 0x84, 0xCE, 0xB7, + 0xCC, 0x93, 0xE6, 0x84, 0xCE, 0xB7, 0xCC, 0x94, + 0xE6, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xE6, 0x84, + 0xCE, 0xB9, 0xCC, 0x88, 0xE6, 0x84, 0xCE, 0xB9, + // Bytes 4800 - 483f + 0xCC, 0x93, 0xE6, 0x84, 0xCE, 0xB9, 0xCC, 0x94, + 0xE6, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xE6, 0x84, + 0xCE, 0xBF, 0xCC, 0x94, 0xE6, 0x84, 0xCF, 0x85, + 0xCC, 0x88, 0xE6, 0x84, 0xCF, 0x85, 0xCC, 0x93, + 0xE6, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xE6, 0x84, + 0xCF, 0x89, 0xCC, 0x80, 0xE6, 0x84, 0xCF, 0x89, + 0xCC, 0x81, 0xE6, 0x84, 0xCF, 0x89, 0xCC, 0x93, + 0xE6, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xE6, 0x84, + // Bytes 4840 - 487f + 0xCF, 0x89, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0x91, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0x97, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0x97, + // Bytes 4880 - 48bf + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0x97, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0x97, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0x97, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0x97, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xA9, + // Bytes 48c0 - 48ff + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xA9, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xA9, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xB1, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xB1, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xB1, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xB1, + // Bytes 4900 - 493f + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCE, 0xB7, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x86, 0xCF, 0x89, + 0xCC, 0x93, 0xCC, 0x80, 0xE6, 0x86, 0xCF, 0x89, + // Bytes 4940 - 497f + 0xCC, 0x93, 0xCC, 0x81, 0xE6, 0x86, 0xCF, 0x89, + 0xCC, 0x93, 0xCD, 0x82, 0xE6, 0x86, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x80, 0xE6, 0x86, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCF, 0x89, + 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x42, 0xCC, 0x80, + 0xE6, 0xE6, 0x42, 0xCC, 0x81, 0xE6, 0xE6, 0x42, + 0xCC, 0x93, 0xE6, 0xE6, 0x43, 0xE3, 0x82, 0x99, + 0x08, 0x08, 0x43, 0xE3, 0x82, 0x9A, 0x08, 0x08, + // Bytes 4980 - 49bf + 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0xE6, 0x46, + 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0x82, 0x81, + 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0x84, + 0x81, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, + 0x82, 0x81, } -// nfcDecompValues: 1408 entries, 2816 bytes +// nfcValues: 2944 entries, 5888 bytes // Block 2 is the null block. -var nfcDecompValues = [1408]uint16{ +var nfcValues = [2944]uint16{ // Block 0x0, offset 0x0 + 0x003c: 0x8800, 0x003d: 0x8800, 0x003e: 0x8800, // Block 0x1, offset 0x40 + 0x0041: 0x8800, 0x0042: 0x8800, 0x0043: 0x8800, 0x0044: 0x8800, 0x0045: 0x8800, + 0x0046: 0x8800, 0x0047: 0x8800, 0x0048: 0x8800, 0x0049: 0x8800, 0x004a: 0x8800, 0x004b: 0x8800, + 0x004c: 0x8800, 0x004d: 0x8800, 0x004e: 0x8800, 0x004f: 0x8800, 0x0050: 0x8800, + 0x0052: 0x8800, 0x0053: 0x8800, 0x0054: 0x8800, 0x0055: 0x8800, 0x0056: 0x8800, 0x0057: 0x8800, + 0x0058: 0x8800, 0x0059: 0x8800, 0x005a: 0x8800, + 0x0061: 0x8800, 0x0062: 0x8800, 0x0063: 0x8800, + 0x0064: 0x8800, 0x0065: 0x8800, 0x0066: 0x8800, 0x0067: 0x8800, 0x0068: 0x8800, 0x0069: 0x8800, + 0x006a: 0x8800, 0x006b: 0x8800, 0x006c: 0x8800, 0x006d: 0x8800, 0x006e: 0x8800, 0x006f: 0x8800, + 0x0070: 0x8800, 0x0072: 0x8800, 0x0073: 0x8800, 0x0074: 0x8800, 0x0075: 0x8800, + 0x0076: 0x8800, 0x0077: 0x8800, 0x0078: 0x8800, 0x0079: 0x8800, 0x007a: 0x8800, // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x00cd: 0x02fb, 0x00ce: 0x02ff, 0x00cf: 0x0303, 0x00d0: 0x0307, 0x00d1: 0x030b, - 0x00d2: 0x030f, 0x00d3: 0x0313, 0x00d4: 0x0317, 0x00d5: 0x031b, 0x00d6: 0x0321, 0x00d7: 0x0327, - 0x00d8: 0x032d, 0x00d9: 0x0333, 0x00da: 0x0339, 0x00db: 0x033f, 0x00dc: 0x0345, - 0x00de: 0x034b, 0x00df: 0x0351, 0x00e0: 0x0357, 0x00e1: 0x035d, 0x00e2: 0x0363, 0x00e3: 0x0368, - 0x00e6: 0x036d, 0x00e7: 0x0371, 0x00e8: 0x0375, 0x00e9: 0x0379, - 0x00ea: 0x037d, 0x00eb: 0x0381, 0x00ec: 0x0385, 0x00ed: 0x038b, 0x00ee: 0x0391, 0x00ef: 0x0396, - 0x00f0: 0x039b, 0x00f4: 0x03a8, 0x00f5: 0x03ac, - 0x00f8: 0x03b0, 0x00f9: 0x03b4, 0x00fa: 0x03b8, 0x00fb: 0x03be, - 0x00fc: 0x03c4, 0x00fd: 0x03c9, 0x00fe: 0x03ce, 0x00ff: 0x03d3, + 0x00c0: 0x2e54, 0x00c1: 0x2e59, 0x00c2: 0x463f, 0x00c3: 0x2e5e, 0x00c4: 0x464e, 0x00c5: 0x4653, + 0x00c6: 0x8800, 0x00c7: 0x465d, 0x00c8: 0x2ec7, 0x00c9: 0x2ecc, 0x00ca: 0x4662, 0x00cb: 0x2ee0, + 0x00cc: 0x2f53, 0x00cd: 0x2f58, 0x00ce: 0x2f5d, 0x00cf: 0x4676, 0x00d1: 0x2fe9, + 0x00d2: 0x300c, 0x00d3: 0x3011, 0x00d4: 0x4680, 0x00d5: 0x4685, 0x00d6: 0x4694, + 0x00d8: 0x8800, 0x00d9: 0x3098, 0x00da: 0x309d, 0x00db: 0x30a2, 0x00dc: 0x46c6, 0x00dd: 0x311a, + 0x00e0: 0x3160, 0x00e1: 0x3165, 0x00e2: 0x46d0, 0x00e3: 0x316a, + 0x00e4: 0x46df, 0x00e5: 0x46e4, 0x00e6: 0x8800, 0x00e7: 0x46ee, 0x00e8: 0x31d3, 0x00e9: 0x31d8, + 0x00ea: 0x46f3, 0x00eb: 0x31ec, 0x00ec: 0x3264, 0x00ed: 0x3269, 0x00ee: 0x326e, 0x00ef: 0x4707, + 0x00f1: 0x32fa, 0x00f2: 0x331d, 0x00f3: 0x3322, 0x00f4: 0x4711, 0x00f5: 0x4716, + 0x00f6: 0x4725, 0x00f8: 0x8800, 0x00f9: 0x33ae, 0x00fa: 0x33b3, 0x00fb: 0x33b8, + 0x00fc: 0x4757, 0x00fd: 0x3435, 0x00ff: 0x344e, // Block 0x4, offset 0x100 - 0x0100: 0x0b02, 0x0101: 0x0b06, 0x0102: 0x0b0a, 0x0103: 0x0b0e, 0x0104: 0x0b12, 0x0105: 0x0b16, - 0x0106: 0x0b1a, 0x0107: 0x0b1e, 0x0108: 0x0b22, 0x0109: 0x0b26, 0x010a: 0x0b2a, 0x010b: 0x0b2e, - 0x010c: 0x0b32, 0x010d: 0x0b38, 0x010e: 0x0b3e, 0x010f: 0x0b44, 0x0110: 0x0b4a, 0x0111: 0x0b50, - 0x0112: 0x0b56, 0x0113: 0x0b5c, 0x0114: 0x0b62, 0x0115: 0x0b66, 0x0116: 0x0b6a, 0x0117: 0x0b6e, - 0x0118: 0x0b72, 0x0119: 0x0b76, 0x011a: 0x0b7a, 0x011b: 0x0b7e, 0x011c: 0x0b82, 0x011d: 0x0b88, - 0x011e: 0x0b8e, 0x011f: 0x0b92, 0x0120: 0x0b96, 0x0121: 0x0b9a, 0x0122: 0x0b9e, 0x0123: 0x0ba2, - 0x0124: 0x0ba6, 0x0125: 0x0bac, 0x0126: 0x0bb2, 0x0127: 0x0bb8, 0x0128: 0x0bbe, 0x0129: 0x0bc4, - 0x012a: 0x0bca, 0x012b: 0x0bce, 0x012c: 0x0bd2, 0x012d: 0x0bd6, 0x012e: 0x0bda, 0x012f: 0x0bde, - 0x0130: 0x0be2, 0x0131: 0x0be6, 0x0132: 0x0bea, 0x0133: 0x0bee, 0x0134: 0x0bf2, 0x0135: 0x0bf6, - 0x0136: 0x0bfa, 0x0137: 0x0bfe, 0x0138: 0x0c02, 0x0139: 0x0c08, 0x013a: 0x0c0e, 0x013b: 0x0c14, - 0x013c: 0x0c1a, 0x013d: 0x0c1e, 0x013e: 0x0c22, 0x013f: 0x0c26, + 0x0100: 0x2e63, 0x0101: 0x316f, 0x0102: 0x4644, 0x0103: 0x46d5, 0x0104: 0x2e81, 0x0105: 0x318d, + 0x0106: 0x2e95, 0x0107: 0x31a1, 0x0108: 0x2e9a, 0x0109: 0x31a6, 0x010a: 0x2e9f, 0x010b: 0x31ab, + 0x010c: 0x2ea4, 0x010d: 0x31b0, 0x010e: 0x2eae, 0x010f: 0x31ba, + 0x0112: 0x4667, 0x0113: 0x46f8, 0x0114: 0x2ed6, 0x0115: 0x31e2, 0x0116: 0x2edb, 0x0117: 0x31e7, + 0x0118: 0x2ef9, 0x0119: 0x3205, 0x011a: 0x2eea, 0x011b: 0x31f6, 0x011c: 0x2f12, 0x011d: 0x321e, + 0x011e: 0x2f1c, 0x011f: 0x3228, 0x0120: 0x2f21, 0x0121: 0x322d, 0x0122: 0x2f2b, 0x0123: 0x3237, + 0x0124: 0x2f30, 0x0125: 0x323c, 0x0128: 0x2f62, 0x0129: 0x3273, + 0x012a: 0x2f67, 0x012b: 0x3278, 0x012c: 0x2f6c, 0x012d: 0x327d, 0x012e: 0x2f8f, 0x012f: 0x329b, + 0x0130: 0x2f71, 0x0134: 0x2f99, 0x0135: 0x32a5, + 0x0136: 0x2fad, 0x0137: 0x32be, 0x0139: 0x2fb7, 0x013a: 0x32c8, 0x013b: 0x2fc1, + 0x013c: 0x32d2, 0x013d: 0x2fbc, 0x013e: 0x32cd, // Block 0x5, offset 0x140 - 0x0140: 0x0c2a, 0x0141: 0x0c2e, 0x0142: 0x0c32, 0x0143: 0x0c36, 0x0144: 0x0c3a, 0x0145: 0x0c3e, - 0x0146: 0x0c42, 0x0147: 0x0c46, 0x0148: 0x0c4a, 0x0149: 0x0c4e, 0x014a: 0x0c52, 0x014b: 0x0c56, - 0x014c: 0x0c5a, 0x014d: 0x0c5e, 0x014e: 0x0c62, 0x014f: 0x0c66, 0x0150: 0x0c6a, 0x0151: 0x0c6e, - 0x0152: 0x0c72, 0x0153: 0x0c76, 0x0154: 0x0c7a, 0x0155: 0x0c7e, 0x0156: 0x0c82, 0x0157: 0x0c86, - 0x0158: 0x0c8a, 0x0159: 0x0c8e, 0x015b: 0x0c96, - 0x0160: 0x0c9b, 0x0161: 0x0c9f, 0x0162: 0x0ca3, 0x0163: 0x0ca7, - 0x0164: 0x0cab, 0x0165: 0x0cb1, 0x0166: 0x0cb7, 0x0167: 0x0cbd, 0x0168: 0x0cc3, 0x0169: 0x0cc9, - 0x016a: 0x0ccf, 0x016b: 0x0cd5, 0x016c: 0x0cdb, 0x016d: 0x0ce1, 0x016e: 0x0ce7, 0x016f: 0x0ced, - 0x0170: 0x0cf3, 0x0171: 0x0cf9, 0x0172: 0x0cff, 0x0173: 0x0d05, 0x0174: 0x0d0b, 0x0175: 0x0d11, - 0x0176: 0x0d17, 0x0177: 0x0d1d, 0x0178: 0x0d23, 0x0179: 0x0d27, 0x017a: 0x0d2b, 0x017b: 0x0d2f, - 0x017c: 0x0d33, 0x017d: 0x0d37, 0x017e: 0x0d3b, 0x017f: 0x0d41, + 0x0143: 0x2fe4, 0x0144: 0x32f5, 0x0145: 0x2ffd, + 0x0146: 0x330e, 0x0147: 0x2ff3, 0x0148: 0x3304, + 0x014c: 0x468a, 0x014d: 0x471b, 0x014e: 0x3016, 0x014f: 0x3327, 0x0150: 0x3020, 0x0151: 0x3331, + 0x0154: 0x303e, 0x0155: 0x334f, 0x0156: 0x3057, 0x0157: 0x3368, + 0x0158: 0x3048, 0x0159: 0x3359, 0x015a: 0x46ad, 0x015b: 0x473e, 0x015c: 0x3061, 0x015d: 0x3372, + 0x015e: 0x3070, 0x015f: 0x3381, 0x0160: 0x46b2, 0x0161: 0x4743, 0x0162: 0x3089, 0x0163: 0x339f, + 0x0164: 0x307a, 0x0165: 0x3390, 0x0168: 0x46bc, 0x0169: 0x474d, + 0x016a: 0x46c1, 0x016b: 0x4752, 0x016c: 0x30a7, 0x016d: 0x33bd, 0x016e: 0x30b1, 0x016f: 0x33c7, + 0x0170: 0x30b6, 0x0171: 0x33cc, 0x0172: 0x30d4, 0x0173: 0x33ea, 0x0174: 0x30f7, 0x0175: 0x340d, + 0x0176: 0x311f, 0x0177: 0x343a, 0x0178: 0x3133, 0x0179: 0x3142, 0x017a: 0x3462, 0x017b: 0x314c, + 0x017c: 0x346c, 0x017d: 0x3151, 0x017e: 0x3471, 0x017f: 0x8800, // Block 0x6, offset 0x180 - 0x0180: 0x0d47, 0x0181: 0x0d4d, 0x0182: 0x0d53, 0x0183: 0x0d59, 0x0184: 0x0d5f, 0x0185: 0x0d65, - 0x0186: 0x0d6b, 0x0187: 0x0d71, 0x0188: 0x0d77, 0x0189: 0x0d7b, 0x018a: 0x0d7f, 0x018b: 0x0d83, - 0x018c: 0x0d87, 0x018d: 0x0d8b, 0x018e: 0x0d8f, 0x018f: 0x0d93, 0x0190: 0x0d97, 0x0191: 0x0d9d, - 0x0192: 0x0da3, 0x0193: 0x0da9, 0x0194: 0x0daf, 0x0195: 0x0db5, 0x0196: 0x0dbb, 0x0197: 0x0dc1, - 0x0198: 0x0dc7, 0x0199: 0x0dcd, 0x019a: 0x0dd3, 0x019b: 0x0dd9, 0x019c: 0x0ddf, 0x019d: 0x0de5, - 0x019e: 0x0deb, 0x019f: 0x0df1, 0x01a0: 0x0df7, 0x01a1: 0x0dfd, 0x01a2: 0x0e03, 0x01a3: 0x0e09, - 0x01a4: 0x0e0f, 0x01a5: 0x0e13, 0x01a6: 0x0e17, 0x01a7: 0x0e1b, 0x01a8: 0x0e1f, 0x01a9: 0x0e25, - 0x01aa: 0x0e2b, 0x01ab: 0x0e31, 0x01ac: 0x0e37, 0x01ad: 0x0e3d, 0x01ae: 0x0e43, 0x01af: 0x0e49, - 0x01b0: 0x0e4f, 0x01b1: 0x0e55, 0x01b2: 0x0e5b, 0x01b3: 0x0e5f, 0x01b4: 0x0e63, 0x01b5: 0x0e67, - 0x01b6: 0x0e6b, 0x01b7: 0x0e6f, 0x01b8: 0x0e73, 0x01b9: 0x0e77, + 0x018d: 0x2e6d, 0x018e: 0x3179, 0x018f: 0x2f7b, 0x0190: 0x3287, 0x0191: 0x3025, + 0x0192: 0x3336, 0x0193: 0x30bb, 0x0194: 0x33d1, 0x0195: 0x38b4, 0x0196: 0x3a43, 0x0197: 0x38ad, + 0x0198: 0x3a3c, 0x0199: 0x38bb, 0x019a: 0x3a4a, 0x019b: 0x38a6, 0x019c: 0x3a35, + 0x019e: 0x3795, 0x019f: 0x3924, 0x01a0: 0x378e, 0x01a1: 0x391d, 0x01a2: 0x3498, 0x01a3: 0x34aa, + 0x01a6: 0x2f26, 0x01a7: 0x3232, 0x01a8: 0x2fa3, 0x01a9: 0x32b4, + 0x01aa: 0x46a3, 0x01ab: 0x4734, 0x01ac: 0x3875, 0x01ad: 0x3a04, 0x01ae: 0x34bc, 0x01af: 0x34c2, + 0x01b0: 0x32aa, 0x01b4: 0x2f0d, 0x01b5: 0x3219, + 0x01b8: 0x2fdf, 0x01b9: 0x32f0, 0x01ba: 0x379c, 0x01bb: 0x392b, + 0x01bc: 0x3492, 0x01bd: 0x34a4, 0x01be: 0x349e, 0x01bf: 0x34b0, // Block 0x7, offset 0x1c0 - 0x01c0: 0x0e7b, 0x01c1: 0x0e80, 0x01c2: 0x0e85, 0x01c3: 0x0e8c, 0x01c4: 0x0e93, 0x01c5: 0x0e9a, - 0x01c6: 0x0ea1, 0x01c7: 0x0ea8, 0x01c8: 0x0eaf, 0x01c9: 0x0eb4, 0x01ca: 0x0eb9, 0x01cb: 0x0ec0, - 0x01cc: 0x0ec7, 0x01cd: 0x0ece, 0x01ce: 0x0ed5, 0x01cf: 0x0edc, 0x01d0: 0x0ee3, 0x01d1: 0x0ee8, - 0x01d2: 0x0eed, 0x01d3: 0x0ef4, 0x01d4: 0x0efb, 0x01d5: 0x0f02, - 0x01d8: 0x0f09, 0x01d9: 0x0f0e, 0x01da: 0x0f13, 0x01db: 0x0f1a, 0x01dc: 0x0f21, 0x01dd: 0x0f28, - 0x01e0: 0x0f2f, 0x01e1: 0x0f34, 0x01e2: 0x0f39, 0x01e3: 0x0f40, - 0x01e4: 0x0f47, 0x01e5: 0x0f4e, 0x01e6: 0x0f55, 0x01e7: 0x0f5c, 0x01e8: 0x0f63, 0x01e9: 0x0f68, - 0x01ea: 0x0f6d, 0x01eb: 0x0f74, 0x01ec: 0x0f7b, 0x01ed: 0x0f82, 0x01ee: 0x0f89, 0x01ef: 0x0f90, - 0x01f0: 0x0f97, 0x01f1: 0x0f9c, 0x01f2: 0x0fa1, 0x01f3: 0x0fa8, 0x01f4: 0x0faf, 0x01f5: 0x0fb6, - 0x01f6: 0x0fbd, 0x01f7: 0x0fc4, 0x01f8: 0x0fcb, 0x01f9: 0x0fd0, 0x01fa: 0x0fd5, 0x01fb: 0x0fdc, - 0x01fc: 0x0fe3, 0x01fd: 0x0fea, 0x01fe: 0x0ff1, 0x01ff: 0x0ff8, + 0x01c0: 0x2e72, 0x01c1: 0x317e, 0x01c2: 0x2e77, 0x01c3: 0x3183, 0x01c4: 0x2eef, 0x01c5: 0x31fb, + 0x01c6: 0x2ef4, 0x01c7: 0x3200, 0x01c8: 0x2f80, 0x01c9: 0x328c, 0x01ca: 0x2f85, 0x01cb: 0x3291, + 0x01cc: 0x302a, 0x01cd: 0x333b, 0x01ce: 0x302f, 0x01cf: 0x3340, 0x01d0: 0x304d, 0x01d1: 0x335e, + 0x01d2: 0x3052, 0x01d3: 0x3363, 0x01d4: 0x30c0, 0x01d5: 0x33d6, 0x01d6: 0x30c5, 0x01d7: 0x33db, + 0x01d8: 0x306b, 0x01d9: 0x337c, 0x01da: 0x3084, 0x01db: 0x339a, + 0x01de: 0x2f3f, 0x01df: 0x324b, + 0x01e6: 0x4649, 0x01e7: 0x46da, 0x01e8: 0x4671, 0x01e9: 0x4702, + 0x01ea: 0x3844, 0x01eb: 0x39d3, 0x01ec: 0x3821, 0x01ed: 0x39b0, 0x01ee: 0x468f, 0x01ef: 0x4720, + 0x01f0: 0x383d, 0x01f1: 0x39cc, 0x01f2: 0x3129, 0x01f3: 0x3444, // Block 0x8, offset 0x200 - 0x0200: 0x0fff, 0x0201: 0x1004, 0x0202: 0x1009, 0x0203: 0x1010, 0x0204: 0x1017, 0x0205: 0x101e, - 0x0208: 0x1025, 0x0209: 0x102a, 0x020a: 0x102f, 0x020b: 0x1036, - 0x020c: 0x103d, 0x020d: 0x1044, 0x0210: 0x104b, 0x0211: 0x1050, - 0x0212: 0x1055, 0x0213: 0x105c, 0x0214: 0x1063, 0x0215: 0x106a, 0x0216: 0x1071, 0x0217: 0x1078, - 0x0219: 0x107f, 0x021b: 0x1084, 0x021d: 0x108b, - 0x021f: 0x1092, 0x0220: 0x1099, 0x0221: 0x109e, 0x0222: 0x10a3, 0x0223: 0x10aa, - 0x0224: 0x10b1, 0x0225: 0x10b8, 0x0226: 0x10bf, 0x0227: 0x10c6, 0x0228: 0x10cd, 0x0229: 0x10d2, - 0x022a: 0x10d7, 0x022b: 0x10de, 0x022c: 0x10e5, 0x022d: 0x10ec, 0x022e: 0x10f3, 0x022f: 0x10fa, - 0x0230: 0x1101, 0x0231: 0x0525, 0x0232: 0x1106, 0x0233: 0x052a, 0x0234: 0x110b, 0x0235: 0x052f, - 0x0236: 0x1110, 0x0237: 0x0534, 0x0238: 0x1115, 0x0239: 0x054a, 0x023a: 0x111a, 0x023b: 0x054f, - 0x023c: 0x111f, 0x023d: 0x0554, + 0x0200: 0x86e6, 0x0201: 0x86e6, 0x0202: 0x86e6, 0x0203: 0x86e6, 0x0204: 0x86e6, 0x0205: 0x80e6, + 0x0206: 0x86e6, 0x0207: 0x86e6, 0x0208: 0x86e6, 0x0209: 0x86e6, 0x020a: 0x86e6, 0x020b: 0x86e6, + 0x020c: 0x86e6, 0x020d: 0x80e6, 0x020e: 0x80e6, 0x020f: 0x86e6, 0x0210: 0x80e6, 0x0211: 0x86e6, + 0x0212: 0x80e6, 0x0213: 0x86e6, 0x0214: 0x86e6, 0x0215: 0x80e8, 0x0216: 0x80dc, 0x0217: 0x80dc, + 0x0218: 0x80dc, 0x0219: 0x80dc, 0x021a: 0x80e8, 0x021b: 0x86d8, 0x021c: 0x80dc, 0x021d: 0x80dc, + 0x021e: 0x80dc, 0x021f: 0x80dc, 0x0220: 0x80dc, 0x0221: 0x80ca, 0x0222: 0x80ca, 0x0223: 0x86dc, + 0x0224: 0x86dc, 0x0225: 0x86dc, 0x0226: 0x86dc, 0x0227: 0x86ca, 0x0228: 0x86ca, 0x0229: 0x80dc, + 0x022a: 0x80dc, 0x022b: 0x80dc, 0x022c: 0x80dc, 0x022d: 0x86dc, 0x022e: 0x86dc, 0x022f: 0x80dc, + 0x0230: 0x86dc, 0x0231: 0x86dc, 0x0232: 0x80dc, 0x0233: 0x80dc, 0x0234: 0x8001, 0x0235: 0x8001, + 0x0236: 0x8001, 0x0237: 0x8001, 0x0238: 0x8601, 0x0239: 0x80dc, 0x023a: 0x80dc, 0x023b: 0x80dc, + 0x023c: 0x80dc, 0x023d: 0x80e6, 0x023e: 0x80e6, 0x023f: 0x80e6, // Block 0x9, offset 0x240 - 0x0240: 0x1124, 0x0241: 0x112b, 0x0242: 0x1132, 0x0243: 0x113b, 0x0244: 0x1144, 0x0245: 0x114d, - 0x0246: 0x1156, 0x0247: 0x115f, 0x0248: 0x1168, 0x0249: 0x116f, 0x024a: 0x1176, 0x024b: 0x117f, - 0x024c: 0x1188, 0x024d: 0x1191, 0x024e: 0x119a, 0x024f: 0x11a3, 0x0250: 0x11ac, 0x0251: 0x11b3, - 0x0252: 0x11ba, 0x0253: 0x11c3, 0x0254: 0x11cc, 0x0255: 0x11d5, 0x0256: 0x11de, 0x0257: 0x11e7, - 0x0258: 0x11f0, 0x0259: 0x11f7, 0x025a: 0x11fe, 0x025b: 0x1207, 0x025c: 0x1210, 0x025d: 0x1219, - 0x025e: 0x1222, 0x025f: 0x122b, 0x0260: 0x1234, 0x0261: 0x123b, 0x0262: 0x1242, 0x0263: 0x124b, - 0x0264: 0x1254, 0x0265: 0x125d, 0x0266: 0x1266, 0x0267: 0x126f, 0x0268: 0x1278, 0x0269: 0x127f, - 0x026a: 0x1286, 0x026b: 0x128f, 0x026c: 0x1298, 0x026d: 0x12a1, 0x026e: 0x12aa, 0x026f: 0x12b3, - 0x0270: 0x12bc, 0x0271: 0x12c1, 0x0272: 0x12c6, 0x0273: 0x12cd, 0x0274: 0x12d2, - 0x0276: 0x12d9, 0x0277: 0x12de, 0x0278: 0x12e5, 0x0279: 0x12ea, 0x027a: 0x12ef, 0x027b: 0x04ee, - 0x027c: 0x12f4, 0x027e: 0x12fd, + 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4980, 0x0245: 0x86f0, + 0x0246: 0x80e6, 0x0247: 0x80dc, 0x0248: 0x80dc, 0x0249: 0x80dc, 0x024a: 0x80e6, 0x024b: 0x80e6, + 0x024c: 0x80e6, 0x024d: 0x80dc, 0x024e: 0x80dc, 0x0250: 0x80e6, 0x0251: 0x80e6, + 0x0252: 0x80e6, 0x0253: 0x80dc, 0x0254: 0x80dc, 0x0255: 0x80dc, 0x0256: 0x80dc, 0x0257: 0x80e6, + 0x0258: 0x80e8, 0x0259: 0x80dc, 0x025a: 0x80dc, 0x025b: 0x80e6, 0x025c: 0x80e9, 0x025d: 0x80ea, + 0x025e: 0x80ea, 0x025f: 0x80e9, 0x0260: 0x80ea, 0x0261: 0x80ea, 0x0262: 0x80e9, 0x0263: 0x80e6, + 0x0264: 0x80e6, 0x0265: 0x80e6, 0x0266: 0x80e6, 0x0267: 0x80e6, 0x0268: 0x80e6, 0x0269: 0x80e6, + 0x026a: 0x80e6, 0x026b: 0x80e6, 0x026c: 0x80e6, 0x026d: 0x80e6, 0x026e: 0x80e6, 0x026f: 0x80e6, + 0x0274: 0x042d, + 0x027e: 0x0105, // Block 0xa, offset 0x280 - 0x0281: 0x1304, 0x0282: 0x130f, 0x0283: 0x1316, 0x0284: 0x131b, - 0x0286: 0x1322, 0x0287: 0x1327, 0x0288: 0x132e, 0x0289: 0x04f6, 0x028a: 0x1333, 0x028b: 0x04fb, - 0x028c: 0x1338, 0x028d: 0x133d, 0x028e: 0x1349, 0x028f: 0x1355, 0x0290: 0x1361, 0x0291: 0x1366, - 0x0292: 0x136b, 0x0293: 0x0514, 0x0296: 0x1372, 0x0297: 0x1377, - 0x0298: 0x137e, 0x0299: 0x1383, 0x029a: 0x1388, 0x029b: 0x0500, 0x029d: 0x138d, - 0x029e: 0x1399, 0x029f: 0x13a5, 0x02a0: 0x13b1, 0x02a1: 0x13b6, 0x02a2: 0x13bb, 0x02a3: 0x0539, - 0x02a4: 0x13c2, 0x02a5: 0x13c7, 0x02a6: 0x13cc, 0x02a7: 0x13d1, 0x02a8: 0x13d8, 0x02a9: 0x13dd, - 0x02aa: 0x13e2, 0x02ab: 0x050a, 0x02ac: 0x13e7, 0x02ad: 0x13ec, 0x02ae: 0x04e3, 0x02af: 0x13f7, - 0x02b2: 0x13f9, 0x02b3: 0x1400, 0x02b4: 0x1405, - 0x02b6: 0x140c, 0x02b7: 0x1411, 0x02b8: 0x1418, 0x02b9: 0x0505, 0x02ba: 0x141d, 0x02bb: 0x050f, - 0x02bc: 0x1422, 0x02bd: 0x1427, + 0x0285: 0x3486, + 0x0286: 0x34ce, 0x0287: 0x0394, 0x0288: 0x34ec, 0x0289: 0x34f8, 0x028a: 0x350a, + 0x028c: 0x3528, 0x028e: 0x353a, 0x028f: 0x3558, 0x0290: 0x3ced, 0x0291: 0x8800, + 0x0295: 0x8800, 0x0297: 0x8800, + 0x0299: 0x8800, + 0x029f: 0x8800, 0x02a1: 0x8800, + 0x02a5: 0x8800, 0x02a9: 0x8800, + 0x02aa: 0x351c, 0x02ab: 0x354c, 0x02ac: 0x47b5, 0x02ad: 0x357c, 0x02ae: 0x47df, 0x02af: 0x358e, + 0x02b0: 0x3d55, 0x02b1: 0x8800, 0x02b5: 0x8800, + 0x02b7: 0x8800, 0x02b9: 0x8800, + 0x02bf: 0x8800, // Block 0xb, offset 0x2c0 - 0x02cc: 0x1b8a, 0x02ce: 0x1b91, 0x02d0: 0x1b98, - 0x02d2: 0x1b9f, 0x02d4: 0x1ba6, 0x02d6: 0x1bad, - 0x02d8: 0x1bb4, 0x02da: 0x1bbb, 0x02dc: 0x1bc2, - 0x02de: 0x1bc9, 0x02e0: 0x1bd0, 0x02e2: 0x1bd7, - 0x02e5: 0x1bde, 0x02e7: 0x1be5, 0x02e9: 0x1bec, - 0x02f0: 0x1bf3, 0x02f1: 0x1bfa, 0x02f3: 0x1c01, 0x02f4: 0x1c08, - 0x02f6: 0x1c0f, 0x02f7: 0x1c16, 0x02f9: 0x1c1d, 0x02fa: 0x1c24, - 0x02fc: 0x1c2b, 0x02fd: 0x1c32, + 0x02c0: 0x3606, 0x02c1: 0x3612, 0x02c3: 0x3600, + 0x02c6: 0x8800, 0x02c7: 0x35ee, + 0x02cc: 0x3642, 0x02cd: 0x362a, 0x02ce: 0x3654, 0x02d0: 0x8800, + 0x02d3: 0x8800, 0x02d5: 0x8800, 0x02d6: 0x8800, 0x02d7: 0x8800, + 0x02d8: 0x8800, 0x02d9: 0x3636, 0x02da: 0x8800, + 0x02de: 0x8800, 0x02e3: 0x8800, + 0x02e7: 0x8800, + 0x02eb: 0x8800, 0x02ed: 0x8800, + 0x02f0: 0x8800, 0x02f3: 0x8800, 0x02f5: 0x8800, + 0x02f6: 0x8800, 0x02f7: 0x8800, 0x02f8: 0x8800, 0x02f9: 0x36ba, 0x02fa: 0x8800, + 0x02fe: 0x8800, // Block 0xc, offset 0x300 - 0x0300: 0x2fce, 0x0301: 0x2fd2, 0x0302: 0x2fd6, 0x0303: 0x2fda, 0x0304: 0x2fde, 0x0305: 0x2fe2, - 0x0306: 0x2fe6, 0x0307: 0x2fea, 0x0308: 0x2fee, 0x0309: 0x2eed, 0x030a: 0x2ff2, 0x030b: 0x2ef1, - 0x030c: 0x2ff6, 0x030d: 0x2ffa, 0x030e: 0x2ffe, 0x030f: 0x3002, 0x0310: 0x3006, 0x0311: 0x2e6d, - 0x0312: 0x2b15, 0x0313: 0x300a, 0x0314: 0x300e, 0x0315: 0x195a, 0x0316: 0x2c25, 0x0317: 0x2d71, - 0x0318: 0x3012, 0x0319: 0x3016, 0x031a: 0x2f0d, 0x031b: 0x301a, 0x031c: 0x2f11, 0x031d: 0x301e, - 0x031e: 0x3022, 0x031f: 0x3026, 0x0320: 0x2e75, 0x0321: 0x302a, 0x0322: 0x302e, 0x0323: 0x3032, - 0x0324: 0x3036, 0x0325: 0x303a, 0x0326: 0x2e79, 0x0327: 0x303e, 0x0328: 0x3042, 0x0329: 0x3046, - 0x032a: 0x304a, 0x032b: 0x304e, 0x032c: 0x3052, 0x032d: 0x2f41, 0x032e: 0x3056, 0x032f: 0x305a, - 0x0330: 0x2cb1, 0x0331: 0x305e, 0x0332: 0x2f51, 0x0333: 0x3062, 0x0334: 0x3066, 0x0335: 0x306a, - 0x0336: 0x306e, 0x0337: 0x3072, 0x0338: 0x2f65, 0x0339: 0x3076, 0x033a: 0x2e99, 0x033b: 0x307a, - 0x033c: 0x2f69, 0x033d: 0x2bd9, 0x033e: 0x307e, 0x033f: 0x2f6d, + 0x0301: 0x3618, 0x0302: 0x369c, + 0x0310: 0x35f4, 0x0311: 0x3678, + 0x0312: 0x35fa, 0x0313: 0x367e, 0x0316: 0x360c, 0x0317: 0x3690, + 0x0318: 0x8800, 0x0319: 0x8800, 0x031a: 0x370e, 0x031b: 0x3714, 0x031c: 0x361e, 0x031d: 0x36a2, + 0x031e: 0x3624, 0x031f: 0x36a8, 0x0322: 0x3630, 0x0323: 0x36b4, + 0x0324: 0x363c, 0x0325: 0x36c0, 0x0326: 0x3648, 0x0327: 0x36cc, 0x0328: 0x8800, 0x0329: 0x8800, + 0x032a: 0x371a, 0x032b: 0x3720, 0x032c: 0x3672, 0x032d: 0x36f6, 0x032e: 0x364e, 0x032f: 0x36d2, + 0x0330: 0x365a, 0x0331: 0x36de, 0x0332: 0x3660, 0x0333: 0x36e4, 0x0334: 0x3666, 0x0335: 0x36ea, + 0x0338: 0x366c, 0x0339: 0x36f0, // Block 0xd, offset 0x340 - 0x0340: 0x3082, 0x0341: 0x2f75, 0x0342: 0x3086, 0x0343: 0x308a, 0x0344: 0x308e, 0x0345: 0x3092, - 0x0346: 0x3096, 0x0347: 0x2f7d, 0x0348: 0x2e8d, 0x0349: 0x309a, 0x034a: 0x2f81, 0x034b: 0x309e, - 0x034c: 0x2f85, 0x034d: 0x30a2, 0x034e: 0x1b76, 0x034f: 0x30a6, 0x0350: 0x30ab, 0x0351: 0x30b0, - 0x0352: 0x30b5, 0x0353: 0x30b9, 0x0354: 0x30bd, 0x0355: 0x30c1, 0x0356: 0x30c6, 0x0357: 0x30cb, - 0x0358: 0x30d0, 0x0359: 0x30d4, + 0x0351: 0x80dc, + 0x0352: 0x80e6, 0x0353: 0x80e6, 0x0354: 0x80e6, 0x0355: 0x80e6, 0x0356: 0x80dc, 0x0357: 0x80e6, + 0x0358: 0x80e6, 0x0359: 0x80e6, 0x035a: 0x80de, 0x035b: 0x80dc, 0x035c: 0x80e6, 0x035d: 0x80e6, + 0x035e: 0x80e6, 0x035f: 0x80e6, 0x0360: 0x80e6, 0x0361: 0x80e6, 0x0362: 0x80dc, 0x0363: 0x80dc, + 0x0364: 0x80dc, 0x0365: 0x80dc, 0x0366: 0x80dc, 0x0367: 0x80dc, 0x0368: 0x80e6, 0x0369: 0x80e6, + 0x036a: 0x80dc, 0x036b: 0x80e6, 0x036c: 0x80e6, 0x036d: 0x80de, 0x036e: 0x80e4, 0x036f: 0x80e6, + 0x0370: 0x800a, 0x0371: 0x800b, 0x0372: 0x800c, 0x0373: 0x800d, 0x0374: 0x800e, 0x0375: 0x800f, + 0x0376: 0x8010, 0x0377: 0x8011, 0x0378: 0x8012, 0x0379: 0x8013, 0x037a: 0x8013, 0x037b: 0x8014, + 0x037c: 0x8015, 0x037d: 0x8016, 0x037f: 0x8017, // Block 0xe, offset 0x380 - 0x0380: 0x3d23, 0x0381: 0x3d27, 0x0382: 0x3d2b, 0x0383: 0x3d2f, 0x0384: 0x3d34, 0x0385: 0x2eb5, - 0x0386: 0x3d38, 0x0387: 0x3d3c, 0x0388: 0x3d40, 0x0389: 0x3d44, 0x038a: 0x2eb9, 0x038b: 0x3d48, - 0x038c: 0x3d4c, 0x038d: 0x3d50, 0x038e: 0x2ebd, 0x038f: 0x3d55, 0x0390: 0x3d59, 0x0391: 0x3d5d, - 0x0392: 0x3d61, 0x0393: 0x3d66, 0x0394: 0x3d6a, 0x0395: 0x3c71, 0x0396: 0x3d6e, 0x0397: 0x3d73, - 0x0398: 0x3d77, 0x0399: 0x3d7b, 0x039a: 0x3d7f, 0x039b: 0x2f9a, 0x039c: 0x3d83, 0x039d: 0x1866, - 0x039e: 0x3d88, 0x039f: 0x3d8c, 0x03a0: 0x3d90, 0x03a1: 0x3d94, 0x03a2: 0x3cb9, 0x03a3: 0x3d98, - 0x03a4: 0x3d9c, 0x03a5: 0x2fae, 0x03a6: 0x2ec1, 0x03a7: 0x2ec5, 0x03a8: 0x2fb2, 0x03a9: 0x3da0, - 0x03aa: 0x3da4, 0x03ab: 0x2bf1, 0x03ac: 0x3da8, 0x03ad: 0x2ec9, 0x03ae: 0x3dac, 0x03af: 0x3db0, - 0x03b0: 0x3db4, 0x03b1: 0x3db8, 0x03b2: 0x3db8, 0x03b3: 0x3db8, 0x03b4: 0x3dbc, 0x03b5: 0x3dc1, - 0x03b6: 0x3dc5, 0x03b7: 0x3dc9, 0x03b8: 0x3dcd, 0x03b9: 0x3dd2, 0x03ba: 0x3dd6, 0x03bb: 0x3dda, - 0x03bc: 0x3dde, 0x03bd: 0x3de2, 0x03be: 0x3de6, 0x03bf: 0x3dea, + 0x0388: 0x8800, 0x038a: 0x8800, 0x038b: 0x801b, + 0x038c: 0x801c, 0x038d: 0x801d, 0x038e: 0x801e, 0x038f: 0x801f, 0x0390: 0x8020, 0x0391: 0x8021, + 0x0392: 0x8022, 0x0393: 0x86e6, 0x0394: 0x86e6, 0x0395: 0x86dc, 0x0396: 0x80dc, 0x0397: 0x80e6, + 0x0398: 0x80e6, 0x0399: 0x80e6, 0x039a: 0x80e6, 0x039b: 0x80e6, 0x039c: 0x80dc, 0x039d: 0x80e6, + 0x039e: 0x80e6, 0x039f: 0x80dc, + 0x03b0: 0x8023, // Block 0xf, offset 0x3c0 - 0x03c0: 0x3dee, 0x03c1: 0x3df2, 0x03c2: 0x3df6, 0x03c3: 0x3dfa, 0x03c4: 0x3dfe, 0x03c5: 0x3e02, - 0x03c6: 0x3e02, 0x03c7: 0x2fba, 0x03c8: 0x3e06, 0x03c9: 0x3e0a, 0x03ca: 0x3e0e, 0x03cb: 0x3e12, - 0x03cc: 0x2ed1, 0x03cd: 0x3e16, 0x03ce: 0x3e1a, 0x03cf: 0x3e1e, 0x03d0: 0x2e39, 0x03d1: 0x3e22, - 0x03d2: 0x3e26, 0x03d3: 0x3e2a, 0x03d4: 0x3e2e, 0x03d5: 0x3e32, 0x03d6: 0x3e36, 0x03d7: 0x3e3a, - 0x03d8: 0x3e3e, 0x03d9: 0x3e42, 0x03da: 0x3e47, 0x03db: 0x3e4b, 0x03dc: 0x3e4f, 0x03dd: 0x3c55, - 0x03de: 0x3e53, 0x03df: 0x3e57, 0x03e0: 0x3e5b, 0x03e1: 0x3e60, 0x03e2: 0x3e65, 0x03e3: 0x3e69, - 0x03e4: 0x3e6d, 0x03e5: 0x3e71, 0x03e6: 0x3e75, 0x03e7: 0x3e79, 0x03e8: 0x3e7d, 0x03e9: 0x3e81, - 0x03ea: 0x3e85, 0x03eb: 0x3e85, 0x03ec: 0x3e89, 0x03ed: 0x3e8e, 0x03ee: 0x3e92, 0x03ef: 0x2be1, - 0x03f0: 0x3e96, 0x03f1: 0x3e9a, 0x03f2: 0x3e9f, 0x03f3: 0x3ea3, 0x03f4: 0x3ea7, 0x03f5: 0x18ce, - 0x03f6: 0x3eab, 0x03f7: 0x3eaf, 0x03f8: 0x18d6, 0x03f9: 0x3eb3, 0x03fa: 0x3eb7, 0x03fb: 0x3ebb, - 0x03fc: 0x3ec0, 0x03fd: 0x3ec4, 0x03fe: 0x3ec9, 0x03ff: 0x3ecd, + 0x03c5: 0x8800, + 0x03c6: 0x0078, 0x03c7: 0x8800, 0x03c8: 0x007f, 0x03c9: 0x8800, 0x03ca: 0x0086, 0x03cb: 0x8800, + 0x03cc: 0x008d, 0x03cd: 0x8800, 0x03ce: 0x0094, 0x03d1: 0x8800, + 0x03d2: 0x009b, + 0x03f4: 0x8007, 0x03f5: 0x8600, + 0x03fa: 0x8800, 0x03fb: 0x00a2, + 0x03fc: 0x8800, 0x03fd: 0x00a9, 0x03fe: 0x8800, 0x03ff: 0x8800, // Block 0x10, offset 0x400 - 0x0400: 0x3ed1, 0x0401: 0x3ed5, 0x0402: 0x3ed9, 0x0403: 0x3edd, 0x0404: 0x3ee1, 0x0405: 0x3ee5, - 0x0406: 0x3ee9, 0x0407: 0x3eed, 0x0408: 0x3ef1, 0x0409: 0x3ef5, 0x040a: 0x3efa, 0x040b: 0x3efe, - 0x040c: 0x3f02, 0x040d: 0x3f06, 0x040e: 0x2b11, 0x040f: 0x3f0a, 0x0410: 0x18fe, 0x0411: 0x3f0f, - 0x0412: 0x3f0f, 0x0413: 0x3f14, 0x0414: 0x3f18, 0x0415: 0x3f18, 0x0416: 0x3f1c, 0x0417: 0x3f20, - 0x0418: 0x3f25, 0x0419: 0x3f2a, 0x041a: 0x3f2e, 0x041b: 0x3f32, 0x041c: 0x3f36, 0x041d: 0x3f3a, - 0x041e: 0x3f3e, 0x041f: 0x3f42, 0x0420: 0x3f46, 0x0421: 0x3f4a, 0x0422: 0x3f4e, 0x0423: 0x2ee5, - 0x0424: 0x3f52, 0x0425: 0x3f57, 0x0426: 0x3f5b, 0x0427: 0x3f5f, 0x0428: 0x2fea, 0x0429: 0x3f5f, - 0x042a: 0x3f63, 0x042b: 0x2eed, 0x042c: 0x3f67, 0x042d: 0x3f6b, 0x042e: 0x3f6f, 0x042f: 0x3f73, - 0x0430: 0x2ef1, 0x0431: 0x2aa5, 0x0432: 0x3f77, 0x0433: 0x3f7b, 0x0434: 0x3f7f, 0x0435: 0x3f83, - 0x0436: 0x3f87, 0x0437: 0x3f8b, 0x0438: 0x3f8f, 0x0439: 0x3f94, 0x043a: 0x3f98, 0x043b: 0x3f9c, - 0x043c: 0x3fa0, 0x043d: 0x3fa4, 0x043e: 0x3fa8, 0x043f: 0x3fad, + 0x0400: 0x2e7c, 0x0401: 0x3188, 0x0402: 0x2e86, 0x0403: 0x3192, 0x0404: 0x2e8b, 0x0405: 0x3197, + 0x0406: 0x2e90, 0x0407: 0x319c, 0x0408: 0x37b1, 0x0409: 0x3940, 0x040a: 0x2ea9, 0x040b: 0x31b5, + 0x040c: 0x2eb3, 0x040d: 0x31bf, 0x040e: 0x2ec2, 0x040f: 0x31ce, 0x0410: 0x2eb8, 0x0411: 0x31c4, + 0x0412: 0x2ebd, 0x0413: 0x31c9, 0x0414: 0x37d4, 0x0415: 0x3963, 0x0416: 0x37db, 0x0417: 0x396a, + 0x0418: 0x2efe, 0x0419: 0x320a, 0x041a: 0x2f03, 0x041b: 0x320f, 0x041c: 0x37e9, 0x041d: 0x3978, + 0x041e: 0x2f08, 0x041f: 0x3214, 0x0420: 0x2f17, 0x0421: 0x3223, 0x0422: 0x2f35, 0x0423: 0x3241, + 0x0424: 0x2f44, 0x0425: 0x3250, 0x0426: 0x2f3a, 0x0427: 0x3246, 0x0428: 0x2f49, 0x0429: 0x3255, + 0x042a: 0x2f4e, 0x042b: 0x325a, 0x042c: 0x2f94, 0x042d: 0x32a0, 0x042e: 0x37f0, 0x042f: 0x397f, + 0x0430: 0x2f9e, 0x0431: 0x32af, 0x0432: 0x2fa8, 0x0433: 0x32b9, 0x0434: 0x2fb2, 0x0435: 0x32c3, + 0x0436: 0x467b, 0x0437: 0x470c, 0x0438: 0x37f7, 0x0439: 0x3986, 0x043a: 0x2fcb, 0x043b: 0x32dc, + 0x043c: 0x2fc6, 0x043d: 0x32d7, 0x043e: 0x2fd0, 0x043f: 0x32e1, // Block 0x11, offset 0x440 - 0x0440: 0x3fb1, 0x0441: 0x3fb5, 0x0442: 0x3fb9, 0x0443: 0x3fbd, 0x0444: 0x3fc1, 0x0445: 0x3fc5, - 0x0446: 0x3fc9, 0x0447: 0x3fcd, 0x0448: 0x2ef5, 0x0449: 0x3fd1, 0x044a: 0x3fd5, 0x044b: 0x3fda, - 0x044c: 0x3fde, 0x044d: 0x3fe2, 0x044e: 0x3fe6, 0x044f: 0x2efd, 0x0450: 0x3fea, 0x0451: 0x3fee, - 0x0452: 0x3ff2, 0x0453: 0x3ff6, 0x0454: 0x3ffa, 0x0455: 0x3ffe, 0x0456: 0x4002, 0x0457: 0x4006, - 0x0458: 0x2b15, 0x0459: 0x300a, 0x045a: 0x400a, 0x045b: 0x400e, 0x045c: 0x4012, 0x045d: 0x4016, - 0x045e: 0x401b, 0x045f: 0x401f, 0x0460: 0x4023, 0x0461: 0x4027, 0x0462: 0x2f01, 0x0463: 0x402b, - 0x0464: 0x4030, 0x0465: 0x4034, 0x0466: 0x4038, 0x0467: 0x30b5, 0x0468: 0x403c, 0x0469: 0x4040, - 0x046a: 0x4044, 0x046b: 0x4048, 0x046c: 0x404c, 0x046d: 0x4051, 0x046e: 0x4055, 0x046f: 0x4059, - 0x0470: 0x405d, 0x0471: 0x4062, 0x0472: 0x4066, 0x0473: 0x406a, 0x0474: 0x406e, 0x0475: 0x2c25, - 0x0476: 0x4072, 0x0477: 0x4076, 0x0478: 0x407b, 0x0479: 0x4080, 0x047a: 0x4085, 0x047b: 0x4089, - 0x047c: 0x408e, 0x047d: 0x4092, 0x047e: 0x4096, 0x047f: 0x409a, + 0x0440: 0x2fd5, 0x0441: 0x32e6, 0x0442: 0x2fda, 0x0443: 0x32eb, 0x0444: 0x2fee, 0x0445: 0x32ff, + 0x0446: 0x2ff8, 0x0447: 0x3309, 0x0448: 0x3007, 0x0449: 0x3318, 0x044a: 0x3002, 0x044b: 0x3313, + 0x044c: 0x381a, 0x044d: 0x39a9, 0x044e: 0x3828, 0x044f: 0x39b7, 0x0450: 0x382f, 0x0451: 0x39be, + 0x0452: 0x3836, 0x0453: 0x39c5, 0x0454: 0x3034, 0x0455: 0x3345, 0x0456: 0x3039, 0x0457: 0x334a, + 0x0458: 0x3043, 0x0459: 0x3354, 0x045a: 0x46a8, 0x045b: 0x4739, 0x045c: 0x387c, 0x045d: 0x3a0b, + 0x045e: 0x305c, 0x045f: 0x336d, 0x0460: 0x3066, 0x0461: 0x3377, 0x0462: 0x46b7, 0x0463: 0x4748, + 0x0464: 0x3883, 0x0465: 0x3a12, 0x0466: 0x388a, 0x0467: 0x3a19, 0x0468: 0x3891, 0x0469: 0x3a20, + 0x046a: 0x3075, 0x046b: 0x3386, 0x046c: 0x307f, 0x046d: 0x3395, 0x046e: 0x3093, 0x046f: 0x33a9, + 0x0470: 0x308e, 0x0471: 0x33a4, 0x0472: 0x30cf, 0x0473: 0x33e5, 0x0474: 0x30de, 0x0475: 0x33f4, + 0x0476: 0x30d9, 0x0477: 0x33ef, 0x0478: 0x3898, 0x0479: 0x3a27, 0x047a: 0x389f, 0x047b: 0x3a2e, + 0x047c: 0x30e3, 0x047d: 0x33f9, 0x047e: 0x30e8, 0x047f: 0x33fe, // Block 0x12, offset 0x480 - 0x0480: 0x409e, 0x0481: 0x2f05, 0x0482: 0x2d71, 0x0483: 0x40a2, 0x0484: 0x40a6, 0x0485: 0x40aa, - 0x0486: 0x40ae, 0x0487: 0x40b3, 0x0488: 0x40b7, 0x0489: 0x40bb, 0x048a: 0x40bf, 0x048b: 0x3016, - 0x048c: 0x40c3, 0x048d: 0x40c7, 0x048e: 0x40cc, 0x048f: 0x40d0, 0x0490: 0x40d4, 0x0491: 0x40d9, - 0x0492: 0x40de, 0x0493: 0x40e2, 0x0494: 0x301a, 0x0495: 0x40e6, 0x0496: 0x40ea, 0x0497: 0x40ee, - 0x0498: 0x40f2, 0x0499: 0x40f6, 0x049a: 0x40fa, 0x049b: 0x40fe, 0x049c: 0x4103, 0x049d: 0x4107, - 0x049e: 0x410c, 0x049f: 0x4110, 0x04a0: 0x4115, 0x04a1: 0x3022, 0x04a2: 0x4119, 0x04a3: 0x411d, - 0x04a4: 0x4122, 0x04a5: 0x4126, 0x04a6: 0x412a, 0x04a7: 0x412f, 0x04a8: 0x4134, 0x04a9: 0x4138, - 0x04aa: 0x413c, 0x04ab: 0x4140, 0x04ac: 0x4144, 0x04ad: 0x4144, 0x04ae: 0x4148, 0x04af: 0x414c, - 0x04b0: 0x302a, 0x04b1: 0x4150, 0x04b2: 0x4154, 0x04b3: 0x4158, 0x04b4: 0x415c, 0x04b5: 0x4160, - 0x04b6: 0x4165, 0x04b7: 0x4169, 0x04b8: 0x2bed, 0x04b9: 0x416e, 0x04ba: 0x4173, 0x04bb: 0x4177, - 0x04bc: 0x417c, 0x04bd: 0x4181, 0x04be: 0x4186, 0x04bf: 0x418a, + 0x0480: 0x30ed, 0x0481: 0x3403, 0x0482: 0x30f2, 0x0483: 0x3408, 0x0484: 0x3101, 0x0485: 0x3417, + 0x0486: 0x30fc, 0x0487: 0x3412, 0x0488: 0x3106, 0x0489: 0x3421, 0x048a: 0x310b, 0x048b: 0x3426, + 0x048c: 0x3110, 0x048d: 0x342b, 0x048e: 0x312e, 0x048f: 0x3449, 0x0490: 0x3147, 0x0491: 0x3467, + 0x0492: 0x3156, 0x0493: 0x3476, 0x0494: 0x315b, 0x0495: 0x347b, 0x0496: 0x325f, 0x0497: 0x338b, + 0x0498: 0x341c, 0x0499: 0x3458, 0x049b: 0x34b6, + 0x04a0: 0x4658, 0x04a1: 0x46e9, 0x04a2: 0x2e68, 0x04a3: 0x3174, + 0x04a4: 0x375d, 0x04a5: 0x38ec, 0x04a6: 0x3756, 0x04a7: 0x38e5, 0x04a8: 0x376b, 0x04a9: 0x38fa, + 0x04aa: 0x3764, 0x04ab: 0x38f3, 0x04ac: 0x37a3, 0x04ad: 0x3932, 0x04ae: 0x3779, 0x04af: 0x3908, + 0x04b0: 0x3772, 0x04b1: 0x3901, 0x04b2: 0x3787, 0x04b3: 0x3916, 0x04b4: 0x3780, 0x04b5: 0x390f, + 0x04b6: 0x37aa, 0x04b7: 0x3939, 0x04b8: 0x466c, 0x04b9: 0x46fd, 0x04ba: 0x2ee5, 0x04bb: 0x31f1, + 0x04bc: 0x2ed1, 0x04bd: 0x31dd, 0x04be: 0x37bf, 0x04bf: 0x394e, // Block 0x13, offset 0x4c0 - 0x04c0: 0x3042, 0x04c1: 0x418e, 0x04c2: 0x4193, 0x04c3: 0x4198, 0x04c4: 0x419d, 0x04c5: 0x41a2, - 0x04c6: 0x41a6, 0x04c7: 0x41a6, 0x04c8: 0x3046, 0x04c9: 0x30bd, 0x04ca: 0x41aa, 0x04cb: 0x41ae, - 0x04cc: 0x41b2, 0x04cd: 0x41b6, 0x04ce: 0x41bb, 0x04cf: 0x2b59, 0x04d0: 0x304e, 0x04d1: 0x41bf, - 0x04d2: 0x41c3, 0x04d3: 0x2f2d, 0x04d4: 0x41c8, 0x04d5: 0x41cd, 0x04d6: 0x2e89, 0x04d7: 0x41d2, - 0x04d8: 0x41d6, 0x04d9: 0x2f39, 0x04da: 0x41da, 0x04db: 0x41de, 0x04dc: 0x41e2, 0x04dd: 0x41e7, - 0x04de: 0x41e7, 0x04df: 0x41ec, 0x04e0: 0x41f0, 0x04e1: 0x41f4, 0x04e2: 0x41f9, 0x04e3: 0x41fd, - 0x04e4: 0x4201, 0x04e5: 0x4205, 0x04e6: 0x420a, 0x04e7: 0x420e, 0x04e8: 0x4212, 0x04e9: 0x4216, - 0x04ea: 0x421a, 0x04eb: 0x421e, 0x04ec: 0x4223, 0x04ed: 0x4227, 0x04ee: 0x422b, 0x04ef: 0x422f, - 0x04f0: 0x4233, 0x04f1: 0x4237, 0x04f2: 0x423b, 0x04f3: 0x4240, 0x04f4: 0x4245, 0x04f5: 0x4249, - 0x04f6: 0x424e, 0x04f7: 0x4252, 0x04f8: 0x4257, 0x04f9: 0x425b, 0x04fa: 0x2f51, 0x04fb: 0x425f, - 0x04fc: 0x4264, 0x04fd: 0x4269, 0x04fe: 0x426d, 0x04ff: 0x4272, + 0x04c0: 0x37b8, 0x04c1: 0x3947, 0x04c2: 0x37cd, 0x04c3: 0x395c, 0x04c4: 0x37c6, 0x04c5: 0x3955, + 0x04c6: 0x37e2, 0x04c7: 0x3971, 0x04c8: 0x2f76, 0x04c9: 0x3282, 0x04ca: 0x2f8a, 0x04cb: 0x3296, + 0x04cc: 0x469e, 0x04cd: 0x472f, 0x04ce: 0x301b, 0x04cf: 0x332c, 0x04d0: 0x3805, 0x04d1: 0x3994, + 0x04d2: 0x37fe, 0x04d3: 0x398d, 0x04d4: 0x3813, 0x04d5: 0x39a2, 0x04d6: 0x380c, 0x04d7: 0x399b, + 0x04d8: 0x386e, 0x04d9: 0x39fd, 0x04da: 0x3852, 0x04db: 0x39e1, 0x04dc: 0x384b, 0x04dd: 0x39da, + 0x04de: 0x3860, 0x04df: 0x39ef, 0x04e0: 0x3859, 0x04e1: 0x39e8, 0x04e2: 0x3867, 0x04e3: 0x39f6, + 0x04e4: 0x30ca, 0x04e5: 0x33e0, 0x04e6: 0x30ac, 0x04e7: 0x33c2, 0x04e8: 0x38c9, 0x04e9: 0x3a58, + 0x04ea: 0x38c2, 0x04eb: 0x3a51, 0x04ec: 0x38d7, 0x04ed: 0x3a66, 0x04ee: 0x38d0, 0x04ef: 0x3a5f, + 0x04f0: 0x38de, 0x04f1: 0x3a6d, 0x04f2: 0x3115, 0x04f3: 0x3430, 0x04f4: 0x313d, 0x04f5: 0x345d, + 0x04f6: 0x3138, 0x04f7: 0x3453, 0x04f8: 0x3124, 0x04f9: 0x343f, // Block 0x14, offset 0x500 - 0x0500: 0x4276, 0x0501: 0x427b, 0x0502: 0x427f, 0x0503: 0x4283, 0x0504: 0x4287, 0x0505: 0x428b, - 0x0506: 0x428f, 0x0507: 0x4293, 0x0508: 0x4298, 0x0509: 0x429d, 0x050a: 0x42a2, 0x050b: 0x3f14, - 0x050c: 0x42a7, 0x050d: 0x42ab, 0x050e: 0x42af, 0x050f: 0x42b3, 0x0510: 0x42b7, 0x0511: 0x42bb, - 0x0512: 0x42bf, 0x0513: 0x42c3, 0x0514: 0x42c7, 0x0515: 0x42cb, 0x0516: 0x42cf, 0x0517: 0x42d3, - 0x0518: 0x2c31, 0x0519: 0x42d8, 0x051a: 0x42dc, 0x051b: 0x42e0, 0x051c: 0x42e4, 0x051d: 0x42e8, - 0x051e: 0x42ec, 0x051f: 0x2f5d, 0x0520: 0x42f0, 0x0521: 0x42f4, 0x0522: 0x42f8, 0x0523: 0x42fc, - 0x0524: 0x4300, 0x0525: 0x4305, 0x0526: 0x430a, 0x0527: 0x430f, 0x0528: 0x4313, 0x0529: 0x4317, - 0x052a: 0x431b, 0x052b: 0x431f, 0x052c: 0x4324, 0x052d: 0x4328, 0x052e: 0x432d, 0x052f: 0x4331, - 0x0530: 0x4335, 0x0531: 0x433a, 0x0532: 0x433f, 0x0533: 0x4343, 0x0534: 0x2b45, 0x0535: 0x4347, - 0x0536: 0x434b, 0x0537: 0x434f, 0x0538: 0x4353, 0x0539: 0x4357, 0x053a: 0x435b, 0x053b: 0x306a, - 0x053c: 0x435f, 0x053d: 0x4363, 0x053e: 0x4367, 0x053f: 0x436b, + 0x0500: 0x47bb, 0x0501: 0x47c1, 0x0502: 0x48d5, 0x0503: 0x48ed, 0x0504: 0x48dd, 0x0505: 0x48f5, + 0x0506: 0x48e5, 0x0507: 0x48fd, 0x0508: 0x4761, 0x0509: 0x4767, 0x050a: 0x4845, 0x050b: 0x485d, + 0x050c: 0x484d, 0x050d: 0x4865, 0x050e: 0x4855, 0x050f: 0x486d, 0x0510: 0x47cd, 0x0511: 0x47d3, + 0x0512: 0x3c9d, 0x0513: 0x3cad, 0x0514: 0x3ca5, 0x0515: 0x3cb5, + 0x0518: 0x476d, 0x0519: 0x4773, 0x051a: 0x3bcd, 0x051b: 0x3bdd, 0x051c: 0x3bd5, 0x051d: 0x3be5, + 0x0520: 0x47e5, 0x0521: 0x47eb, 0x0522: 0x4905, 0x0523: 0x491d, + 0x0524: 0x490d, 0x0525: 0x4925, 0x0526: 0x4915, 0x0527: 0x492d, 0x0528: 0x4779, 0x0529: 0x477f, + 0x052a: 0x4875, 0x052b: 0x488d, 0x052c: 0x487d, 0x052d: 0x4895, 0x052e: 0x4885, 0x052f: 0x489d, + 0x0530: 0x47fd, 0x0531: 0x4803, 0x0532: 0x3cfd, 0x0533: 0x3d15, 0x0534: 0x3d05, 0x0535: 0x3d1d, + 0x0536: 0x3d0d, 0x0537: 0x3d25, 0x0538: 0x4785, 0x0539: 0x478b, 0x053a: 0x3bfd, 0x053b: 0x3c15, + 0x053c: 0x3c05, 0x053d: 0x3c1d, 0x053e: 0x3c0d, 0x053f: 0x3c25, // Block 0x15, offset 0x540 - 0x0540: 0x436f, 0x0541: 0x4373, 0x0542: 0x4377, 0x0543: 0x437b, 0x0544: 0x1a66, 0x0545: 0x437f, - 0x0546: 0x4384, 0x0547: 0x4388, 0x0548: 0x438c, 0x0549: 0x4390, 0x054a: 0x4394, 0x054b: 0x4398, - 0x054c: 0x439d, 0x054d: 0x43a2, 0x054e: 0x43a6, 0x054f: 0x43aa, 0x0550: 0x307e, 0x0551: 0x3082, - 0x0552: 0x1a82, 0x0553: 0x43ae, 0x0554: 0x43b3, 0x0555: 0x43b7, 0x0556: 0x43bb, 0x0557: 0x43bf, - 0x0558: 0x43c3, 0x0559: 0x43c8, 0x055a: 0x43cd, 0x055b: 0x43d1, 0x055c: 0x43d5, 0x055d: 0x43d9, - 0x055e: 0x43de, 0x055f: 0x3086, 0x0560: 0x43e2, 0x0561: 0x43e7, 0x0562: 0x43ec, 0x0563: 0x43f0, - 0x0564: 0x43f4, 0x0565: 0x43f8, 0x0566: 0x43fd, 0x0567: 0x4401, 0x0568: 0x4405, 0x0569: 0x4409, - 0x056a: 0x440d, 0x056b: 0x4411, 0x056c: 0x4415, 0x056d: 0x4419, 0x056e: 0x441e, 0x056f: 0x4422, - 0x0570: 0x4426, 0x0571: 0x442a, 0x0572: 0x442f, 0x0573: 0x4433, 0x0574: 0x4437, 0x0575: 0x443b, - 0x0576: 0x443f, 0x0577: 0x4444, 0x0578: 0x4449, 0x0579: 0x444d, 0x057a: 0x4451, 0x057b: 0x4455, - 0x057c: 0x445a, 0x057d: 0x445e, 0x057e: 0x309e, 0x057f: 0x309e, + 0x0540: 0x4809, 0x0541: 0x480f, 0x0542: 0x3d2d, 0x0543: 0x3d3d, 0x0544: 0x3d35, 0x0545: 0x3d45, + 0x0548: 0x4791, 0x0549: 0x4797, 0x054a: 0x3c2d, 0x054b: 0x3c3d, + 0x054c: 0x3c35, 0x054d: 0x3c45, 0x0550: 0x481b, 0x0551: 0x4821, + 0x0552: 0x3d65, 0x0553: 0x3d7d, 0x0554: 0x3d6d, 0x0555: 0x3d85, 0x0556: 0x3d75, 0x0557: 0x3d8d, + 0x0559: 0x479d, 0x055b: 0x3c4d, 0x055d: 0x3c55, + 0x055f: 0x3c5d, 0x0560: 0x4833, 0x0561: 0x4839, 0x0562: 0x4935, 0x0563: 0x494d, + 0x0564: 0x493d, 0x0565: 0x4955, 0x0566: 0x4945, 0x0567: 0x495d, 0x0568: 0x47a3, 0x0569: 0x47a9, + 0x056a: 0x48a5, 0x056b: 0x48bd, 0x056c: 0x48ad, 0x056d: 0x48c5, 0x056e: 0x48b5, 0x056f: 0x48cd, + 0x0570: 0x47af, 0x0571: 0x421c, 0x0572: 0x3576, 0x0573: 0x4222, 0x0574: 0x47d9, 0x0575: 0x4228, + 0x0576: 0x3588, 0x0577: 0x422e, 0x0578: 0x35a6, 0x0579: 0x4234, 0x057a: 0x35be, 0x057b: 0x423a, + 0x057c: 0x4827, 0x057d: 0x4240, + // Block 0x16, offset 0x580 + 0x0580: 0x3c85, 0x0581: 0x3c8d, 0x0582: 0x4069, 0x0583: 0x4087, 0x0584: 0x4073, 0x0585: 0x4091, + 0x0586: 0x407d, 0x0587: 0x409b, 0x0588: 0x3bbd, 0x0589: 0x3bc5, 0x058a: 0x3fb5, 0x058b: 0x3fd3, + 0x058c: 0x3fbf, 0x058d: 0x3fdd, 0x058e: 0x3fc9, 0x058f: 0x3fe7, 0x0590: 0x3ccd, 0x0591: 0x3cd5, + 0x0592: 0x40a5, 0x0593: 0x40c3, 0x0594: 0x40af, 0x0595: 0x40cd, 0x0596: 0x40b9, 0x0597: 0x40d7, + 0x0598: 0x3bed, 0x0599: 0x3bf5, 0x059a: 0x3ff1, 0x059b: 0x400f, 0x059c: 0x3ffb, 0x059d: 0x4019, + 0x059e: 0x4005, 0x059f: 0x4023, 0x05a0: 0x3da5, 0x05a1: 0x3dad, 0x05a2: 0x40e1, 0x05a3: 0x40ff, + 0x05a4: 0x40eb, 0x05a5: 0x4109, 0x05a6: 0x40f5, 0x05a7: 0x4113, 0x05a8: 0x3c65, 0x05a9: 0x3c6d, + 0x05aa: 0x402d, 0x05ab: 0x404b, 0x05ac: 0x4037, 0x05ad: 0x4055, 0x05ae: 0x4041, 0x05af: 0x405f, + 0x05b0: 0x356a, 0x05b1: 0x3564, 0x05b2: 0x3c75, 0x05b3: 0x3570, 0x05b4: 0x3c7d, + 0x05b6: 0x47c7, 0x05b7: 0x3c95, 0x05b8: 0x34da, 0x05b9: 0x34d4, 0x05ba: 0x34c8, 0x05bb: 0x41ec, + 0x05bc: 0x34e0, 0x05be: 0x0490, 0x05bf: 0x8800, + // Block 0x17, offset 0x5c0 + 0x05c1: 0x348c, 0x05c2: 0x3cbd, 0x05c3: 0x3582, 0x05c4: 0x3cc5, + 0x05c6: 0x47f1, 0x05c7: 0x3cdd, 0x05c8: 0x34e6, 0x05c9: 0x41f2, 0x05ca: 0x34f2, 0x05cb: 0x41f8, + 0x05cc: 0x34fe, 0x05cd: 0x3a74, 0x05ce: 0x3a7b, 0x05cf: 0x3a82, 0x05d0: 0x359a, 0x05d1: 0x3594, + 0x05d2: 0x3ce5, 0x05d3: 0x43e2, 0x05d6: 0x35a0, 0x05d7: 0x3cf5, + 0x05d8: 0x3516, 0x05d9: 0x3510, 0x05da: 0x3504, 0x05db: 0x41fe, 0x05dd: 0x3a89, + 0x05de: 0x3a90, 0x05df: 0x3a97, 0x05e0: 0x35d0, 0x05e1: 0x35ca, 0x05e2: 0x3d4d, 0x05e3: 0x43ea, + 0x05e4: 0x35b2, 0x05e5: 0x35b8, 0x05e6: 0x35d6, 0x05e7: 0x3d5d, 0x05e8: 0x3546, 0x05e9: 0x3540, + 0x05ea: 0x3534, 0x05eb: 0x420a, 0x05ec: 0x352e, 0x05ed: 0x3480, 0x05ee: 0x41e6, 0x05ef: 0x014f, + 0x05f2: 0x3d95, 0x05f3: 0x35dc, 0x05f4: 0x3d9d, + 0x05f6: 0x483f, 0x05f7: 0x3db5, 0x05f8: 0x3522, 0x05f9: 0x4204, 0x05fa: 0x3552, 0x05fb: 0x4216, + 0x05fc: 0x355e, 0x05fd: 0x0391, 0x05fe: 0x8800, + // Block 0x18, offset 0x600 + 0x0601: 0x3aeb, 0x0603: 0x8800, 0x0604: 0x3af2, 0x0605: 0x8800, + 0x0607: 0x3af9, 0x0608: 0x8800, 0x0609: 0x3b00, + 0x060d: 0x8800, + 0x0620: 0x2e4a, 0x0621: 0x8800, 0x0622: 0x3b0e, + 0x0624: 0x8800, 0x0625: 0x8800, + 0x062d: 0x3b07, 0x062e: 0x2e45, 0x062f: 0x2e4f, + 0x0630: 0x3b15, 0x0631: 0x3b1c, 0x0632: 0x8800, 0x0633: 0x8800, 0x0634: 0x3b23, 0x0635: 0x3b2a, + 0x0636: 0x8800, 0x0637: 0x8800, 0x0638: 0x3b31, 0x0639: 0x3b38, 0x063a: 0x8800, 0x063b: 0x8800, + 0x063c: 0x8800, 0x063d: 0x8800, + // Block 0x19, offset 0x640 + 0x0640: 0x3b3f, 0x0641: 0x3b46, 0x0642: 0x8800, 0x0643: 0x8800, 0x0644: 0x3b5b, 0x0645: 0x3b62, + 0x0646: 0x8800, 0x0647: 0x8800, 0x0648: 0x3b69, 0x0649: 0x3b70, + 0x0651: 0x8800, + 0x0652: 0x8800, + 0x0662: 0x8800, + 0x0668: 0x8800, 0x0669: 0x8800, + 0x066b: 0x8800, 0x066c: 0x3b85, 0x066d: 0x3b8c, 0x066e: 0x3b93, 0x066f: 0x3b9a, + 0x0672: 0x8800, 0x0673: 0x8800, 0x0674: 0x8800, 0x0675: 0x8800, + // Block 0x1a, offset 0x680 + 0x0686: 0x8800, 0x068b: 0x8800, + 0x068c: 0x3ded, 0x068d: 0x8800, 0x068e: 0x3df5, 0x068f: 0x8800, 0x0690: 0x3dfd, 0x0691: 0x8800, + 0x0692: 0x3e05, 0x0693: 0x8800, 0x0694: 0x3e0d, 0x0695: 0x8800, 0x0696: 0x3e15, 0x0697: 0x8800, + 0x0698: 0x3e1d, 0x0699: 0x8800, 0x069a: 0x3e25, 0x069b: 0x8800, 0x069c: 0x3e2d, 0x069d: 0x8800, + 0x069e: 0x3e35, 0x069f: 0x8800, 0x06a0: 0x3e3d, 0x06a1: 0x8800, 0x06a2: 0x3e45, + 0x06a4: 0x8800, 0x06a5: 0x3e4d, 0x06a6: 0x8800, 0x06a7: 0x3e55, 0x06a8: 0x8800, 0x06a9: 0x3e5d, + 0x06af: 0x8800, + 0x06b0: 0x3e65, 0x06b1: 0x3e6d, 0x06b2: 0x8800, 0x06b3: 0x3e75, 0x06b4: 0x3e7d, 0x06b5: 0x8800, + 0x06b6: 0x3e85, 0x06b7: 0x3e8d, 0x06b8: 0x8800, 0x06b9: 0x3e95, 0x06ba: 0x3e9d, 0x06bb: 0x8800, + 0x06bc: 0x3ea5, 0x06bd: 0x3ead, + // Block 0x1b, offset 0x6c0 + 0x06d4: 0x3de5, + 0x06d9: 0x8608, 0x06da: 0x8608, 0x06dd: 0x8800, + 0x06de: 0x3eb5, + 0x06e6: 0x8800, + 0x06eb: 0x8800, 0x06ec: 0x3ec5, 0x06ed: 0x8800, 0x06ee: 0x3ecd, 0x06ef: 0x8800, + 0x06f0: 0x3ed5, 0x06f1: 0x8800, 0x06f2: 0x3edd, 0x06f3: 0x8800, 0x06f4: 0x3ee5, 0x06f5: 0x8800, + 0x06f6: 0x3eed, 0x06f7: 0x8800, 0x06f8: 0x3ef5, 0x06f9: 0x8800, 0x06fa: 0x3efd, 0x06fb: 0x8800, + 0x06fc: 0x3f05, 0x06fd: 0x8800, 0x06fe: 0x3f0d, 0x06ff: 0x8800, + // Block 0x1c, offset 0x700 + 0x0700: 0x3f15, 0x0701: 0x8800, 0x0702: 0x3f1d, 0x0704: 0x8800, 0x0705: 0x3f25, + 0x0706: 0x8800, 0x0707: 0x3f2d, 0x0708: 0x8800, 0x0709: 0x3f35, + 0x070f: 0x8800, 0x0710: 0x3f3d, 0x0711: 0x3f45, + 0x0712: 0x8800, 0x0713: 0x3f4d, 0x0714: 0x3f55, 0x0715: 0x8800, 0x0716: 0x3f5d, 0x0717: 0x3f65, + 0x0718: 0x8800, 0x0719: 0x3f6d, 0x071a: 0x3f75, 0x071b: 0x8800, 0x071c: 0x3f7d, 0x071d: 0x3f85, + 0x072f: 0x8800, + 0x0730: 0x8800, 0x0731: 0x8800, 0x0732: 0x8800, 0x0734: 0x3ebd, + 0x0737: 0x3f8d, 0x0738: 0x3f95, 0x0739: 0x3f9d, 0x073a: 0x3fa5, + 0x073d: 0x8800, 0x073e: 0x3fad, + // Block 0x1d, offset 0x740 + 0x0740: 0x18b5, 0x0741: 0x1239, 0x0742: 0x1911, 0x0743: 0x18dd, 0x0744: 0x1395, 0x0745: 0x0c29, + 0x0746: 0x0e1d, 0x0747: 0x1b5d, 0x0748: 0x1b5d, 0x0749: 0x0f49, 0x074a: 0x1995, 0x074b: 0x0e81, + 0x074c: 0x0f45, 0x074d: 0x112d, 0x074e: 0x150d, 0x074f: 0x169d, 0x0750: 0x17d5, 0x0751: 0x1811, + 0x0752: 0x1845, 0x0753: 0x1959, 0x0754: 0x12b1, 0x0755: 0x133d, 0x0756: 0x13e9, 0x0757: 0x1481, + 0x0758: 0x179d, 0x0759: 0x197d, 0x075a: 0x1aa5, 0x075b: 0x0c4d, 0x075c: 0x0df1, 0x075d: 0x12c5, + 0x075e: 0x140d, 0x075f: 0x17d1, 0x0760: 0x1af5, 0x0761: 0x0ff1, 0x0762: 0x13b5, 0x0763: 0x17c1, + 0x0764: 0x1855, 0x0765: 0x1161, 0x0766: 0x16f9, 0x0767: 0x181d, 0x0768: 0x105d, 0x0769: 0x124d, + 0x076a: 0x1355, 0x076b: 0x1459, 0x076c: 0x1965, 0x076d: 0x0c8d, 0x076e: 0x0d25, 0x076f: 0x0d91, + 0x0770: 0x11c9, 0x0771: 0x12bd, 0x0772: 0x1409, 0x0773: 0x152d, 0x0774: 0x16b5, 0x0775: 0x17c9, + 0x0776: 0x17e1, 0x0777: 0x1905, 0x0778: 0x1a21, 0x0779: 0x1ad5, 0x077a: 0x1af1, 0x077b: 0x1569, + 0x077c: 0x15a9, 0x077d: 0x1661, 0x077e: 0x1781, 0x077f: 0x19b1, + // Block 0x1e, offset 0x780 + 0x0780: 0x1afd, 0x0781: 0x1889, 0x0782: 0x0f05, 0x0783: 0x1079, 0x0784: 0x1619, 0x0785: 0x16d9, + 0x0786: 0x143d, 0x0787: 0x1571, 0x0788: 0x18d5, 0x0789: 0x1a19, 0x078a: 0x0f01, 0x078b: 0x0fcd, + 0x078c: 0x12b5, 0x078d: 0x1369, 0x078e: 0x139d, 0x078f: 0x1651, 0x0790: 0x1679, 0x0791: 0x19dd, + 0x0792: 0x0d8d, 0x0793: 0x16e5, 0x0794: 0x0d31, 0x0795: 0x0d2d, 0x0796: 0x15d5, 0x0797: 0x1665, + 0x0798: 0x1799, 0x0799: 0x19e5, 0x079a: 0x18a5, 0x079b: 0x1165, 0x079c: 0x12b1, 0x079d: 0x1895, + 0x079e: 0x0c35, 0x079f: 0x0fa1, 0x07a0: 0x10d1, 0x07a1: 0x146d, 0x07a2: 0x14ed, 0x07a3: 0x0db1, + 0x07a4: 0x1579, 0x07a5: 0x0c9d, 0x07a6: 0x10b5, 0x07a7: 0x0c15, 0x07a8: 0x1329, 0x07a9: 0x11e1, + 0x07aa: 0x164d, 0x07ab: 0x0e05, 0x07ac: 0x0ef1, 0x07ad: 0x1539, 0x07ae: 0x17a1, 0x07af: 0x1879, + 0x07b0: 0x12f5, 0x07b1: 0x1935, 0x07b2: 0x1321, 0x07b3: 0x1175, 0x07b4: 0x1759, 0x07b5: 0x1195, + 0x07b6: 0x14e9, 0x07b7: 0x0c69, 0x07b8: 0x0ce5, 0x07b9: 0x0d29, 0x07ba: 0x1291, 0x07bb: 0x1639, + 0x07bc: 0x1731, 0x07bd: 0x1885, 0x07be: 0x1991, 0x07bf: 0x0d99, + // Block 0x1f, offset 0x7c0 + 0x07c0: 0x0e4d, 0x07c1: 0x0f55, 0x07c2: 0x106d, 0x07c3: 0x11fd, 0x07c4: 0x13b9, 0x07c5: 0x157d, + 0x07c6: 0x19cd, 0x07c7: 0x1aad, 0x07c8: 0x1b01, 0x07c9: 0x1b19, 0x07ca: 0x0d75, 0x07cb: 0x1231, + 0x07cc: 0x12e1, 0x07cd: 0x1929, 0x07ce: 0x1039, 0x07cf: 0x1115, 0x07d0: 0x1131, 0x07d1: 0x11c1, + 0x07d2: 0x13a9, 0x07d3: 0x13f5, 0x07d4: 0x14a5, 0x07d5: 0x15c9, 0x07d6: 0x166d, 0x07d7: 0x16d1, + 0x07d8: 0x1919, 0x07d9: 0x17a9, 0x07da: 0x1941, 0x07db: 0x19b5, 0x07dc: 0x0d4d, 0x07dd: 0x0d79, + 0x07de: 0x0e61, 0x07df: 0x13e5, 0x07e0: 0x1831, 0x07e1: 0x1879, 0x07e2: 0x1059, 0x07e3: 0x10c9, + 0x07e4: 0x118d, 0x07e5: 0x12ed, 0x07e6: 0x1615, 0x07e7: 0x1461, 0x07e8: 0x0c79, 0x07e9: 0x0ebd, + 0x07ea: 0x0fa1, 0x07eb: 0x1005, 0x07ec: 0x10d5, 0x07ed: 0x147d, 0x07ee: 0x1499, 0x07ef: 0x16a9, + 0x07f0: 0x16c9, 0x07f1: 0x1999, 0x07f2: 0x1a15, 0x07f3: 0x1a25, 0x07f4: 0x1a61, 0x07f5: 0x0c91, + 0x07f6: 0x15bd, 0x07f7: 0x1985, 0x07f8: 0x19fd, 0x07f9: 0x10ed, 0x07fa: 0x0c55, 0x07fb: 0x0cb5, + 0x07fc: 0x0fa5, 0x07fd: 0x0fc5, 0x07fe: 0x11ed, 0x07ff: 0x12b1, + // Block 0x20, offset 0x800 + 0x0800: 0x1401, 0x0801: 0x1509, 0x0802: 0x17b5, 0x0803: 0x1955, 0x0804: 0x1b55, 0x0805: 0x1221, + 0x0806: 0x19d9, 0x0807: 0x0d71, 0x0808: 0x126d, 0x0809: 0x1279, 0x080a: 0x134d, 0x080b: 0x1385, + 0x080c: 0x1489, 0x080d: 0x14e5, 0x080e: 0x1565, 0x080f: 0x1649, 0x0810: 0x1a6d, 0x0811: 0x0ced, + 0x0812: 0x1141, 0x0813: 0x19e9, 0x0814: 0x0ca5, 0x0815: 0x0fe9, 0x0816: 0x136d, 0x0817: 0x191d, + 0x0818: 0x10a5, 0x0819: 0x10f5, 0x081a: 0x1281, 0x081b: 0x146d, 0x081c: 0x19f1, 0x081d: 0x0d55, + 0x081e: 0x0e3d, 0x081f: 0x0fd5, 0x0820: 0x1211, 0x0821: 0x125d, 0x0822: 0x129d, 0x0823: 0x1331, + 0x0824: 0x1485, 0x0825: 0x14f9, 0x0826: 0x1695, 0x0827: 0x1835, 0x0828: 0x1841, 0x0829: 0x198d, + 0x082a: 0x1a09, 0x082b: 0x0dc1, 0x082c: 0x1389, 0x082d: 0x0e41, 0x082e: 0x1405, 0x082f: 0x14a9, + 0x0830: 0x17c5, 0x0831: 0x19f5, 0x0832: 0x1add, 0x0833: 0x1b05, 0x0834: 0x1275, 0x0835: 0x1365, + 0x0836: 0x1701, 0x0837: 0x15f5, 0x0838: 0x1601, 0x0839: 0x1625, 0x083a: 0x1455, 0x083b: 0x13dd, + 0x083c: 0x18a1, 0x083d: 0x0c71, 0x083e: 0x1769, 0x083f: 0x0d59, + // Block 0x21, offset 0x840 + 0x0840: 0x0d49, 0x0841: 0x1049, 0x0842: 0x1169, 0x0843: 0x1631, 0x0844: 0x0f91, 0x0845: 0x1341, + 0x0846: 0x122d, 0x0847: 0x1925, 0x0848: 0x1825, 0x0849: 0x19e1, 0x084a: 0x1861, 0x084b: 0x1065, + 0x084c: 0x0cc5, 0x084d: 0x0e99, 0x0850: 0x0eed, + 0x0852: 0x121d, 0x0855: 0x0d35, 0x0856: 0x145d, 0x0857: 0x1521, + 0x0858: 0x1585, 0x0859: 0x15a1, 0x085a: 0x15a5, 0x085b: 0x15b9, 0x085c: 0x1a2d, 0x085d: 0x1629, + 0x085e: 0x16ad, 0x0860: 0x17cd, 0x0862: 0x1891, + 0x0865: 0x1945, 0x0866: 0x196d, + 0x086a: 0x1a81, 0x086b: 0x1a85, 0x086c: 0x1a89, 0x086d: 0x1aed, + 0x0870: 0x0c95, 0x0871: 0x0cb9, 0x0872: 0x0ccd, 0x0873: 0x0d89, 0x0874: 0x0d95, 0x0875: 0x0dd5, + 0x0876: 0x0e89, 0x0877: 0x0ea5, 0x0878: 0x0ead, 0x0879: 0x0ee9, 0x087a: 0x0ef5, 0x087b: 0x0fd1, + 0x087c: 0x0fd9, 0x087d: 0x10e1, 0x087e: 0x1109, 0x087f: 0x1111, + // Block 0x22, offset 0x880 + 0x0880: 0x1129, 0x0881: 0x11d5, 0x0882: 0x1205, 0x0883: 0x1225, 0x0884: 0x1295, 0x0885: 0x1359, + 0x0886: 0x1375, 0x0887: 0x13a5, 0x0888: 0x13f9, 0x0889: 0x1419, 0x088a: 0x148d, 0x088b: 0x156d, + 0x088c: 0x1589, 0x088d: 0x1591, 0x088e: 0x158d, 0x088f: 0x1595, 0x0890: 0x1599, 0x0891: 0x159d, + 0x0892: 0x15b1, 0x0893: 0x15b5, 0x0894: 0x15d9, 0x0895: 0x15ed, 0x0896: 0x1609, 0x0897: 0x166d, + 0x0898: 0x1675, 0x0899: 0x167d, 0x089a: 0x1691, 0x089b: 0x16b9, 0x089c: 0x1709, 0x089d: 0x173d, + 0x089e: 0x173d, 0x089f: 0x17a5, 0x08a0: 0x184d, 0x08a1: 0x1865, 0x08a2: 0x1899, 0x08a3: 0x189d, + 0x08a4: 0x18e1, 0x08a5: 0x18e5, 0x08a6: 0x193d, 0x08a7: 0x1945, 0x08a8: 0x1a0d, 0x08a9: 0x1a51, + 0x08aa: 0x1a69, 0x08ab: 0x10d9, 0x08ac: 0x2018, 0x08ad: 0x1721, + 0x08b0: 0x0c1d, 0x08b1: 0x0d21, 0x08b2: 0x0ce1, 0x08b3: 0x0c89, 0x08b4: 0x0cc9, 0x08b5: 0x0cf5, + 0x08b6: 0x0d85, 0x08b7: 0x0da1, 0x08b8: 0x0e89, 0x08b9: 0x0e75, 0x08ba: 0x0e85, 0x08bb: 0x0ea1, + 0x08bc: 0x0eed, 0x08bd: 0x0efd, 0x08be: 0x0f41, 0x08bf: 0x0f4d, + // Block 0x23, offset 0x8c0 + 0x08c0: 0x0f69, 0x08c1: 0x0f79, 0x08c2: 0x1061, 0x08c3: 0x1069, 0x08c4: 0x1099, 0x08c5: 0x10b9, + 0x08c6: 0x10e9, 0x08c7: 0x1101, 0x08c8: 0x10f1, 0x08c9: 0x1111, 0x08ca: 0x1105, 0x08cb: 0x1129, + 0x08cc: 0x1145, 0x08cd: 0x119d, 0x08ce: 0x11a9, 0x08cf: 0x11b1, 0x08d0: 0x11d9, 0x08d1: 0x121d, + 0x08d2: 0x124d, 0x08d3: 0x1251, 0x08d4: 0x1265, 0x08d5: 0x12e5, 0x08d6: 0x12f5, 0x08d7: 0x134d, + 0x08d8: 0x1399, 0x08d9: 0x1391, 0x08da: 0x13a5, 0x08db: 0x13c1, 0x08dc: 0x13f9, 0x08dd: 0x1551, + 0x08de: 0x141d, 0x08df: 0x1451, 0x08e0: 0x145d, 0x08e1: 0x149d, 0x08e2: 0x14b9, 0x08e3: 0x14dd, + 0x08e4: 0x1501, 0x08e5: 0x1505, 0x08e6: 0x1521, 0x08e7: 0x1525, 0x08e8: 0x1535, 0x08e9: 0x1549, + 0x08ea: 0x1545, 0x08eb: 0x1575, 0x08ec: 0x15f1, 0x08ed: 0x1609, 0x08ee: 0x1621, 0x08ef: 0x1659, + 0x08f0: 0x166d, 0x08f1: 0x1689, 0x08f2: 0x16b9, 0x08f3: 0x176d, 0x08f4: 0x1795, 0x08f5: 0x1809, + 0x08f6: 0x1851, 0x08f7: 0x185d, 0x08f8: 0x1865, 0x08f9: 0x187d, 0x08fa: 0x1891, 0x08fb: 0x1881, + 0x08fc: 0x1899, 0x08fd: 0x1895, 0x08fe: 0x188d, 0x08ff: 0x189d, + // Block 0x24, offset 0x900 + 0x0900: 0x18a9, 0x0901: 0x18e5, 0x0902: 0x1921, 0x0903: 0x1951, 0x0904: 0x1981, 0x0905: 0x19a1, + 0x0906: 0x19ed, 0x0907: 0x1a0d, 0x0908: 0x1a2d, 0x0909: 0x1a41, 0x090a: 0x1a51, 0x090b: 0x1a5d, + 0x090c: 0x1a69, 0x090d: 0x1abd, 0x090e: 0x1b5d, 0x090f: 0x1faf, 0x0910: 0x1faa, 0x0911: 0x1fdc, + 0x0912: 0x0b45, 0x0913: 0x0b6d, 0x0914: 0x0b71, 0x0915: 0x205e, 0x0916: 0x208b, 0x0917: 0x2103, + 0x0918: 0x1b49, 0x0919: 0x1b59, + // Block 0x25, offset 0x940 + 0x0940: 0x0c39, 0x0941: 0x0c31, 0x0942: 0x0c41, 0x0943: 0x1f41, 0x0944: 0x0c85, 0x0945: 0x0c95, + 0x0946: 0x0c99, 0x0947: 0x0ca1, 0x0948: 0x0ca9, 0x0949: 0x0cad, 0x094a: 0x0cb9, 0x094b: 0x0cb1, + 0x094c: 0x0af1, 0x094d: 0x1f55, 0x094e: 0x0ccd, 0x094f: 0x0cd1, 0x0950: 0x0cd5, 0x0951: 0x0cf1, + 0x0952: 0x1f46, 0x0953: 0x0af5, 0x0954: 0x0cdd, 0x0955: 0x0cfd, 0x0956: 0x1f50, 0x0957: 0x0d0d, + 0x0958: 0x0d15, 0x0959: 0x0c75, 0x095a: 0x0d1d, 0x095b: 0x0d21, 0x095c: 0x212b, 0x095d: 0x0d3d, + 0x095e: 0x0d45, 0x095f: 0x0afd, 0x0960: 0x0d5d, 0x0961: 0x0d61, 0x0962: 0x0d69, 0x0963: 0x0d6d, + 0x0964: 0x0b01, 0x0965: 0x0d85, 0x0966: 0x0d89, 0x0967: 0x0d95, 0x0968: 0x0da1, 0x0969: 0x0da5, + 0x096a: 0x0da9, 0x096b: 0x0db1, 0x096c: 0x0dd1, 0x096d: 0x0dd5, 0x096e: 0x0ddd, 0x096f: 0x0ded, + 0x0970: 0x0df5, 0x0971: 0x0df9, 0x0972: 0x0df9, 0x0973: 0x0df9, 0x0974: 0x1f64, 0x0975: 0x13d1, + 0x0976: 0x0e0d, 0x0977: 0x0e15, 0x0978: 0x1f69, 0x0979: 0x0e21, 0x097a: 0x0e29, 0x097b: 0x0e31, + 0x097c: 0x0e59, 0x097d: 0x0e45, 0x097e: 0x0e51, 0x097f: 0x0e55, + // Block 0x26, offset 0x980 + 0x0980: 0x0e5d, 0x0981: 0x0e65, 0x0982: 0x0e69, 0x0983: 0x0e71, 0x0984: 0x0e79, 0x0985: 0x0e7d, + 0x0986: 0x0e7d, 0x0987: 0x0e85, 0x0988: 0x0e8d, 0x0989: 0x0e91, 0x098a: 0x0e9d, 0x098b: 0x0ec1, + 0x098c: 0x0ea5, 0x098d: 0x0ec5, 0x098e: 0x0ea9, 0x098f: 0x0eb1, 0x0990: 0x0d49, 0x0991: 0x0f0d, + 0x0992: 0x0ed5, 0x0993: 0x0ed9, 0x0994: 0x0edd, 0x0995: 0x0ed1, 0x0996: 0x0ee5, 0x0997: 0x0ee1, + 0x0998: 0x0ef9, 0x0999: 0x1f6e, 0x099a: 0x0f15, 0x099b: 0x0f19, 0x099c: 0x0f21, 0x099d: 0x0f2d, + 0x099e: 0x0f35, 0x099f: 0x0f51, 0x09a0: 0x1f73, 0x09a1: 0x1f78, 0x09a2: 0x0f5d, 0x09a3: 0x0f61, + 0x09a4: 0x0f65, 0x09a5: 0x0f59, 0x09a6: 0x0f6d, 0x09a7: 0x0b05, 0x09a8: 0x0b09, 0x09a9: 0x0f75, + 0x09aa: 0x0f7d, 0x09ab: 0x0f7d, 0x09ac: 0x1f7d, 0x09ad: 0x0f99, 0x09ae: 0x0f9d, 0x09af: 0x0fa1, + 0x09b0: 0x0fa9, 0x09b1: 0x1f82, 0x09b2: 0x0fb1, 0x09b3: 0x0fb5, 0x09b4: 0x108d, 0x09b5: 0x0fbd, + 0x09b6: 0x0b0d, 0x09b7: 0x0fc9, 0x09b8: 0x0fd9, 0x09b9: 0x0fe5, 0x09ba: 0x0fe1, 0x09bb: 0x1f8c, + 0x09bc: 0x0fed, 0x09bd: 0x1f91, 0x09be: 0x0ff9, 0x09bf: 0x0ff5, + // Block 0x27, offset 0x9c0 + 0x09c0: 0x0ffd, 0x09c1: 0x100d, 0x09c2: 0x1011, 0x09c3: 0x0b11, 0x09c4: 0x1021, 0x09c5: 0x1029, + 0x09c6: 0x102d, 0x09c7: 0x1031, 0x09c8: 0x0b15, 0x09c9: 0x1f96, 0x09ca: 0x0b19, 0x09cb: 0x104d, + 0x09cc: 0x1051, 0x09cd: 0x1055, 0x09ce: 0x105d, 0x09cf: 0x215d, 0x09d0: 0x1075, 0x09d1: 0x1fa0, + 0x09d2: 0x1fa0, 0x09d3: 0x1715, 0x09d4: 0x1085, 0x09d5: 0x1085, 0x09d6: 0x0b1d, 0x09d7: 0x1fc3, + 0x09d8: 0x2095, 0x09d9: 0x1095, 0x09da: 0x109d, 0x09db: 0x0b21, 0x09dc: 0x10b1, 0x09dd: 0x10c1, + 0x09de: 0x10c5, 0x09df: 0x10cd, 0x09e0: 0x10dd, 0x09e1: 0x0b29, 0x09e2: 0x0b25, 0x09e3: 0x10e1, + 0x09e4: 0x1fa5, 0x09e5: 0x10e5, 0x09e6: 0x10f9, 0x09e7: 0x10fd, 0x09e8: 0x1101, 0x09e9: 0x10fd, + 0x09ea: 0x110d, 0x09eb: 0x1111, 0x09ec: 0x1121, 0x09ed: 0x1119, 0x09ee: 0x111d, 0x09ef: 0x1125, + 0x09f0: 0x1129, 0x09f1: 0x112d, 0x09f2: 0x1139, 0x09f3: 0x113d, 0x09f4: 0x1155, 0x09f5: 0x115d, + 0x09f6: 0x116d, 0x09f7: 0x1181, 0x09f8: 0x1fb4, 0x09f9: 0x117d, 0x09fa: 0x1171, 0x09fb: 0x1189, + 0x09fc: 0x1191, 0x09fd: 0x11a5, 0x09fe: 0x1fb9, 0x09ff: 0x11ad, + // Block 0x28, offset 0xa00 + 0x0a00: 0x11a1, 0x0a01: 0x1199, 0x0a02: 0x0b2d, 0x0a03: 0x11b5, 0x0a04: 0x11bd, 0x0a05: 0x11c5, + 0x0a06: 0x11b9, 0x0a07: 0x0b31, 0x0a08: 0x11d5, 0x0a09: 0x11dd, 0x0a0a: 0x1fbe, 0x0a0b: 0x1209, + 0x0a0c: 0x123d, 0x0a0d: 0x1219, 0x0a0e: 0x0b3d, 0x0a0f: 0x1225, 0x0a10: 0x0b39, 0x0a11: 0x0b35, + 0x0a12: 0x0d01, 0x0a13: 0x0d05, 0x0a14: 0x1241, 0x0a15: 0x1229, 0x0a16: 0x16e9, 0x0a17: 0x0ba1, + 0x0a18: 0x124d, 0x0a19: 0x1251, 0x0a1a: 0x1255, 0x0a1b: 0x1269, 0x0a1c: 0x1261, 0x0a1d: 0x1fd7, + 0x0a1e: 0x0b41, 0x0a1f: 0x127d, 0x0a20: 0x1271, 0x0a21: 0x128d, 0x0a22: 0x1295, 0x0a23: 0x1fe1, + 0x0a24: 0x1299, 0x0a25: 0x1285, 0x0a26: 0x12a1, 0x0a27: 0x0b45, 0x0a28: 0x12a5, 0x0a29: 0x12a9, + 0x0a2a: 0x12ad, 0x0a2b: 0x12b9, 0x0a2c: 0x1fe6, 0x0a2d: 0x12c1, 0x0a2e: 0x0b49, 0x0a2f: 0x12cd, + 0x0a30: 0x1feb, 0x0a31: 0x12d1, 0x0a32: 0x0b4d, 0x0a33: 0x12dd, 0x0a34: 0x12e9, 0x0a35: 0x12f5, + 0x0a36: 0x12f9, 0x0a37: 0x1ff0, 0x0a38: 0x1f87, 0x0a39: 0x1ff5, 0x0a3a: 0x1319, 0x0a3b: 0x1ffa, + 0x0a3c: 0x1325, 0x0a3d: 0x132d, 0x0a3e: 0x131d, 0x0a3f: 0x1339, + // Block 0x29, offset 0xa40 + 0x0a40: 0x1349, 0x0a41: 0x1359, 0x0a42: 0x134d, 0x0a43: 0x1351, 0x0a44: 0x135d, 0x0a45: 0x1361, + 0x0a46: 0x1fff, 0x0a47: 0x1345, 0x0a48: 0x1379, 0x0a49: 0x137d, 0x0a4a: 0x0b51, 0x0a4b: 0x1391, + 0x0a4c: 0x138d, 0x0a4d: 0x2004, 0x0a4e: 0x1371, 0x0a4f: 0x13ad, 0x0a50: 0x2009, 0x0a51: 0x200e, + 0x0a52: 0x13b1, 0x0a53: 0x13c5, 0x0a54: 0x13c1, 0x0a55: 0x13bd, 0x0a56: 0x0b55, 0x0a57: 0x13c9, + 0x0a58: 0x13d9, 0x0a59: 0x13d5, 0x0a5a: 0x13e1, 0x0a5b: 0x1f4b, 0x0a5c: 0x13f1, 0x0a5d: 0x2013, + 0x0a5e: 0x13fd, 0x0a5f: 0x201d, 0x0a60: 0x1411, 0x0a61: 0x141d, 0x0a62: 0x1431, 0x0a63: 0x2022, + 0x0a64: 0x1445, 0x0a65: 0x1449, 0x0a66: 0x2027, 0x0a67: 0x202c, 0x0a68: 0x1465, 0x0a69: 0x1475, + 0x0a6a: 0x0b59, 0x0a6b: 0x1479, 0x0a6c: 0x0b5d, 0x0a6d: 0x0b5d, 0x0a6e: 0x1491, 0x0a6f: 0x1495, + 0x0a70: 0x149d, 0x0a71: 0x14a1, 0x0a72: 0x14ad, 0x0a73: 0x0b61, 0x0a74: 0x14c5, 0x0a75: 0x2031, + 0x0a76: 0x14e1, 0x0a77: 0x2036, 0x0a78: 0x14ed, 0x0a79: 0x1f9b, 0x0a7a: 0x14fd, 0x0a7b: 0x203b, + 0x0a7c: 0x2040, 0x0a7d: 0x2045, 0x0a7e: 0x0b65, 0x0a7f: 0x0b69, + // Block 0x2a, offset 0xa80 + 0x0a80: 0x1535, 0x0a81: 0x204f, 0x0a82: 0x204a, 0x0a83: 0x2054, 0x0a84: 0x2059, 0x0a85: 0x153d, + 0x0a86: 0x1541, 0x0a87: 0x1541, 0x0a88: 0x1549, 0x0a89: 0x0b71, 0x0a8a: 0x154d, 0x0a8b: 0x0b75, + 0x0a8c: 0x0b79, 0x0a8d: 0x2063, 0x0a8e: 0x1561, 0x0a8f: 0x1569, 0x0a90: 0x1575, 0x0a91: 0x0b7d, + 0x0a92: 0x2068, 0x0a93: 0x1599, 0x0a94: 0x206d, 0x0a95: 0x2072, 0x0a96: 0x15b9, 0x0a97: 0x15d1, + 0x0a98: 0x0b81, 0x0a99: 0x15d9, 0x0a9a: 0x15dd, 0x0a9b: 0x15e1, 0x0a9c: 0x2077, 0x0a9d: 0x207c, + 0x0a9e: 0x207c, 0x0a9f: 0x15f9, 0x0aa0: 0x0b85, 0x0aa1: 0x2081, 0x0aa2: 0x160d, 0x0aa3: 0x1611, + 0x0aa4: 0x0b89, 0x0aa5: 0x2086, 0x0aa6: 0x162d, 0x0aa7: 0x0b8d, 0x0aa8: 0x163d, 0x0aa9: 0x1635, + 0x0aaa: 0x1645, 0x0aab: 0x2090, 0x0aac: 0x165d, 0x0aad: 0x0b91, 0x0aae: 0x1669, 0x0aaf: 0x1671, + 0x0ab0: 0x1681, 0x0ab1: 0x0b95, 0x0ab2: 0x209a, 0x0ab3: 0x209f, 0x0ab4: 0x0b99, 0x0ab5: 0x20a4, + 0x0ab6: 0x1699, 0x0ab7: 0x20a9, 0x0ab8: 0x16a5, 0x0ab9: 0x16b1, 0x0aba: 0x16b9, 0x0abb: 0x20ae, + 0x0abc: 0x20b3, 0x0abd: 0x16cd, 0x0abe: 0x20b8, 0x0abf: 0x16d5, + // Block 0x2b, offset 0xac0 + 0x0ac0: 0x1fc8, 0x0ac1: 0x0b9d, 0x0ac2: 0x16ed, 0x0ac3: 0x16f1, 0x0ac4: 0x0ba5, 0x0ac5: 0x16f5, + 0x0ac6: 0x0f71, 0x0ac7: 0x20bd, 0x0ac8: 0x20c2, 0x0ac9: 0x1fcd, 0x0aca: 0x1fd2, 0x0acb: 0x1715, + 0x0acc: 0x1719, 0x0acd: 0x1931, 0x0ace: 0x0ba9, 0x0acf: 0x1745, 0x0ad0: 0x1741, 0x0ad1: 0x1749, + 0x0ad2: 0x0d7d, 0x0ad3: 0x174d, 0x0ad4: 0x1751, 0x0ad5: 0x1755, 0x0ad6: 0x175d, 0x0ad7: 0x20c7, + 0x0ad8: 0x1759, 0x0ad9: 0x1761, 0x0ada: 0x1775, 0x0adb: 0x1779, 0x0adc: 0x1765, 0x0add: 0x177d, + 0x0ade: 0x1791, 0x0adf: 0x17a5, 0x0ae0: 0x1771, 0x0ae1: 0x1785, 0x0ae2: 0x1789, 0x0ae3: 0x178d, + 0x0ae4: 0x20cc, 0x0ae5: 0x20d6, 0x0ae6: 0x20d1, 0x0ae7: 0x0bad, 0x0ae8: 0x17ad, 0x0ae9: 0x17b1, + 0x0aea: 0x17b9, 0x0aeb: 0x20ea, 0x0aec: 0x17bd, 0x0aed: 0x20db, 0x0aee: 0x0bb1, 0x0aef: 0x0bb5, + 0x0af0: 0x20e0, 0x0af1: 0x20e5, 0x0af2: 0x0bb9, 0x0af3: 0x17dd, 0x0af4: 0x17e1, 0x0af5: 0x17e5, + 0x0af6: 0x17e9, 0x0af7: 0x17f5, 0x0af8: 0x17f1, 0x0af9: 0x17fd, 0x0afa: 0x17f9, 0x0afb: 0x1809, + 0x0afc: 0x1801, 0x0afd: 0x1805, 0x0afe: 0x180d, 0x0aff: 0x0bbd, + // Block 0x2c, offset 0xb00 + 0x0b00: 0x1815, 0x0b01: 0x1819, 0x0b02: 0x0bc1, 0x0b03: 0x1829, 0x0b04: 0x182d, 0x0b05: 0x20ef, + 0x0b06: 0x1839, 0x0b07: 0x183d, 0x0b08: 0x0bc5, 0x0b09: 0x1849, 0x0b0a: 0x0af9, 0x0b0b: 0x20f4, + 0x0b0c: 0x20f9, 0x0b0d: 0x0bc9, 0x0b0e: 0x0bcd, 0x0b0f: 0x1875, 0x0b10: 0x188d, 0x0b11: 0x18a9, + 0x0b12: 0x18b9, 0x0b13: 0x20fe, 0x0b14: 0x18cd, 0x0b15: 0x18d1, 0x0b16: 0x18e9, 0x0b17: 0x18f5, + 0x0b18: 0x2108, 0x0b19: 0x1f5a, 0x0b1a: 0x1901, 0x0b1b: 0x18fd, 0x0b1c: 0x1909, 0x0b1d: 0x1f5f, + 0x0b1e: 0x1915, 0x0b1f: 0x1921, 0x0b20: 0x210d, 0x0b21: 0x2112, 0x0b22: 0x1961, 0x0b23: 0x1969, + 0x0b24: 0x1971, 0x0b25: 0x2117, 0x0b26: 0x1975, 0x0b27: 0x199d, 0x0b28: 0x19a9, 0x0b29: 0x19ad, + 0x0b2a: 0x19a5, 0x0b2b: 0x19b9, 0x0b2c: 0x19bd, 0x0b2d: 0x211c, 0x0b2e: 0x19c9, 0x0b2f: 0x0bd1, + 0x0b30: 0x19d1, 0x0b31: 0x2121, 0x0b32: 0x0bd5, 0x0b33: 0x1a05, 0x0b34: 0x1001, 0x0b35: 0x1a1d, + 0x0b36: 0x2126, 0x0b37: 0x2130, 0x0b38: 0x0bd9, 0x0b39: 0x0bdd, 0x0b3a: 0x1a45, 0x0b3b: 0x2135, + 0x0b3c: 0x0be1, 0x0b3d: 0x213a, 0x0b3e: 0x1a5d, 0x0b3f: 0x1a5d, + // Block 0x2d, offset 0xb40 + 0x0b40: 0x1a65, 0x0b41: 0x213f, 0x0b42: 0x1a7d, 0x0b43: 0x0be5, 0x0b44: 0x1a8d, 0x0b45: 0x1a99, + 0x0b46: 0x1aa1, 0x0b47: 0x1aa9, 0x0b48: 0x0be9, 0x0b49: 0x2144, 0x0b4a: 0x1abd, 0x0b4b: 0x1ad9, + 0x0b4c: 0x1ae5, 0x0b4d: 0x0bed, 0x0b4e: 0x0bf1, 0x0b4f: 0x1ae9, 0x0b50: 0x2149, 0x0b51: 0x0bf5, + 0x0b52: 0x214e, 0x0b53: 0x2153, 0x0b54: 0x2158, 0x0b55: 0x1b0d, 0x0b56: 0x0bf9, 0x0b57: 0x1b21, + 0x0b58: 0x1b29, 0x0b59: 0x1b2d, 0x0b5a: 0x1b35, 0x0b5b: 0x1b3d, 0x0b5c: 0x1b45, 0x0b5d: 0x2162, } -// nfcDecompSparseOffset: 56 entries, 112 bytes -var nfcDecompSparseOffset = []uint16{0x0, 0xa, 0x10, 0x15, 0x18, 0x22, 0x27, 0x2e, 0x31, 0x38, 0x3e, 0x46, 0x48, 0x4c, 0x50, 0x52, 0x56, 0x59, 0x5c, 0x60, 0x62, 0x64, 0x66, 0x6a, 0x6c, 0x70, 0x7a, 0x82, 0x84, 0x8d, 0x90, 0x9e, 0xa0, 0xa4, 0xa7, 0xa9, 0xaf, 0xbb, 0xc0, 0xc3, 0xc5, 0xc7, 0xd4, 0xe2, 0xed, 0xf4, 0xff, 0x10b, 0x11c, 0x12d, 0x135, 0x139, 0x13d, 0x141, 0x145, 0x147} +// nfcSparseOffset: 94 entries, 188 bytes +var nfcSparseOffset = []uint16{0x0, 0x2, 0x6, 0x8, 0x13, 0x23, 0x25, 0x2a, 0x35, 0x44, 0x51, 0x59, 0x5d, 0x62, 0x64, 0x6c, 0x73, 0x76, 0x7e, 0x82, 0x86, 0x88, 0x8a, 0x93, 0x97, 0x9e, 0xa3, 0xa6, 0xb0, 0xb2, 0xb9, 0xc1, 0xc4, 0xc6, 0xc8, 0xca, 0xcf, 0xde, 0xea, 0xec, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x101, 0x104, 0x106, 0x109, 0x10c, 0x110, 0x119, 0x11b, 0x11e, 0x120, 0x129, 0x138, 0x13a, 0x148, 0x14b, 0x151, 0x157, 0x162, 0x166, 0x168, 0x16a, 0x16c, 0x16e, 0x170, 0x176, 0x179, 0x17b, 0x17d, 0x180, 0x182, 0x184, 0x186, 0x188, 0x18e, 0x190, 0x192, 0x194, 0x196, 0x1a4, 0x1ad, 0x1af, 0x1b1, 0x1b7, 0x1bf, 0x1cc, 0x1d6, 0x1d8} -// nfcDecompSparseValues: 341 entries, 1364 bytes -var nfcDecompSparseValues = [341]valueRange{ +// nfcSparseValues: 474 entries, 1896 bytes +var nfcSparseValues = [474]valueRange{ // Block 0x0, offset 0x1 - {value: 0x0004, lo: 0x09}, - {value: 0x0032, lo: 0x80, hi: 0x85}, - {value: 0x004a, lo: 0x87, hi: 0x8f}, - {value: 0x006e, lo: 0x91, hi: 0x96}, - {value: 0x0086, lo: 0x99, hi: 0x9d}, - {value: 0x009a, lo: 0xa0, hi: 0xa5}, - {value: 0x00b2, lo: 0xa7, hi: 0xaf}, - {value: 0x00d6, lo: 0xb1, hi: 0xb6}, - {value: 0x00ee, lo: 0xb9, hi: 0xbd}, - {value: 0x0102, lo: 0xbf, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x8800, lo: 0xa8, hi: 0xa8}, // Block 0x1, offset 0x2 - {value: 0x0004, lo: 0x05}, - {value: 0x0106, lo: 0x80, hi: 0x8f}, - {value: 0x0146, lo: 0x92, hi: 0xa5}, - {value: 0x0196, lo: 0xa8, hi: 0xb0}, - {value: 0x01c0, lo: 0xb4, hi: 0xb7}, - {value: 0x01d0, lo: 0xb9, hi: 0xbe}, + {value: 0x0091, lo: 0x03}, + {value: 0x4699, lo: 0xa0, hi: 0xa1}, + {value: 0x46cb, lo: 0xaf, hi: 0xb0}, + {value: 0x8800, lo: 0xb7, hi: 0xb7}, // Block 0x2, offset 0x3 - {value: 0x0004, lo: 0x04}, - {value: 0x01f0, lo: 0x83, hi: 0x88}, - {value: 0x020c, lo: 0x8c, hi: 0x91}, - {value: 0x0224, lo: 0x94, hi: 0xa5}, - {value: 0x026c, lo: 0xa8, hi: 0xbe}, + {value: 0x0000, lo: 0x01}, + {value: 0x8800, lo: 0x92, hi: 0x92}, // Block 0x3, offset 0x4 - {value: 0x0004, lo: 0x02}, - {value: 0x02ca, lo: 0xa0, hi: 0xa1}, - {value: 0x02d2, lo: 0xaf, hi: 0xb0}, + {value: 0x0006, lo: 0x0a}, + {value: 0x8800, lo: 0x81, hi: 0x81}, + {value: 0x8800, lo: 0x85, hi: 0x85}, + {value: 0x8800, lo: 0x89, hi: 0x89}, + {value: 0x47f7, lo: 0x8a, hi: 0x8a}, + {value: 0x4815, lo: 0x8b, hi: 0x8b}, + {value: 0x35ac, lo: 0x8c, hi: 0x8c}, + {value: 0x35c4, lo: 0x8d, hi: 0x8d}, + {value: 0x482d, lo: 0x8e, hi: 0x8e}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x35e2, lo: 0x93, hi: 0x94}, // Block 0x4, offset 0x5 - {value: 0x0004, lo: 0x09}, - {value: 0x03d8, lo: 0x80, hi: 0x9b}, - {value: 0x0448, lo: 0x9e, hi: 0x9f}, - {value: 0x0450, lo: 0xa6, hi: 0xaa}, - {value: 0x0466, lo: 0xab, hi: 0xab}, - {value: 0x046c, lo: 0xac, hi: 0xac}, - {value: 0x0472, lo: 0xad, hi: 0xad}, - {value: 0x0478, lo: 0xae, hi: 0xb0}, - {value: 0x0486, lo: 0xb1, hi: 0xb1}, - {value: 0x048c, lo: 0xb2, hi: 0xb3}, + {value: 0x0000, lo: 0x0f}, + {value: 0x8800, lo: 0x83, hi: 0x83}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x8800, lo: 0x8b, hi: 0x8b}, + {value: 0x8800, lo: 0x8d, hi: 0x8d}, + {value: 0x368a, lo: 0x90, hi: 0x90}, + {value: 0x3696, lo: 0x91, hi: 0x91}, + {value: 0x3684, lo: 0x93, hi: 0x93}, + {value: 0x8800, lo: 0x96, hi: 0x96}, + {value: 0x36fc, lo: 0x97, hi: 0x97}, + {value: 0x36c6, lo: 0x9c, hi: 0x9c}, + {value: 0x36ae, lo: 0x9d, hi: 0x9d}, + {value: 0x36d8, lo: 0x9e, hi: 0x9e}, + {value: 0x8800, lo: 0xb4, hi: 0xb5}, + {value: 0x3702, lo: 0xb6, hi: 0xb6}, + {value: 0x3708, lo: 0xb7, hi: 0xb7}, // Block 0x5, offset 0x6 - {value: 0x0003, lo: 0x04}, - {value: 0x04cc, lo: 0x80, hi: 0x81}, - {value: 0x04d2, lo: 0x83, hi: 0x84}, - {value: 0x04da, lo: 0xb4, hi: 0xb4}, - {value: 0x04e1, lo: 0xbe, hi: 0xbe}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x83, hi: 0x87}, // Block 0x6, offset 0x7 - {value: 0x0005, lo: 0x06}, - {value: 0x04e3, lo: 0x85, hi: 0x85}, - {value: 0x04ee, lo: 0x86, hi: 0x87}, - {value: 0x04f6, lo: 0x88, hi: 0x8a}, - {value: 0x0505, lo: 0x8c, hi: 0x8c}, - {value: 0x050a, lo: 0x8e, hi: 0x90}, - {value: 0x051b, lo: 0xaa, hi: 0xb0}, + {value: 0x0001, lo: 0x04}, + {value: 0x8018, lo: 0x81, hi: 0x82}, + {value: 0x80e6, lo: 0x84, hi: 0x84}, + {value: 0x80dc, lo: 0x85, hi: 0x85}, + {value: 0x8012, lo: 0x87, hi: 0x87}, // Block 0x7, offset 0x8 - {value: 0x0005, lo: 0x02}, - {value: 0x0540, lo: 0x8a, hi: 0x8e}, - {value: 0x0562, lo: 0x93, hi: 0x94}, + {value: 0x0000, lo: 0x0a}, + {value: 0x80e6, lo: 0x90, hi: 0x97}, + {value: 0x801e, lo: 0x98, hi: 0x98}, + {value: 0x801f, lo: 0x99, hi: 0x99}, + {value: 0x8020, lo: 0x9a, hi: 0x9a}, + {value: 0x3726, lo: 0xa2, hi: 0xa2}, + {value: 0x372c, lo: 0xa3, hi: 0xa3}, + {value: 0x3738, lo: 0xa4, hi: 0xa4}, + {value: 0x3732, lo: 0xa5, hi: 0xa5}, + {value: 0x373e, lo: 0xa6, hi: 0xa6}, + {value: 0x8800, lo: 0xa7, hi: 0xa7}, // Block 0x8, offset 0x9 - {value: 0x0005, lo: 0x06}, - {value: 0x0584, lo: 0x80, hi: 0x81}, - {value: 0x058e, lo: 0x83, hi: 0x83}, - {value: 0x0593, lo: 0x87, hi: 0x87}, - {value: 0x0598, lo: 0x8c, hi: 0x8e}, - {value: 0x05a7, lo: 0x99, hi: 0x99}, - {value: 0x05ac, lo: 0xb9, hi: 0xb9}, + {value: 0x0000, lo: 0x0e}, + {value: 0x3750, lo: 0x80, hi: 0x80}, + {value: 0x8800, lo: 0x81, hi: 0x81}, + {value: 0x3744, lo: 0x82, hi: 0x82}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x374a, lo: 0x93, hi: 0x93}, + {value: 0x8800, lo: 0x95, hi: 0x95}, + {value: 0x80e6, lo: 0x96, hi: 0x9c}, + {value: 0x80e6, lo: 0x9f, hi: 0xa2}, + {value: 0x80dc, lo: 0xa3, hi: 0xa3}, + {value: 0x80e6, lo: 0xa4, hi: 0xa4}, + {value: 0x80e6, lo: 0xa7, hi: 0xa8}, + {value: 0x80dc, lo: 0xaa, hi: 0xaa}, + {value: 0x80e6, lo: 0xab, hi: 0xac}, + {value: 0x80dc, lo: 0xad, hi: 0xad}, // Block 0x9, offset 0xa - {value: 0x0005, lo: 0x05}, - {value: 0x05b1, lo: 0x90, hi: 0x91}, - {value: 0x05bb, lo: 0x93, hi: 0x93}, - {value: 0x05c0, lo: 0x97, hi: 0x97}, - {value: 0x05c5, lo: 0x9c, hi: 0x9e}, - {value: 0x05d4, lo: 0xb6, hi: 0xb7}, + {value: 0x0000, lo: 0x0c}, + {value: 0x8024, lo: 0x91, hi: 0x91}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, + {value: 0x80dc, lo: 0xb1, hi: 0xb1}, + {value: 0x80e6, lo: 0xb2, hi: 0xb3}, + {value: 0x80dc, lo: 0xb4, hi: 0xb4}, + {value: 0x80e6, lo: 0xb5, hi: 0xb6}, + {value: 0x80dc, lo: 0xb7, hi: 0xb9}, + {value: 0x80e6, lo: 0xba, hi: 0xba}, + {value: 0x80dc, lo: 0xbb, hi: 0xbc}, + {value: 0x80e6, lo: 0xbd, hi: 0xbd}, + {value: 0x80dc, lo: 0xbe, hi: 0xbe}, + {value: 0x80e6, lo: 0xbf, hi: 0xbf}, // Block 0xa, offset 0xb - {value: 0x0005, lo: 0x07}, - {value: 0x05de, lo: 0x81, hi: 0x82}, - {value: 0x05e8, lo: 0x90, hi: 0x93}, - {value: 0x05fc, lo: 0x96, hi: 0x97}, - {value: 0x0606, lo: 0x9a, hi: 0x9f}, - {value: 0x0624, lo: 0xa2, hi: 0xa7}, - {value: 0x0642, lo: 0xaa, hi: 0xb5}, - {value: 0x067e, lo: 0xb8, hi: 0xb9}, + {value: 0x000a, lo: 0x07}, + {value: 0x80e6, lo: 0x80, hi: 0x80}, + {value: 0x80e6, lo: 0x81, hi: 0x81}, + {value: 0x80dc, lo: 0x82, hi: 0x83}, + {value: 0x80dc, lo: 0x84, hi: 0x85}, + {value: 0x80dc, lo: 0x86, hi: 0x87}, + {value: 0x80dc, lo: 0x88, hi: 0x89}, + {value: 0x80e6, lo: 0x8a, hi: 0x8a}, // Block 0xb, offset 0xc - {value: 0x0005, lo: 0x01}, - {value: 0x068d, lo: 0xa2, hi: 0xa6}, - // Block 0xc, offset 0xd {value: 0x0000, lo: 0x03}, - {value: 0x06ba, lo: 0x80, hi: 0x80}, - {value: 0x06bf, lo: 0x82, hi: 0x82}, - {value: 0x06c4, lo: 0x93, hi: 0x93}, + {value: 0x80e6, lo: 0xab, hi: 0xb1}, + {value: 0x80dc, lo: 0xb2, hi: 0xb2}, + {value: 0x80e6, lo: 0xb3, hi: 0xb3}, + // Block 0xc, offset 0xd + {value: 0x0000, lo: 0x04}, + {value: 0x80e6, lo: 0x96, hi: 0x99}, + {value: 0x80e6, lo: 0x9b, hi: 0xa3}, + {value: 0x80e6, lo: 0xa5, hi: 0xa7}, + {value: 0x80e6, lo: 0xa9, hi: 0xad}, // Block 0xd, offset 0xe - {value: 0x0000, lo: 0x03}, - {value: 0x06c9, lo: 0xa9, hi: 0xa9}, - {value: 0x06d0, lo: 0xb1, hi: 0xb1}, - {value: 0x06d7, lo: 0xb4, hi: 0xb4}, + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0x99, hi: 0x9b}, // Block 0xe, offset 0xf - {value: 0x0007, lo: 0x01}, - {value: 0x06de, lo: 0x98, hi: 0x9f}, + {value: 0x0000, lo: 0x07}, + {value: 0x8800, lo: 0xa8, hi: 0xa8}, + {value: 0x3dbd, lo: 0xa9, hi: 0xa9}, + {value: 0x8800, lo: 0xb0, hi: 0xb0}, + {value: 0x3dc5, lo: 0xb1, hi: 0xb1}, + {value: 0x8800, lo: 0xb3, hi: 0xb3}, + {value: 0x3dcd, lo: 0xb4, hi: 0xb4}, + {value: 0x8607, lo: 0xbc, hi: 0xbc}, // Block 0xf, offset 0x10 - {value: 0x0007, lo: 0x03}, - {value: 0x0716, lo: 0x8b, hi: 0x8c}, - {value: 0x0724, lo: 0x9c, hi: 0x9d}, - {value: 0x0732, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0x06}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x80e6, lo: 0x91, hi: 0x91}, + {value: 0x80dc, lo: 0x92, hi: 0x92}, + {value: 0x80e6, lo: 0x93, hi: 0x93}, + {value: 0x80e6, lo: 0x94, hi: 0x94}, + {value: 0x4432, lo: 0x98, hi: 0x9f}, // Block 0x10, offset 0x11 {value: 0x0000, lo: 0x02}, - {value: 0x0739, lo: 0xb3, hi: 0xb3}, - {value: 0x0740, lo: 0xb6, hi: 0xb6}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x11, offset 0x12 - {value: 0x0007, lo: 0x02}, - {value: 0x0747, lo: 0x99, hi: 0x9b}, - {value: 0x075c, lo: 0x9e, hi: 0x9e}, + {value: 0x0007, lo: 0x07}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x0001, lo: 0x8b, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, + {value: 0x4472, lo: 0x9c, hi: 0x9c}, + {value: 0x447a, lo: 0x9d, hi: 0x9d}, + {value: 0x4482, lo: 0x9f, hi: 0x9f}, // Block 0x12, offset 0x13 - {value: 0x0007, lo: 0x03}, - {value: 0x0763, lo: 0x88, hi: 0x88}, - {value: 0x076a, lo: 0x8b, hi: 0x8c}, - {value: 0x0778, lo: 0x9c, hi: 0x9d}, + {value: 0x0000, lo: 0x03}, + {value: 0x44aa, lo: 0xb3, hi: 0xb3}, + {value: 0x44b2, lo: 0xb6, hi: 0xb6}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, // Block 0x13, offset 0x14 - {value: 0x0000, lo: 0x01}, - {value: 0x0786, lo: 0x94, hi: 0x94}, + {value: 0x0008, lo: 0x03}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x448a, lo: 0x99, hi: 0x9b}, + {value: 0x44a2, lo: 0x9e, hi: 0x9e}, // Block 0x14, offset 0x15 - {value: 0x0007, lo: 0x01}, - {value: 0x078d, lo: 0x8a, hi: 0x8c}, + {value: 0x0000, lo: 0x01}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, // Block 0x15, offset 0x16 {value: 0x0000, lo: 0x01}, - {value: 0x07a2, lo: 0x88, hi: 0x88}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, // Block 0x16, offset 0x17 - {value: 0x0007, lo: 0x03}, - {value: 0x07a9, lo: 0x80, hi: 0x80}, - {value: 0x07b0, lo: 0x87, hi: 0x88}, - {value: 0x07be, lo: 0x8a, hi: 0x8b}, + {value: 0x0000, lo: 0x08}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x0016, lo: 0x88, hi: 0x88}, + {value: 0x000f, lo: 0x8b, hi: 0x8b}, + {value: 0x001d, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x96, hi: 0x97}, + {value: 0x44ba, lo: 0x9c, hi: 0x9c}, + {value: 0x44c2, lo: 0x9d, hi: 0x9d}, // Block 0x17, offset 0x18 - {value: 0x0007, lo: 0x01}, - {value: 0x07cf, lo: 0x8a, hi: 0x8c}, + {value: 0x0000, lo: 0x03}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x0024, lo: 0x94, hi: 0x94}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x18, offset 0x19 - {value: 0x0007, lo: 0x03}, - {value: 0x07e4, lo: 0x9a, hi: 0x9a}, - {value: 0x07eb, lo: 0x9c, hi: 0x9d}, - {value: 0x07fc, lo: 0x9e, hi: 0x9e}, + {value: 0x0000, lo: 0x06}, + {value: 0x8800, lo: 0x86, hi: 0x87}, + {value: 0x002b, lo: 0x8a, hi: 0x8a}, + {value: 0x0039, lo: 0x8b, hi: 0x8b}, + {value: 0x0032, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, // Block 0x19, offset 0x1a - {value: 0x0007, lo: 0x09}, - {value: 0x0823, lo: 0x83, hi: 0x83}, - {value: 0x082a, lo: 0x8d, hi: 0x8d}, - {value: 0x0831, lo: 0x92, hi: 0x92}, - {value: 0x0838, lo: 0x97, hi: 0x97}, - {value: 0x083f, lo: 0x9c, hi: 0x9c}, - {value: 0x0846, lo: 0xa9, hi: 0xa9}, - {value: 0x084d, lo: 0xb3, hi: 0xb3}, - {value: 0x0854, lo: 0xb5, hi: 0xb6}, - {value: 0x086c, lo: 0xb8, hi: 0xb8}, + {value: 0x0607, lo: 0x04}, + {value: 0x8800, lo: 0x86, hi: 0x86}, + {value: 0x3dd5, lo: 0x88, hi: 0x88}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8054, lo: 0x95, hi: 0x96}, // Block 0x1a, offset 0x1b - {value: 0x0000, lo: 0x07}, - {value: 0x087d, lo: 0x81, hi: 0x81}, - {value: 0x0884, lo: 0x93, hi: 0x93}, - {value: 0x088b, lo: 0x9d, hi: 0x9d}, - {value: 0x0892, lo: 0xa2, hi: 0xa2}, - {value: 0x0899, lo: 0xa7, hi: 0xa7}, - {value: 0x08a0, lo: 0xac, hi: 0xac}, - {value: 0x08a7, lo: 0xb9, hi: 0xb9}, + {value: 0x0000, lo: 0x02}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, + {value: 0x8800, lo: 0xbf, hi: 0xbf}, // Block 0x1b, offset 0x1c - {value: 0x0000, lo: 0x01}, - {value: 0x08ae, lo: 0xa6, hi: 0xa6}, + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x8600, lo: 0x82, hi: 0x82}, + {value: 0x8800, lo: 0x86, hi: 0x86}, + {value: 0x0047, lo: 0x87, hi: 0x87}, + {value: 0x004e, lo: 0x88, hi: 0x88}, + {value: 0x2e37, lo: 0x8a, hi: 0x8a}, + {value: 0x00c5, lo: 0x8b, hi: 0x8b}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x95, hi: 0x96}, // Block 0x1c, offset 0x1d - {value: 0x0000, lo: 0x08}, - {value: 0x08b9, lo: 0x86, hi: 0x86}, - {value: 0x08c0, lo: 0x88, hi: 0x88}, - {value: 0x08c7, lo: 0x8a, hi: 0x8a}, - {value: 0x08ce, lo: 0x8c, hi: 0x8c}, - {value: 0x08d5, lo: 0x8e, hi: 0x8e}, - {value: 0x08dc, lo: 0x92, hi: 0x92}, - {value: 0x08e3, lo: 0xbb, hi: 0xbb}, - {value: 0x08ea, lo: 0xbd, hi: 0xbd}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x1d, offset 0x1e - {value: 0x0007, lo: 0x02}, - {value: 0x08f1, lo: 0x80, hi: 0x81}, - {value: 0x08ff, lo: 0x83, hi: 0x83}, + {value: 0x0000, lo: 0x06}, + {value: 0x8800, lo: 0x86, hi: 0x87}, + {value: 0x0055, lo: 0x8a, hi: 0x8a}, + {value: 0x0063, lo: 0x8b, hi: 0x8b}, + {value: 0x005c, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, // Block 0x1e, offset 0x1f - {value: 0x0004, lo: 0x0d}, - {value: 0x09ea, lo: 0x80, hi: 0x88}, - {value: 0x0a10, lo: 0x89, hi: 0x89}, - {value: 0x0a16, lo: 0x8a, hi: 0x94}, - {value: 0x0a44, lo: 0x95, hi: 0x95}, - {value: 0x0a4a, lo: 0x96, hi: 0x96}, - {value: 0x0a50, lo: 0x97, hi: 0x97}, - {value: 0x0a56, lo: 0x98, hi: 0x9c}, - {value: 0x0a6c, lo: 0x9d, hi: 0x9d}, - {value: 0x0a72, lo: 0x9e, hi: 0xae}, - {value: 0x0ab8, lo: 0xaf, hi: 0xaf}, - {value: 0x0abe, lo: 0xb0, hi: 0xb8}, - {value: 0x0ae4, lo: 0xb9, hi: 0xb9}, - {value: 0x0aea, lo: 0xba, hi: 0xbf}, + {value: 0x12fd, lo: 0x07}, + {value: 0x8609, lo: 0x8a, hi: 0x8a}, + {value: 0x8600, lo: 0x8f, hi: 0x8f}, + {value: 0x8800, lo: 0x99, hi: 0x99}, + {value: 0x3ddd, lo: 0x9a, hi: 0x9a}, + {value: 0x2e3e, lo: 0x9c, hi: 0x9d}, + {value: 0x006a, lo: 0x9e, hi: 0x9e}, + {value: 0x8600, lo: 0x9f, hi: 0x9f}, // Block 0x1f, offset 0x20 - {value: 0x0004, lo: 0x01}, - {value: 0x142e, lo: 0x80, hi: 0x81}, + {value: 0x0000, lo: 0x02}, + {value: 0x8067, lo: 0xb8, hi: 0xb9}, + {value: 0x8009, lo: 0xba, hi: 0xba}, // Block 0x20, offset 0x21 - {value: 0x0000, lo: 0x03}, - {value: 0x14d6, lo: 0xa6, hi: 0xa6}, - {value: 0x091c, lo: 0xaa, hi: 0xaa}, - {value: 0x0046, lo: 0xab, hi: 0xab}, + {value: 0x0000, lo: 0x01}, + {value: 0x806b, lo: 0x88, hi: 0x8b}, // Block 0x21, offset 0x22 - {value: 0x0006, lo: 0x02}, - {value: 0x159f, lo: 0x9a, hi: 0x9b}, - {value: 0x15ab, lo: 0xae, hi: 0xae}, + {value: 0x0000, lo: 0x01}, + {value: 0x8076, lo: 0xb8, hi: 0xb9}, // Block 0x22, offset 0x23 - {value: 0x0006, lo: 0x01}, - {value: 0x15b1, lo: 0x8d, hi: 0x8f}, + {value: 0x0000, lo: 0x01}, + {value: 0x807a, lo: 0x88, hi: 0x8b}, // Block 0x23, offset 0x24 - {value: 0x0000, lo: 0x05}, - {value: 0x15c3, lo: 0x84, hi: 0x84}, - {value: 0x15c9, lo: 0x89, hi: 0x89}, - {value: 0x15cf, lo: 0x8c, hi: 0x8c}, - {value: 0x15d5, lo: 0xa4, hi: 0xa4}, - {value: 0x15db, lo: 0xa6, hi: 0xa6}, + {value: 0x0000, lo: 0x04}, + {value: 0x80dc, lo: 0x98, hi: 0x99}, + {value: 0x80dc, lo: 0xb5, hi: 0xb5}, + {value: 0x80dc, lo: 0xb7, hi: 0xb7}, + {value: 0x80d8, lo: 0xb9, hi: 0xb9}, // Block 0x24, offset 0x25 - {value: 0x0006, lo: 0x0b}, - {value: 0x1603, lo: 0x81, hi: 0x81}, - {value: 0x1609, lo: 0x84, hi: 0x84}, - {value: 0x160f, lo: 0x87, hi: 0x87}, - {value: 0x1615, lo: 0x89, hi: 0x89}, - {value: 0x161b, lo: 0xa0, hi: 0xa0}, - {value: 0x161f, lo: 0xa2, hi: 0xa2}, - {value: 0x1625, lo: 0xad, hi: 0xae}, - {value: 0x162f, lo: 0xaf, hi: 0xaf}, - {value: 0x1633, lo: 0xb0, hi: 0xb1}, - {value: 0x163f, lo: 0xb4, hi: 0xb5}, - {value: 0x164b, lo: 0xb8, hi: 0xb9}, + {value: 0x0000, lo: 0x0e}, + {value: 0x2757, lo: 0x83, hi: 0x83}, + {value: 0x275e, lo: 0x8d, hi: 0x8d}, + {value: 0x2765, lo: 0x92, hi: 0x92}, + {value: 0x276c, lo: 0x97, hi: 0x97}, + {value: 0x2773, lo: 0x9c, hi: 0x9c}, + {value: 0x2750, lo: 0xa9, hi: 0xa9}, + {value: 0x8081, lo: 0xb1, hi: 0xb1}, + {value: 0x8082, lo: 0xb2, hi: 0xb2}, + {value: 0x4987, lo: 0xb3, hi: 0xb3}, + {value: 0x8084, lo: 0xb4, hi: 0xb4}, + {value: 0x4990, lo: 0xb5, hi: 0xb5}, + {value: 0x44ca, lo: 0xb6, hi: 0xb6}, + {value: 0x44d2, lo: 0xb8, hi: 0xb8}, + {value: 0x8082, lo: 0xba, hi: 0xbd}, // Block 0x25, offset 0x26 - {value: 0x0006, lo: 0x04}, - {value: 0x1657, lo: 0x80, hi: 0x81}, - {value: 0x1663, lo: 0x84, hi: 0x85}, - {value: 0x166f, lo: 0x88, hi: 0x89}, - {value: 0x167b, lo: 0xac, hi: 0xaf}, + {value: 0x0000, lo: 0x0b}, + {value: 0x8082, lo: 0x80, hi: 0x80}, + {value: 0x4999, lo: 0x81, hi: 0x81}, + {value: 0x80e6, lo: 0x82, hi: 0x83}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0x86, hi: 0x87}, + {value: 0x2781, lo: 0x93, hi: 0x93}, + {value: 0x2788, lo: 0x9d, hi: 0x9d}, + {value: 0x278f, lo: 0xa2, hi: 0xa2}, + {value: 0x2796, lo: 0xa7, hi: 0xa7}, + {value: 0x279d, lo: 0xac, hi: 0xac}, + {value: 0x277a, lo: 0xb9, hi: 0xb9}, // Block 0x26, offset 0x27 - {value: 0x0006, lo: 0x02}, - {value: 0x1693, lo: 0xa0, hi: 0xa3}, - {value: 0x16ab, lo: 0xaa, hi: 0xad}, + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0x86, hi: 0x86}, // Block 0x27, offset 0x28 - {value: 0x0004, lo: 0x01}, - {value: 0x16c3, lo: 0xa9, hi: 0xaa}, + {value: 0x0000, lo: 0x05}, + {value: 0x8800, lo: 0xa5, hi: 0xa5}, + {value: 0x0071, lo: 0xa6, hi: 0xa6}, + {value: 0x8600, lo: 0xae, hi: 0xae}, + {value: 0x8007, lo: 0xb7, hi: 0xb7}, + {value: 0x8009, lo: 0xb9, hi: 0xba}, // Block 0x28, offset 0x29 {value: 0x0000, lo: 0x01}, - {value: 0x1814, lo: 0x9c, hi: 0x9c}, + {value: 0x80dc, lo: 0x8d, hi: 0x8d}, // Block 0x29, offset 0x2a - {value: 0x0000, lo: 0x0c}, - {value: 0x1c39, lo: 0x94, hi: 0x94}, - {value: 0x1c4a, lo: 0x9e, hi: 0x9e}, - {value: 0x1c58, lo: 0xac, hi: 0xac}, - {value: 0x1c5f, lo: 0xae, hi: 0xae}, - {value: 0x1c66, lo: 0xb0, hi: 0xb0}, - {value: 0x1c6d, lo: 0xb2, hi: 0xb2}, - {value: 0x1c74, lo: 0xb4, hi: 0xb4}, - {value: 0x1c7b, lo: 0xb6, hi: 0xb6}, - {value: 0x1c82, lo: 0xb8, hi: 0xb8}, - {value: 0x1c89, lo: 0xba, hi: 0xba}, - {value: 0x1c90, lo: 0xbc, hi: 0xbc}, - {value: 0x1c97, lo: 0xbe, hi: 0xbe}, + {value: 0x0000, lo: 0x01}, + {value: 0x8800, lo: 0x80, hi: 0x92}, // Block 0x2a, offset 0x2b - {value: 0x0007, lo: 0x0d}, - {value: 0x1c9e, lo: 0x80, hi: 0x80}, - {value: 0x1ca5, lo: 0x82, hi: 0x82}, - {value: 0x1cac, lo: 0x85, hi: 0x85}, - {value: 0x1cb3, lo: 0x87, hi: 0x87}, - {value: 0x1cba, lo: 0x89, hi: 0x89}, - {value: 0x1cc1, lo: 0x90, hi: 0x91}, - {value: 0x1ccf, lo: 0x93, hi: 0x94}, - {value: 0x1cdd, lo: 0x96, hi: 0x97}, - {value: 0x1ceb, lo: 0x99, hi: 0x9a}, - {value: 0x1cf9, lo: 0x9c, hi: 0x9d}, - {value: 0x1d07, lo: 0xb4, hi: 0xb4}, - {value: 0x1d0e, lo: 0xb7, hi: 0xba}, - {value: 0x1d2a, lo: 0xbe, hi: 0xbe}, + {value: 0x0000, lo: 0x01}, + {value: 0x8e00, lo: 0xa1, hi: 0xb5}, // Block 0x2b, offset 0x2c - {value: 0x0004, lo: 0x0a}, - {value: 0x2a81, lo: 0x80, hi: 0x81}, - {value: 0x1a9e, lo: 0x82, hi: 0x82}, - {value: 0x2a89, lo: 0x83, hi: 0x86}, - {value: 0x1b76, lo: 0x87, hi: 0x87}, - {value: 0x1b76, lo: 0x88, hi: 0x88}, - {value: 0x2a99, lo: 0x89, hi: 0x89}, - {value: 0x1abe, lo: 0x8a, hi: 0x8a}, - {value: 0x2a9d, lo: 0x8b, hi: 0xb3}, - {value: 0x1a16, lo: 0xb4, hi: 0xb4}, - {value: 0x2b41, lo: 0xb5, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0xa8, hi: 0xbf}, // Block 0x2c, offset 0x2d - {value: 0x0004, lo: 0x06}, - {value: 0x1b3a, lo: 0x80, hi: 0x80}, - {value: 0x2b6d, lo: 0x81, hi: 0x9b}, - {value: 0x2ac1, lo: 0x9c, hi: 0x9c}, - {value: 0x2bd9, lo: 0x9d, hi: 0xb0}, - {value: 0x1aa6, lo: 0xb1, hi: 0xb1}, - {value: 0x2c29, lo: 0xb2, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0x80, hi: 0x82}, // Block 0x2d, offset 0x2e - {value: 0x0004, lo: 0x0a}, - {value: 0x2c61, lo: 0x80, hi: 0x80}, - {value: 0x18ba, lo: 0x81, hi: 0x81}, - {value: 0x2c65, lo: 0x82, hi: 0x89}, - {value: 0x186e, lo: 0x8a, hi: 0x8a}, - {value: 0x2c85, lo: 0x8b, hi: 0xa0}, - {value: 0x2c21, lo: 0xa1, hi: 0xa1}, - {value: 0x2cdd, lo: 0xa2, hi: 0xa9}, - {value: 0x2be1, lo: 0xaa, hi: 0xaa}, - {value: 0x2cfd, lo: 0xab, hi: 0xbe}, - {value: 0x2ac1, lo: 0xbf, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x9d, hi: 0x9f}, // Block 0x2e, offset 0x2f - {value: 0x0004, lo: 0x0b}, - {value: 0x2d4d, lo: 0x80, hi: 0x83}, - {value: 0x1b72, lo: 0x84, hi: 0x84}, - {value: 0x2d5d, lo: 0x85, hi: 0x90}, - {value: 0x2173, lo: 0x91, hi: 0x91}, - {value: 0x2d8d, lo: 0x92, hi: 0x9a}, - {value: 0x2be9, lo: 0x9b, hi: 0x9b}, - {value: 0x2db1, lo: 0x9c, hi: 0xa8}, - {value: 0x1aba, lo: 0xa9, hi: 0xa9}, - {value: 0x2de5, lo: 0xaa, hi: 0xb6}, - {value: 0x19f6, lo: 0xb7, hi: 0xb7}, - {value: 0x2e19, lo: 0xb8, hi: 0xbf}, + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x94, hi: 0x94}, + {value: 0x8009, lo: 0xb4, hi: 0xb4}, // Block 0x2f, offset 0x30 - {value: 0x0004, lo: 0x10}, - {value: 0x2e39, lo: 0x80, hi: 0x87}, - {value: 0x1a62, lo: 0x88, hi: 0x88}, - {value: 0x2e59, lo: 0x89, hi: 0x89}, - {value: 0x1a6e, lo: 0x8a, hi: 0x8a}, - {value: 0x2e5d, lo: 0x8b, hi: 0x8d}, - {value: 0x2e69, lo: 0x90, hi: 0x90}, - {value: 0x2e6d, lo: 0x92, hi: 0x92}, - {value: 0x2e71, lo: 0x95, hi: 0x9d}, - {value: 0x1a12, lo: 0x9e, hi: 0x9e}, - {value: 0x2e95, lo: 0xa0, hi: 0xa0}, - {value: 0x2e99, lo: 0xa2, hi: 0xa2}, - {value: 0x2e9d, lo: 0xa5, hi: 0xa6}, - {value: 0x2ea5, lo: 0xaa, hi: 0xad}, - {value: 0x2eb5, lo: 0xb0, hi: 0xbb}, - {value: 0x18d6, lo: 0xbc, hi: 0xbc}, - {value: 0x2ee5, lo: 0xbd, hi: 0xbf}, + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x92, hi: 0x92}, + {value: 0x80e6, lo: 0x9d, hi: 0x9d}, // Block 0x30, offset 0x31 - {value: 0x0004, lo: 0x10}, - {value: 0x2ef1, lo: 0x80, hi: 0x8b}, - {value: 0x2187, lo: 0x8c, hi: 0x8c}, - {value: 0x2f21, lo: 0x8d, hi: 0x90}, - {value: 0x2197, lo: 0x91, hi: 0x91}, - {value: 0x2f31, lo: 0x92, hi: 0x96}, - {value: 0x2cb1, lo: 0x97, hi: 0x97}, - {value: 0x2f45, lo: 0x98, hi: 0x9d}, - {value: 0x2f59, lo: 0x9e, hi: 0xa6}, - {value: 0x2e9d, lo: 0xa7, hi: 0xa7}, - {value: 0x2f7d, lo: 0xa8, hi: 0xac}, - {value: 0x2f92, lo: 0xad, hi: 0xad}, - {value: 0x2f96, lo: 0xb0, hi: 0xb7}, - {value: 0x2ecd, lo: 0xb8, hi: 0xb8}, - {value: 0x2fb6, lo: 0xb9, hi: 0xbb}, - {value: 0x2e69, lo: 0xbc, hi: 0xbc}, - {value: 0x2fc2, lo: 0xbd, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e4, lo: 0xa9, hi: 0xa9}, // Block 0x31, offset 0x32 - {value: 0x0005, lo: 0x07}, - {value: 0x3105, lo: 0x9d, hi: 0x9d}, - {value: 0x310a, lo: 0x9f, hi: 0x9f}, - {value: 0x3124, lo: 0xaa, hi: 0xac}, - {value: 0x3135, lo: 0xad, hi: 0xad}, - {value: 0x313c, lo: 0xae, hi: 0xb6}, - {value: 0x3169, lo: 0xb8, hi: 0xbc}, - {value: 0x3182, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0x02}, + {value: 0x80de, lo: 0xb9, hi: 0xba}, + {value: 0x80dc, lo: 0xbb, hi: 0xbb}, // Block 0x32, offset 0x33 - {value: 0x0005, lo: 0x03}, - {value: 0x3187, lo: 0x80, hi: 0x81}, - {value: 0x3191, lo: 0x83, hi: 0x84}, - {value: 0x319b, lo: 0x86, hi: 0x8e}, + {value: 0x0000, lo: 0x02}, + {value: 0x80e6, lo: 0x97, hi: 0x97}, + {value: 0x80dc, lo: 0x98, hi: 0x98}, // Block 0x33, offset 0x34 {value: 0x0000, lo: 0x03}, - {value: 0x3a73, lo: 0x9a, hi: 0x9a}, - {value: 0x3a7c, lo: 0x9c, hi: 0x9c}, - {value: 0x3a85, lo: 0xab, hi: 0xab}, + {value: 0x8009, lo: 0xa0, hi: 0xa0}, + {value: 0x80e6, lo: 0xb5, hi: 0xbc}, + {value: 0x80dc, lo: 0xbf, hi: 0xbf}, // Block 0x34, offset 0x35 - {value: 0x000d, lo: 0x03}, - {value: 0x3a8e, lo: 0x9e, hi: 0x9e}, - {value: 0x3a97, lo: 0x9f, hi: 0x9f}, - {value: 0x3aa0, lo: 0xa0, hi: 0xa4}, + {value: 0x0000, lo: 0x08}, + {value: 0x00b0, lo: 0x80, hi: 0x80}, + {value: 0x00b7, lo: 0x81, hi: 0x81}, + {value: 0x8800, lo: 0x82, hi: 0x82}, + {value: 0x00be, lo: 0x83, hi: 0x83}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0xab, hi: 0xab}, + {value: 0x80dc, lo: 0xac, hi: 0xac}, + {value: 0x80e6, lo: 0xad, hi: 0xb3}, // Block 0x35, offset 0x36 - {value: 0x0009, lo: 0x03}, - {value: 0x3ae1, lo: 0xbb, hi: 0xbd}, - {value: 0x3b00, lo: 0xbe, hi: 0xbe}, - {value: 0x3b0d, lo: 0xbf, hi: 0xbf}, - // Block 0x36, offset 0x37 {value: 0x0000, lo: 0x01}, - {value: 0x3b1a, lo: 0x80, hi: 0x80}, + {value: 0x8009, lo: 0xaa, hi: 0xaa}, + // Block 0x36, offset 0x37 + {value: 0x0000, lo: 0x02}, + {value: 0x8007, lo: 0xa6, hi: 0xa6}, + {value: 0x8009, lo: 0xb2, hi: 0xb3}, // Block 0x37, offset 0x38 - {value: 0x0004, lo: 0x0d}, - {value: 0x4463, lo: 0x80, hi: 0x81}, - {value: 0x446c, lo: 0x82, hi: 0x89}, - {value: 0x30a2, lo: 0x8a, hi: 0x8a}, - {value: 0x448d, lo: 0x8b, hi: 0x90}, - {value: 0x44a6, lo: 0x91, hi: 0x92}, - {value: 0x44af, lo: 0x93, hi: 0x93}, - {value: 0x44b4, lo: 0x94, hi: 0x94}, - {value: 0x1b42, lo: 0x95, hi: 0x95}, - {value: 0x44b9, lo: 0x96, hi: 0x96}, - {value: 0x1b52, lo: 0x97, hi: 0x97}, - {value: 0x44bd, lo: 0x98, hi: 0x9b}, - {value: 0x1b66, lo: 0x9c, hi: 0x9c}, - {value: 0x44cd, lo: 0x9d, hi: 0x9d}, + {value: 0x0000, lo: 0x01}, + {value: 0x8007, lo: 0xb7, hi: 0xb7}, + // Block 0x38, offset 0x39 + {value: 0x0000, lo: 0x08}, + {value: 0x80e6, lo: 0x90, hi: 0x92}, + {value: 0x8001, lo: 0x94, hi: 0x94}, + {value: 0x80dc, lo: 0x95, hi: 0x99}, + {value: 0x80e6, lo: 0x9a, hi: 0x9b}, + {value: 0x80dc, lo: 0x9c, hi: 0x9f}, + {value: 0x80e6, lo: 0xa0, hi: 0xa0}, + {value: 0x8001, lo: 0xa2, hi: 0xa8}, + {value: 0x80dc, lo: 0xad, hi: 0xad}, + // Block 0x39, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x80e6, lo: 0x80, hi: 0x81}, + {value: 0x80dc, lo: 0x82, hi: 0x82}, + {value: 0x80e6, lo: 0x83, hi: 0x89}, + {value: 0x80dc, lo: 0x8a, hi: 0x8a}, + {value: 0x80e6, lo: 0x8b, hi: 0x8c}, + {value: 0x80ea, lo: 0x8d, hi: 0x8d}, + {value: 0x80d6, lo: 0x8e, hi: 0x8e}, + {value: 0x80dc, lo: 0x8f, hi: 0x8f}, + {value: 0x80ca, lo: 0x90, hi: 0x90}, + {value: 0x80e6, lo: 0x91, hi: 0xa6}, + {value: 0x80e9, lo: 0xbc, hi: 0xbc}, + {value: 0x80dc, lo: 0xbd, hi: 0xbd}, + {value: 0x80e6, lo: 0xbe, hi: 0xbe}, + {value: 0x80dc, lo: 0xbf, hi: 0xbf}, + // Block 0x3a, offset 0x3b + {value: 0x0004, lo: 0x01}, + {value: 0x0971, lo: 0x80, hi: 0x81}, + // Block 0x3b, offset 0x3c + {value: 0x0000, lo: 0x0d}, + {value: 0x80e6, lo: 0x90, hi: 0x91}, + {value: 0x8001, lo: 0x92, hi: 0x93}, + {value: 0x80e6, lo: 0x94, hi: 0x97}, + {value: 0x8001, lo: 0x98, hi: 0x9a}, + {value: 0x80e6, lo: 0x9b, hi: 0x9c}, + {value: 0x80e6, lo: 0xa1, hi: 0xa1}, + {value: 0x8001, lo: 0xa5, hi: 0xa6}, + {value: 0x80e6, lo: 0xa7, hi: 0xa7}, + {value: 0x80dc, lo: 0xa8, hi: 0xa8}, + {value: 0x80e6, lo: 0xa9, hi: 0xa9}, + {value: 0x8001, lo: 0xaa, hi: 0xab}, + {value: 0x80dc, lo: 0xac, hi: 0xaf}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, + // Block 0x3c, offset 0x3d + {value: 0x4099, lo: 0x02}, + {value: 0x0475, lo: 0xa6, hi: 0xa6}, + {value: 0x0125, lo: 0xaa, hi: 0xab}, + // Block 0x3d, offset 0x3e + {value: 0x0007, lo: 0x05}, + {value: 0x8800, lo: 0x90, hi: 0x90}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x8800, lo: 0x94, hi: 0x94}, + {value: 0x3a9e, lo: 0x9a, hi: 0x9b}, + {value: 0x3aac, lo: 0xae, hi: 0xae}, + // Block 0x3e, offset 0x3f + {value: 0x000e, lo: 0x05}, + {value: 0x3ab3, lo: 0x8d, hi: 0x8e}, + {value: 0x3aba, lo: 0x8f, hi: 0x8f}, + {value: 0x8800, lo: 0x90, hi: 0x90}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x8800, lo: 0x94, hi: 0x94}, + // Block 0x3f, offset 0x40 + {value: 0x4d23, lo: 0x0a}, + {value: 0x8800, lo: 0x83, hi: 0x83}, + {value: 0x3ac8, lo: 0x84, hi: 0x84}, + {value: 0x8800, lo: 0x88, hi: 0x88}, + {value: 0x3acf, lo: 0x89, hi: 0x89}, + {value: 0x8800, lo: 0x8b, hi: 0x8b}, + {value: 0x3ad6, lo: 0x8c, hi: 0x8c}, + {value: 0x8800, lo: 0xa3, hi: 0xa3}, + {value: 0x3add, lo: 0xa4, hi: 0xa5}, + {value: 0x3ae4, lo: 0xa6, hi: 0xa6}, + {value: 0x8800, lo: 0xbc, hi: 0xbc}, + // Block 0x40, offset 0x41 + {value: 0x0007, lo: 0x03}, + {value: 0x3b4d, lo: 0xa0, hi: 0xa1}, + {value: 0x3b77, lo: 0xa2, hi: 0xa3}, + {value: 0x3ba1, lo: 0xaa, hi: 0xad}, + // Block 0x41, offset 0x42 + {value: 0x0004, lo: 0x01}, + {value: 0x09c9, lo: 0xa9, hi: 0xaa}, + // Block 0x42, offset 0x43 + {value: 0x0000, lo: 0x01}, + {value: 0x43db, lo: 0x9c, hi: 0x9c}, + // Block 0x43, offset 0x44 + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xaf, hi: 0xb1}, + // Block 0x44, offset 0x45 + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0xbf, hi: 0xbf}, + // Block 0x45, offset 0x46 + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xa0, hi: 0xbf}, + // Block 0x46, offset 0x47 + {value: 0x0000, lo: 0x05}, + {value: 0x80da, lo: 0xaa, hi: 0xaa}, + {value: 0x80e4, lo: 0xab, hi: 0xab}, + {value: 0x80e8, lo: 0xac, hi: 0xac}, + {value: 0x80de, lo: 0xad, hi: 0xad}, + {value: 0x80e0, lo: 0xae, hi: 0xaf}, + // Block 0x47, offset 0x48 + {value: 0x0000, lo: 0x02}, + {value: 0x80e6, lo: 0xaf, hi: 0xaf}, + {value: 0x80e6, lo: 0xbc, hi: 0xbd}, + // Block 0x48, offset 0x49 + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xb0, hi: 0xb1}, + // Block 0x49, offset 0x4a + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x86, hi: 0x86}, + // Block 0x4a, offset 0x4b + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0xa0, hi: 0xb1}, + // Block 0x4b, offset 0x4c + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0xab, hi: 0xad}, + // Block 0x4c, offset 0x4d + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x93, hi: 0x93}, + // Block 0x4d, offset 0x4e + {value: 0x0000, lo: 0x01}, + {value: 0x8007, lo: 0xb3, hi: 0xb3}, + // Block 0x4e, offset 0x4f + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x80, hi: 0x80}, + // Block 0x4f, offset 0x50 + {value: 0x0000, lo: 0x05}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, + {value: 0x80e6, lo: 0xb2, hi: 0xb3}, + {value: 0x80dc, lo: 0xb4, hi: 0xb4}, + {value: 0x80e6, lo: 0xb7, hi: 0xb8}, + {value: 0x80e6, lo: 0xbe, hi: 0xbf}, + // Block 0x50, offset 0x51 + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x81, hi: 0x81}, + // Block 0x51, offset 0x52 + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0xad, hi: 0xad}, + // Block 0x52, offset 0x53 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x80, hi: 0xbf}, + // Block 0x53, offset 0x54 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x80, hi: 0xa3}, + // Block 0x54, offset 0x55 + {value: 0x0006, lo: 0x0d}, + {value: 0x428e, lo: 0x9d, hi: 0x9d}, + {value: 0x801a, lo: 0x9e, hi: 0x9e}, + {value: 0x4300, lo: 0x9f, hi: 0x9f}, + {value: 0x42ee, lo: 0xaa, hi: 0xab}, + {value: 0x43f2, lo: 0xac, hi: 0xac}, + {value: 0x43fa, lo: 0xad, hi: 0xad}, + {value: 0x4246, lo: 0xae, hi: 0xb1}, + {value: 0x4264, lo: 0xb2, hi: 0xb4}, + {value: 0x427c, lo: 0xb5, hi: 0xb6}, + {value: 0x4288, lo: 0xb8, hi: 0xb8}, + {value: 0x4294, lo: 0xb9, hi: 0xbb}, + {value: 0x42ac, lo: 0xbc, hi: 0xbc}, + {value: 0x42b2, lo: 0xbe, hi: 0xbe}, + // Block 0x55, offset 0x56 + {value: 0x0006, lo: 0x08}, + {value: 0x42b8, lo: 0x80, hi: 0x81}, + {value: 0x42c4, lo: 0x83, hi: 0x84}, + {value: 0x42d6, lo: 0x86, hi: 0x89}, + {value: 0x42fa, lo: 0x8a, hi: 0x8a}, + {value: 0x4276, lo: 0x8b, hi: 0x8b}, + {value: 0x425e, lo: 0x8c, hi: 0x8c}, + {value: 0x42a6, lo: 0x8d, hi: 0x8d}, + {value: 0x42d0, lo: 0x8e, hi: 0x8e}, + // Block 0x56, offset 0x57 + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xa0, hi: 0xa6}, + // Block 0x57, offset 0x58 + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0xbd, hi: 0xbd}, + // Block 0x58, offset 0x59 + {value: 0x00db, lo: 0x05}, + {value: 0x80dc, lo: 0x8d, hi: 0x8d}, + {value: 0x80e6, lo: 0x8f, hi: 0x8f}, + {value: 0x80e6, lo: 0xb8, hi: 0xb8}, + {value: 0x8001, lo: 0xb9, hi: 0xba}, + {value: 0x8009, lo: 0xbf, hi: 0xbf}, + // Block 0x59, offset 0x5a + {value: 0x05fe, lo: 0x07}, + {value: 0x8800, lo: 0x99, hi: 0x99}, + {value: 0x411d, lo: 0x9a, hi: 0x9a}, + {value: 0x8800, lo: 0x9b, hi: 0x9b}, + {value: 0x4127, lo: 0x9c, hi: 0x9c}, + {value: 0x8800, lo: 0xa5, hi: 0xa5}, + {value: 0x4131, lo: 0xab, hi: 0xab}, + {value: 0x8009, lo: 0xb9, hi: 0xba}, + // Block 0x5a, offset 0x5b + {value: 0x0000, lo: 0x0c}, + {value: 0x44e2, lo: 0x9e, hi: 0x9e}, + {value: 0x44ec, lo: 0x9f, hi: 0x9f}, + {value: 0x4555, lo: 0xa0, hi: 0xa0}, + {value: 0x4563, lo: 0xa1, hi: 0xa1}, + {value: 0x4571, lo: 0xa2, hi: 0xa2}, + {value: 0x457f, lo: 0xa3, hi: 0xa3}, + {value: 0x458d, lo: 0xa4, hi: 0xa4}, + {value: 0x80d8, lo: 0xa5, hi: 0xa6}, + {value: 0x8001, lo: 0xa7, hi: 0xa9}, + {value: 0x80e2, lo: 0xad, hi: 0xad}, + {value: 0x80d8, lo: 0xae, hi: 0xb2}, + {value: 0x80dc, lo: 0xbb, hi: 0xbf}, + // Block 0x5b, offset 0x5c + {value: 0x0000, lo: 0x09}, + {value: 0x80dc, lo: 0x80, hi: 0x82}, + {value: 0x80e6, lo: 0x85, hi: 0x89}, + {value: 0x80dc, lo: 0x8a, hi: 0x8b}, + {value: 0x80e6, lo: 0xaa, hi: 0xad}, + {value: 0x44f6, lo: 0xbb, hi: 0xbb}, + {value: 0x4500, lo: 0xbc, hi: 0xbc}, + {value: 0x459b, lo: 0xbd, hi: 0xbd}, + {value: 0x45b7, lo: 0xbe, hi: 0xbe}, + {value: 0x45a9, lo: 0xbf, hi: 0xbf}, + // Block 0x5c, offset 0x5d + {value: 0x0000, lo: 0x01}, + {value: 0x45c5, lo: 0x80, hi: 0x80}, + // Block 0x5d, offset 0x5e + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x82, hi: 0x84}, } -// nfcDecompLookup: 832 bytes +// nfcLookup: 1088 bytes // Block 0 is the null block. -var nfcDecompLookup = [832]uint8{ +var nfcLookup = [1088]uint8{ // Block 0x0, offset 0x0 // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x0c3: 0x16, 0x0c4: 0x17, 0x0c5: 0x18, 0x0c6: 0x19, 0x0c7: 0x03, - 0x0c8: 0x1a, 0x0cd: 0x1b, 0x0ce: 0x1c, 0x0cf: 0x1d, - 0x0d0: 0x1e, 0x0d1: 0x1f, 0x0d3: 0x20, - 0x0d8: 0x21, 0x0db: 0x22, + 0x0c2: 0x2e, 0x0c3: 0x03, 0x0c4: 0x04, 0x0c5: 0x05, 0x0c6: 0x2f, 0x0c7: 0x06, + 0x0c8: 0x07, 0x0ca: 0x30, 0x0cc: 0x08, 0x0cd: 0x09, 0x0ce: 0x0a, 0x0cf: 0x31, + 0x0d0: 0x0b, 0x0d1: 0x32, 0x0d2: 0x33, 0x0d3: 0x0c, 0x0d6: 0x0d, 0x0d7: 0x34, + 0x0d8: 0x35, 0x0d9: 0x0e, 0x0db: 0x36, 0x0dc: 0x37, 0x0dd: 0x38, 0x0df: 0x39, 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, - 0x0ef: 0x08, - 0x0f0: 0x0c, + 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, + 0x0f0: 0x10, // Block 0x4, offset 0x100 - 0x124: 0x23, 0x125: 0x24, 0x127: 0x25, - 0x128: 0x26, 0x129: 0x27, 0x12d: 0x28, 0x12e: 0x29, 0x12f: 0x2a, - 0x131: 0x2b, 0x133: 0x2c, 0x135: 0x2d, 0x137: 0x2e, - 0x13d: 0x2f, 0x13e: 0x30, + 0x120: 0x3a, 0x121: 0x3b, 0x124: 0x3c, 0x125: 0x3d, 0x126: 0x3e, 0x127: 0x3f, + 0x128: 0x40, 0x129: 0x41, 0x12a: 0x42, 0x12b: 0x43, 0x12c: 0x3e, 0x12d: 0x44, 0x12e: 0x45, 0x12f: 0x46, + 0x131: 0x47, 0x132: 0x48, 0x133: 0x49, 0x134: 0x4a, 0x135: 0x4b, 0x137: 0x4c, + 0x138: 0x4d, 0x139: 0x4e, 0x13a: 0x4f, 0x13b: 0x50, 0x13c: 0x51, 0x13d: 0x52, 0x13e: 0x53, 0x13f: 0x54, // Block 0x5, offset 0x140 - 0x140: 0x31, - 0x16c: 0x32, 0x16d: 0x33, - 0x178: 0x34, 0x179: 0x04, 0x17a: 0x05, 0x17b: 0x06, 0x17c: 0x07, 0x17d: 0x08, 0x17e: 0x09, 0x17f: 0x0a, + 0x140: 0x55, 0x142: 0x56, 0x144: 0x57, 0x145: 0x58, 0x146: 0x59, 0x147: 0x5a, + 0x14d: 0x5b, + 0x15c: 0x5c, 0x15f: 0x5d, + 0x162: 0x5e, 0x164: 0x5f, + 0x168: 0x60, 0x169: 0x61, 0x16c: 0x0f, 0x16d: 0x62, 0x16e: 0x63, 0x16f: 0x64, + 0x170: 0x65, 0x173: 0x66, 0x177: 0x67, + 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17, // Block 0x6, offset 0x180 - 0x180: 0x35, 0x184: 0x36, 0x186: 0x37, 0x187: 0x38, - 0x188: 0x39, 0x189: 0x3a, 0x18a: 0x3b, 0x18b: 0x3c, 0x18c: 0x3d, - 0x1ab: 0x3e, + 0x180: 0x68, 0x183: 0x69, 0x184: 0x6a, 0x186: 0x6b, 0x187: 0x6c, + 0x188: 0x6d, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x6e, 0x18c: 0x6f, + 0x1ab: 0x70, + 0x1b3: 0x71, 0x1b5: 0x72, 0x1b7: 0x73, // Block 0x7, offset 0x1c0 - 0x1c1: 0x0b, 0x1c2: 0x3f, 0x1c3: 0x40, + 0x1c0: 0x74, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, // Block 0x8, offset 0x200 - 0x224: 0x41, 0x225: 0x42, 0x226: 0x43, 0x227: 0x44, - 0x228: 0x45, 0x229: 0x46, 0x22a: 0x0c, 0x22b: 0x0d, 0x22c: 0x47, 0x22d: 0x48, + 0x219: 0x75, 0x21b: 0x76, + 0x220: 0x77, 0x223: 0x78, 0x224: 0x79, 0x225: 0x7a, 0x226: 0x7b, 0x227: 0x7c, + 0x22a: 0x7d, 0x22b: 0x7e, 0x22f: 0x7f, + 0x230: 0x80, 0x231: 0x80, 0x232: 0x80, 0x233: 0x80, 0x234: 0x80, 0x235: 0x80, 0x236: 0x80, 0x237: 0x80, + 0x238: 0x80, 0x239: 0x80, 0x23a: 0x80, 0x23b: 0x80, 0x23c: 0x80, 0x23d: 0x80, 0x23e: 0x80, 0x23f: 0x80, // Block 0x9, offset 0x240 - 0x242: 0x49, + 0x240: 0x80, 0x241: 0x80, 0x242: 0x80, 0x243: 0x80, 0x244: 0x80, 0x245: 0x80, 0x246: 0x80, 0x247: 0x80, + 0x248: 0x80, 0x249: 0x80, 0x24a: 0x80, 0x24b: 0x80, 0x24c: 0x80, 0x24d: 0x80, 0x24e: 0x80, 0x24f: 0x80, + 0x250: 0x80, 0x251: 0x80, 0x252: 0x80, 0x253: 0x80, 0x254: 0x80, 0x255: 0x80, 0x256: 0x80, 0x257: 0x80, + 0x258: 0x80, 0x259: 0x80, 0x25a: 0x80, 0x25b: 0x80, 0x25c: 0x80, 0x25d: 0x80, 0x25e: 0x80, 0x25f: 0x80, + 0x260: 0x80, 0x261: 0x80, 0x262: 0x80, 0x263: 0x80, 0x264: 0x80, 0x265: 0x80, 0x266: 0x80, 0x267: 0x80, + 0x268: 0x80, 0x269: 0x80, 0x26a: 0x80, 0x26b: 0x80, 0x26c: 0x80, 0x26d: 0x80, 0x26e: 0x80, 0x26f: 0x80, + 0x270: 0x80, 0x271: 0x80, 0x272: 0x80, 0x273: 0x80, 0x274: 0x80, 0x275: 0x80, 0x276: 0x80, 0x277: 0x80, + 0x278: 0x80, 0x279: 0x80, 0x27a: 0x80, 0x27b: 0x80, 0x27c: 0x80, 0x27d: 0x80, 0x27e: 0x80, 0x27f: 0x80, // Block 0xa, offset 0x280 - 0x285: 0x4a, 0x286: 0x4b, 0x287: 0x4c, + 0x280: 0x80, 0x281: 0x80, 0x282: 0x80, 0x283: 0x80, 0x284: 0x80, 0x285: 0x80, 0x286: 0x80, 0x287: 0x80, + 0x288: 0x80, 0x289: 0x80, 0x28a: 0x80, 0x28b: 0x80, 0x28c: 0x80, 0x28d: 0x80, 0x28e: 0x80, 0x28f: 0x80, + 0x290: 0x80, 0x291: 0x80, 0x292: 0x80, 0x293: 0x80, 0x294: 0x80, 0x295: 0x80, 0x296: 0x80, 0x297: 0x80, + 0x298: 0x80, 0x299: 0x80, 0x29a: 0x80, 0x29b: 0x80, 0x29c: 0x80, 0x29d: 0x80, 0x29e: 0x81, // Block 0xb, offset 0x2c0 - 0x2e0: 0x0e, 0x2e1: 0x0f, 0x2e2: 0x10, 0x2e3: 0x11, 0x2e4: 0x12, 0x2e5: 0x13, 0x2e6: 0x14, 0x2e7: 0x15, - 0x2e8: 0x4d, + 0x2e4: 0x1d, 0x2e5: 0x1e, 0x2e6: 0x1f, 0x2e7: 0x20, + 0x2e8: 0x21, 0x2e9: 0x22, 0x2ea: 0x23, 0x2eb: 0x24, 0x2ec: 0x82, 0x2ed: 0x83, + 0x2f8: 0x84, // Block 0xc, offset 0x300 - 0x311: 0x09, - 0x31d: 0x0a, - 0x32f: 0x0b, + 0x307: 0x85, + 0x328: 0x86, + // Block 0xd, offset 0x340 + 0x341: 0x77, 0x342: 0x87, + // Block 0xe, offset 0x380 + 0x385: 0x88, 0x386: 0x89, 0x387: 0x8a, + 0x389: 0x8b, + // Block 0xf, offset 0x3c0 + 0x3e0: 0x25, 0x3e1: 0x26, 0x3e2: 0x27, 0x3e3: 0x28, 0x3e4: 0x29, 0x3e5: 0x2a, 0x3e6: 0x2b, 0x3e7: 0x2c, + 0x3e8: 0x2d, + // Block 0x10, offset 0x400 + 0x410: 0x0c, 0x411: 0x0d, + 0x41d: 0x0e, + 0x42f: 0x0f, } -var nfcDecompTrie = trie{nfcDecompLookup[:], nfcDecompValues[:], nfcDecompSparseValues[:], nfcDecompSparseOffset[:], 22} +var nfcTrie = trie{nfcLookup[:], nfcValues[:], nfcSparseValues[:], nfcSparseOffset[:], 46} -// nfkcDecompValues: 4224 entries, 8448 bytes +// nfkcValues: 5568 entries, 11136 bytes // Block 2 is the null block. -var nfkcDecompValues = [4224]uint16{ +var nfkcValues = [5568]uint16{ // Block 0x0, offset 0x0 + 0x003c: 0x8800, 0x003d: 0x8800, 0x003e: 0x8800, // Block 0x1, offset 0x40 + 0x0041: 0x8800, 0x0042: 0x8800, 0x0043: 0x8800, 0x0044: 0x8800, 0x0045: 0x8800, + 0x0046: 0x8800, 0x0047: 0x8800, 0x0048: 0x8800, 0x0049: 0x8800, 0x004a: 0x8800, 0x004b: 0x8800, + 0x004c: 0x8800, 0x004d: 0x8800, 0x004e: 0x8800, 0x004f: 0x8800, 0x0050: 0x8800, + 0x0052: 0x8800, 0x0053: 0x8800, 0x0054: 0x8800, 0x0055: 0x8800, 0x0056: 0x8800, 0x0057: 0x8800, + 0x0058: 0x8800, 0x0059: 0x8800, 0x005a: 0x8800, + 0x0061: 0x8800, 0x0062: 0x8800, 0x0063: 0x8800, + 0x0064: 0x8800, 0x0065: 0x8800, 0x0066: 0x8800, 0x0067: 0x8800, 0x0068: 0x8800, 0x0069: 0x8800, + 0x006a: 0x8800, 0x006b: 0x8800, 0x006c: 0x8800, 0x006d: 0x8800, 0x006e: 0x8800, 0x006f: 0x8800, + 0x0070: 0x8800, 0x0072: 0x8800, 0x0073: 0x8800, 0x0074: 0x8800, 0x0075: 0x8800, + 0x0076: 0x8800, 0x0077: 0x8800, 0x0078: 0x8800, 0x0079: 0x8800, 0x007a: 0x8800, // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x00c4: 0x02da, 0x00c5: 0x02df, - 0x00c6: 0x02e4, 0x00c7: 0x02e9, 0x00c8: 0x02ec, 0x00c9: 0x02ef, 0x00ca: 0x02f2, 0x00cb: 0x02f5, - 0x00cc: 0x02f8, 0x00cd: 0x02fb, 0x00ce: 0x02ff, 0x00cf: 0x0303, 0x00d0: 0x0307, 0x00d1: 0x030b, - 0x00d2: 0x030f, 0x00d3: 0x0313, 0x00d4: 0x0317, 0x00d5: 0x031b, 0x00d6: 0x0321, 0x00d7: 0x0327, - 0x00d8: 0x032d, 0x00d9: 0x0333, 0x00da: 0x0339, 0x00db: 0x033f, 0x00dc: 0x0345, - 0x00de: 0x034b, 0x00df: 0x0351, 0x00e0: 0x0357, 0x00e1: 0x035d, 0x00e2: 0x0363, 0x00e3: 0x0368, - 0x00e6: 0x036d, 0x00e7: 0x0371, 0x00e8: 0x0375, 0x00e9: 0x0379, - 0x00ea: 0x037d, 0x00eb: 0x0381, 0x00ec: 0x0385, 0x00ed: 0x038b, 0x00ee: 0x0391, 0x00ef: 0x0396, - 0x00f0: 0x039b, 0x00f1: 0x039f, 0x00f2: 0x03a2, 0x00f3: 0x03a5, 0x00f4: 0x03a8, 0x00f5: 0x03ac, - 0x00f8: 0x03b0, 0x00f9: 0x03b4, 0x00fa: 0x03b8, 0x00fb: 0x03be, - 0x00fc: 0x03c4, 0x00fd: 0x03c9, 0x00fe: 0x03ce, 0x00ff: 0x03d3, + 0x00c0: 0x2e54, 0x00c1: 0x2e59, 0x00c2: 0x463f, 0x00c3: 0x2e5e, 0x00c4: 0x464e, 0x00c5: 0x4653, + 0x00c6: 0x8800, 0x00c7: 0x465d, 0x00c8: 0x2ec7, 0x00c9: 0x2ecc, 0x00ca: 0x4662, 0x00cb: 0x2ee0, + 0x00cc: 0x2f53, 0x00cd: 0x2f58, 0x00ce: 0x2f5d, 0x00cf: 0x4676, 0x00d1: 0x2fe9, + 0x00d2: 0x300c, 0x00d3: 0x3011, 0x00d4: 0x4680, 0x00d5: 0x4685, 0x00d6: 0x4694, + 0x00d8: 0x8800, 0x00d9: 0x3098, 0x00da: 0x309d, 0x00db: 0x30a2, 0x00dc: 0x46c6, 0x00dd: 0x311a, + 0x00e0: 0x3160, 0x00e1: 0x3165, 0x00e2: 0x46d0, 0x00e3: 0x316a, + 0x00e4: 0x46df, 0x00e5: 0x46e4, 0x00e6: 0x8800, 0x00e7: 0x46ee, 0x00e8: 0x31d3, 0x00e9: 0x31d8, + 0x00ea: 0x46f3, 0x00eb: 0x31ec, 0x00ec: 0x3264, 0x00ed: 0x3269, 0x00ee: 0x326e, 0x00ef: 0x4707, + 0x00f1: 0x32fa, 0x00f2: 0x331d, 0x00f3: 0x3322, 0x00f4: 0x4711, 0x00f5: 0x4716, + 0x00f6: 0x4725, 0x00f8: 0x8800, 0x00f9: 0x33ae, 0x00fa: 0x33b3, 0x00fb: 0x33b8, + 0x00fc: 0x4757, 0x00fd: 0x3435, 0x00ff: 0x344e, // Block 0x4, offset 0x100 - 0x0100: 0x092d, 0x0101: 0x092f, 0x0102: 0x0931, 0x0103: 0x0007, 0x0104: 0x0933, 0x0105: 0x0936, - 0x0106: 0x0939, 0x0107: 0x093d, 0x0108: 0x093f, 0x0109: 0x0941, 0x010a: 0x0943, 0x010b: 0x0946, - 0x010c: 0x0949, 0x010d: 0x094c, 0x010f: 0x094e, 0x0110: 0x0950, 0x0111: 0x0952, - 0x0112: 0x001e, 0x0113: 0x0955, 0x0114: 0x0958, 0x0115: 0x095c, 0x0116: 0x0960, 0x0117: 0x0962, - 0x0118: 0x0964, 0x0119: 0x0966, 0x011a: 0x096a, 0x011b: 0x096d, 0x011c: 0x096f, 0x011d: 0x0559, - 0x011e: 0x0973, 0x011f: 0x0976, 0x0120: 0x056c, 0x0121: 0x0979, 0x0122: 0x097c, 0x0123: 0x049b, - 0x0124: 0x0964, 0x0125: 0x096d, 0x0126: 0x0559, 0x0127: 0x0973, 0x0128: 0x0575, 0x0129: 0x056c, - 0x012a: 0x0979, - 0x0138: 0x097e, + 0x0100: 0x2e63, 0x0101: 0x316f, 0x0102: 0x4644, 0x0103: 0x46d5, 0x0104: 0x2e81, 0x0105: 0x318d, + 0x0106: 0x2e95, 0x0107: 0x31a1, 0x0108: 0x2e9a, 0x0109: 0x31a6, 0x010a: 0x2e9f, 0x010b: 0x31ab, + 0x010c: 0x2ea4, 0x010d: 0x31b0, 0x010e: 0x2eae, 0x010f: 0x31ba, + 0x0112: 0x4667, 0x0113: 0x46f8, 0x0114: 0x2ed6, 0x0115: 0x31e2, 0x0116: 0x2edb, 0x0117: 0x31e7, + 0x0118: 0x2ef9, 0x0119: 0x3205, 0x011a: 0x2eea, 0x011b: 0x31f6, 0x011c: 0x2f12, 0x011d: 0x321e, + 0x011e: 0x2f1c, 0x011f: 0x3228, 0x0120: 0x2f21, 0x0121: 0x322d, 0x0122: 0x2f2b, 0x0123: 0x3237, + 0x0124: 0x2f30, 0x0125: 0x323c, 0x0128: 0x2f62, 0x0129: 0x3273, + 0x012a: 0x2f67, 0x012b: 0x3278, 0x012c: 0x2f6c, 0x012d: 0x327d, 0x012e: 0x2f8f, 0x012f: 0x329b, + 0x0130: 0x2f71, 0x0132: 0x027d, 0x0133: 0x0301, 0x0134: 0x2f99, 0x0135: 0x32a5, + 0x0136: 0x2fad, 0x0137: 0x32be, 0x0139: 0x2fb7, 0x013a: 0x32c8, 0x013b: 0x2fc1, + 0x013c: 0x32d2, 0x013d: 0x2fbc, 0x013e: 0x32cd, 0x013f: 0x06fd, // Block 0x5, offset 0x140 - 0x0140: 0x0b02, 0x0141: 0x0b06, 0x0142: 0x0b0a, 0x0143: 0x0b0e, 0x0144: 0x0b12, 0x0145: 0x0b16, - 0x0146: 0x0b1a, 0x0147: 0x0b1e, 0x0148: 0x0b22, 0x0149: 0x0b26, 0x014a: 0x0b2a, 0x014b: 0x0b2e, - 0x014c: 0x0b32, 0x014d: 0x0b38, 0x014e: 0x0b3e, 0x014f: 0x0b44, 0x0150: 0x0b4a, 0x0151: 0x0b50, - 0x0152: 0x0b56, 0x0153: 0x0b5c, 0x0154: 0x0b62, 0x0155: 0x0b66, 0x0156: 0x0b6a, 0x0157: 0x0b6e, - 0x0158: 0x0b72, 0x0159: 0x0b76, 0x015a: 0x0b7a, 0x015b: 0x0b7e, 0x015c: 0x0b82, 0x015d: 0x0b88, - 0x015e: 0x0b8e, 0x015f: 0x0b92, 0x0160: 0x0b96, 0x0161: 0x0b9a, 0x0162: 0x0b9e, 0x0163: 0x0ba2, - 0x0164: 0x0ba6, 0x0165: 0x0bac, 0x0166: 0x0bb2, 0x0167: 0x0bb8, 0x0168: 0x0bbe, 0x0169: 0x0bc4, - 0x016a: 0x0bca, 0x016b: 0x0bce, 0x016c: 0x0bd2, 0x016d: 0x0bd6, 0x016e: 0x0bda, 0x016f: 0x0bde, - 0x0170: 0x0be2, 0x0171: 0x0be6, 0x0172: 0x0bea, 0x0173: 0x0bee, 0x0174: 0x0bf2, 0x0175: 0x0bf6, - 0x0176: 0x0bfa, 0x0177: 0x0bfe, 0x0178: 0x0c02, 0x0179: 0x0c08, 0x017a: 0x0c0e, 0x017b: 0x0c14, - 0x017c: 0x0c1a, 0x017d: 0x0c1e, 0x017e: 0x0c22, 0x017f: 0x0c26, + 0x0140: 0x0785, 0x0143: 0x2fe4, 0x0144: 0x32f5, 0x0145: 0x2ffd, + 0x0146: 0x330e, 0x0147: 0x2ff3, 0x0148: 0x3304, 0x0149: 0x07ad, + 0x014c: 0x468a, 0x014d: 0x471b, 0x014e: 0x3016, 0x014f: 0x3327, 0x0150: 0x3020, 0x0151: 0x3331, + 0x0154: 0x303e, 0x0155: 0x334f, 0x0156: 0x3057, 0x0157: 0x3368, + 0x0158: 0x3048, 0x0159: 0x3359, 0x015a: 0x46ad, 0x015b: 0x473e, 0x015c: 0x3061, 0x015d: 0x3372, + 0x015e: 0x3070, 0x015f: 0x3381, 0x0160: 0x46b2, 0x0161: 0x4743, 0x0162: 0x3089, 0x0163: 0x339f, + 0x0164: 0x307a, 0x0165: 0x3390, 0x0168: 0x46bc, 0x0169: 0x474d, + 0x016a: 0x46c1, 0x016b: 0x4752, 0x016c: 0x30a7, 0x016d: 0x33bd, 0x016e: 0x30b1, 0x016f: 0x33c7, + 0x0170: 0x30b6, 0x0171: 0x33cc, 0x0172: 0x30d4, 0x0173: 0x33ea, 0x0174: 0x30f7, 0x0175: 0x340d, + 0x0176: 0x311f, 0x0177: 0x343a, 0x0178: 0x3133, 0x0179: 0x3142, 0x017a: 0x3462, 0x017b: 0x314c, + 0x017c: 0x346c, 0x017d: 0x3151, 0x017e: 0x3471, 0x017f: 0x0175, // Block 0x6, offset 0x180 - 0x0180: 0x0c2a, 0x0181: 0x0c2e, 0x0182: 0x0c32, 0x0183: 0x0c36, 0x0184: 0x0c3a, 0x0185: 0x0c3e, - 0x0186: 0x0c42, 0x0187: 0x0c46, 0x0188: 0x0c4a, 0x0189: 0x0c4e, 0x018a: 0x0c52, 0x018b: 0x0c56, - 0x018c: 0x0c5a, 0x018d: 0x0c5e, 0x018e: 0x0c62, 0x018f: 0x0c66, 0x0190: 0x0c6a, 0x0191: 0x0c6e, - 0x0192: 0x0c72, 0x0193: 0x0c76, 0x0194: 0x0c7a, 0x0195: 0x0c7e, 0x0196: 0x0c82, 0x0197: 0x0c86, - 0x0198: 0x0c8a, 0x0199: 0x0c8e, 0x019a: 0x0c92, 0x019b: 0x0b9a, - 0x01a0: 0x0c9b, 0x01a1: 0x0c9f, 0x01a2: 0x0ca3, 0x01a3: 0x0ca7, - 0x01a4: 0x0cab, 0x01a5: 0x0cb1, 0x01a6: 0x0cb7, 0x01a7: 0x0cbd, 0x01a8: 0x0cc3, 0x01a9: 0x0cc9, - 0x01aa: 0x0ccf, 0x01ab: 0x0cd5, 0x01ac: 0x0cdb, 0x01ad: 0x0ce1, 0x01ae: 0x0ce7, 0x01af: 0x0ced, - 0x01b0: 0x0cf3, 0x01b1: 0x0cf9, 0x01b2: 0x0cff, 0x01b3: 0x0d05, 0x01b4: 0x0d0b, 0x01b5: 0x0d11, - 0x01b6: 0x0d17, 0x01b7: 0x0d1d, 0x01b8: 0x0d23, 0x01b9: 0x0d27, 0x01ba: 0x0d2b, 0x01bb: 0x0d2f, - 0x01bc: 0x0d33, 0x01bd: 0x0d37, 0x01be: 0x0d3b, 0x01bf: 0x0d41, + 0x0184: 0x41d4, 0x0185: 0x41da, + 0x0186: 0x41e0, 0x0187: 0x0292, 0x0188: 0x0295, 0x0189: 0x0322, 0x018a: 0x02a1, 0x018b: 0x02a4, + 0x018c: 0x0358, 0x018d: 0x2e6d, 0x018e: 0x3179, 0x018f: 0x2f7b, 0x0190: 0x3287, 0x0191: 0x3025, + 0x0192: 0x3336, 0x0193: 0x30bb, 0x0194: 0x33d1, 0x0195: 0x38b4, 0x0196: 0x3a43, 0x0197: 0x38ad, + 0x0198: 0x3a3c, 0x0199: 0x38bb, 0x019a: 0x3a4a, 0x019b: 0x38a6, 0x019c: 0x3a35, + 0x019e: 0x3795, 0x019f: 0x3924, 0x01a0: 0x378e, 0x01a1: 0x391d, 0x01a2: 0x3498, 0x01a3: 0x34aa, + 0x01a6: 0x2f26, 0x01a7: 0x3232, 0x01a8: 0x2fa3, 0x01a9: 0x32b4, + 0x01aa: 0x46a3, 0x01ab: 0x4734, 0x01ac: 0x3875, 0x01ad: 0x3a04, 0x01ae: 0x34bc, 0x01af: 0x34c2, + 0x01b0: 0x32aa, 0x01b1: 0x0262, 0x01b2: 0x0265, 0x01b3: 0x02e9, 0x01b4: 0x2f0d, 0x01b5: 0x3219, + 0x01b8: 0x2fdf, 0x01b9: 0x32f0, 0x01ba: 0x379c, 0x01bb: 0x392b, + 0x01bc: 0x3492, 0x01bd: 0x34a4, 0x01be: 0x349e, 0x01bf: 0x34b0, // Block 0x7, offset 0x1c0 - 0x01c0: 0x0d47, 0x01c1: 0x0d4d, 0x01c2: 0x0d53, 0x01c3: 0x0d59, 0x01c4: 0x0d5f, 0x01c5: 0x0d65, - 0x01c6: 0x0d6b, 0x01c7: 0x0d71, 0x01c8: 0x0d77, 0x01c9: 0x0d7b, 0x01ca: 0x0d7f, 0x01cb: 0x0d83, - 0x01cc: 0x0d87, 0x01cd: 0x0d8b, 0x01ce: 0x0d8f, 0x01cf: 0x0d93, 0x01d0: 0x0d97, 0x01d1: 0x0d9d, - 0x01d2: 0x0da3, 0x01d3: 0x0da9, 0x01d4: 0x0daf, 0x01d5: 0x0db5, 0x01d6: 0x0dbb, 0x01d7: 0x0dc1, - 0x01d8: 0x0dc7, 0x01d9: 0x0dcd, 0x01da: 0x0dd3, 0x01db: 0x0dd9, 0x01dc: 0x0ddf, 0x01dd: 0x0de5, - 0x01de: 0x0deb, 0x01df: 0x0df1, 0x01e0: 0x0df7, 0x01e1: 0x0dfd, 0x01e2: 0x0e03, 0x01e3: 0x0e09, - 0x01e4: 0x0e0f, 0x01e5: 0x0e13, 0x01e6: 0x0e17, 0x01e7: 0x0e1b, 0x01e8: 0x0e1f, 0x01e9: 0x0e25, - 0x01ea: 0x0e2b, 0x01eb: 0x0e31, 0x01ec: 0x0e37, 0x01ed: 0x0e3d, 0x01ee: 0x0e43, 0x01ef: 0x0e49, - 0x01f0: 0x0e4f, 0x01f1: 0x0e55, 0x01f2: 0x0e5b, 0x01f3: 0x0e5f, 0x01f4: 0x0e63, 0x01f5: 0x0e67, - 0x01f6: 0x0e6b, 0x01f7: 0x0e6f, 0x01f8: 0x0e73, 0x01f9: 0x0e77, + 0x01c0: 0x2e72, 0x01c1: 0x317e, 0x01c2: 0x2e77, 0x01c3: 0x3183, 0x01c4: 0x2eef, 0x01c5: 0x31fb, + 0x01c6: 0x2ef4, 0x01c7: 0x3200, 0x01c8: 0x2f80, 0x01c9: 0x328c, 0x01ca: 0x2f85, 0x01cb: 0x3291, + 0x01cc: 0x302a, 0x01cd: 0x333b, 0x01ce: 0x302f, 0x01cf: 0x3340, 0x01d0: 0x304d, 0x01d1: 0x335e, + 0x01d2: 0x3052, 0x01d3: 0x3363, 0x01d4: 0x30c0, 0x01d5: 0x33d6, 0x01d6: 0x30c5, 0x01d7: 0x33db, + 0x01d8: 0x306b, 0x01d9: 0x337c, 0x01da: 0x3084, 0x01db: 0x339a, + 0x01de: 0x2f3f, 0x01df: 0x324b, + 0x01e6: 0x4649, 0x01e7: 0x46da, 0x01e8: 0x4671, 0x01e9: 0x4702, + 0x01ea: 0x3844, 0x01eb: 0x39d3, 0x01ec: 0x3821, 0x01ed: 0x39b0, 0x01ee: 0x468f, 0x01ef: 0x4720, + 0x01f0: 0x383d, 0x01f1: 0x39cc, 0x01f2: 0x3129, 0x01f3: 0x3444, // Block 0x8, offset 0x200 - 0x0200: 0x0e7b, 0x0201: 0x0e80, 0x0202: 0x0e85, 0x0203: 0x0e8c, 0x0204: 0x0e93, 0x0205: 0x0e9a, - 0x0206: 0x0ea1, 0x0207: 0x0ea8, 0x0208: 0x0eaf, 0x0209: 0x0eb4, 0x020a: 0x0eb9, 0x020b: 0x0ec0, - 0x020c: 0x0ec7, 0x020d: 0x0ece, 0x020e: 0x0ed5, 0x020f: 0x0edc, 0x0210: 0x0ee3, 0x0211: 0x0ee8, - 0x0212: 0x0eed, 0x0213: 0x0ef4, 0x0214: 0x0efb, 0x0215: 0x0f02, - 0x0218: 0x0f09, 0x0219: 0x0f0e, 0x021a: 0x0f13, 0x021b: 0x0f1a, 0x021c: 0x0f21, 0x021d: 0x0f28, - 0x0220: 0x0f2f, 0x0221: 0x0f34, 0x0222: 0x0f39, 0x0223: 0x0f40, - 0x0224: 0x0f47, 0x0225: 0x0f4e, 0x0226: 0x0f55, 0x0227: 0x0f5c, 0x0228: 0x0f63, 0x0229: 0x0f68, - 0x022a: 0x0f6d, 0x022b: 0x0f74, 0x022c: 0x0f7b, 0x022d: 0x0f82, 0x022e: 0x0f89, 0x022f: 0x0f90, - 0x0230: 0x0f97, 0x0231: 0x0f9c, 0x0232: 0x0fa1, 0x0233: 0x0fa8, 0x0234: 0x0faf, 0x0235: 0x0fb6, - 0x0236: 0x0fbd, 0x0237: 0x0fc4, 0x0238: 0x0fcb, 0x0239: 0x0fd0, 0x023a: 0x0fd5, 0x023b: 0x0fdc, - 0x023c: 0x0fe3, 0x023d: 0x0fea, 0x023e: 0x0ff1, 0x023f: 0x0ff8, + 0x0200: 0x86e6, 0x0201: 0x86e6, 0x0202: 0x86e6, 0x0203: 0x86e6, 0x0204: 0x86e6, 0x0205: 0x80e6, + 0x0206: 0x86e6, 0x0207: 0x86e6, 0x0208: 0x86e6, 0x0209: 0x86e6, 0x020a: 0x86e6, 0x020b: 0x86e6, + 0x020c: 0x86e6, 0x020d: 0x80e6, 0x020e: 0x80e6, 0x020f: 0x86e6, 0x0210: 0x80e6, 0x0211: 0x86e6, + 0x0212: 0x80e6, 0x0213: 0x86e6, 0x0214: 0x86e6, 0x0215: 0x80e8, 0x0216: 0x80dc, 0x0217: 0x80dc, + 0x0218: 0x80dc, 0x0219: 0x80dc, 0x021a: 0x80e8, 0x021b: 0x86d8, 0x021c: 0x80dc, 0x021d: 0x80dc, + 0x021e: 0x80dc, 0x021f: 0x80dc, 0x0220: 0x80dc, 0x0221: 0x80ca, 0x0222: 0x80ca, 0x0223: 0x86dc, + 0x0224: 0x86dc, 0x0225: 0x86dc, 0x0226: 0x86dc, 0x0227: 0x86ca, 0x0228: 0x86ca, 0x0229: 0x80dc, + 0x022a: 0x80dc, 0x022b: 0x80dc, 0x022c: 0x80dc, 0x022d: 0x86dc, 0x022e: 0x86dc, 0x022f: 0x80dc, + 0x0230: 0x86dc, 0x0231: 0x86dc, 0x0232: 0x80dc, 0x0233: 0x80dc, 0x0234: 0x8001, 0x0235: 0x8001, + 0x0236: 0x8001, 0x0237: 0x8001, 0x0238: 0x8601, 0x0239: 0x80dc, 0x023a: 0x80dc, 0x023b: 0x80dc, + 0x023c: 0x80dc, 0x023d: 0x80e6, 0x023e: 0x80e6, 0x023f: 0x80e6, // Block 0x9, offset 0x240 - 0x0240: 0x0fff, 0x0241: 0x1004, 0x0242: 0x1009, 0x0243: 0x1010, 0x0244: 0x1017, 0x0245: 0x101e, - 0x0248: 0x1025, 0x0249: 0x102a, 0x024a: 0x102f, 0x024b: 0x1036, - 0x024c: 0x103d, 0x024d: 0x1044, 0x0250: 0x104b, 0x0251: 0x1050, - 0x0252: 0x1055, 0x0253: 0x105c, 0x0254: 0x1063, 0x0255: 0x106a, 0x0256: 0x1071, 0x0257: 0x1078, - 0x0259: 0x107f, 0x025b: 0x1084, 0x025d: 0x108b, - 0x025f: 0x1092, 0x0260: 0x1099, 0x0261: 0x109e, 0x0262: 0x10a3, 0x0263: 0x10aa, - 0x0264: 0x10b1, 0x0265: 0x10b8, 0x0266: 0x10bf, 0x0267: 0x10c6, 0x0268: 0x10cd, 0x0269: 0x10d2, - 0x026a: 0x10d7, 0x026b: 0x10de, 0x026c: 0x10e5, 0x026d: 0x10ec, 0x026e: 0x10f3, 0x026f: 0x10fa, - 0x0270: 0x1101, 0x0271: 0x0525, 0x0272: 0x1106, 0x0273: 0x052a, 0x0274: 0x110b, 0x0275: 0x052f, - 0x0276: 0x1110, 0x0277: 0x0534, 0x0278: 0x1115, 0x0279: 0x054a, 0x027a: 0x111a, 0x027b: 0x054f, - 0x027c: 0x111f, 0x027d: 0x0554, + 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4980, 0x0245: 0x86f0, + 0x0246: 0x80e6, 0x0247: 0x80dc, 0x0248: 0x80dc, 0x0249: 0x80dc, 0x024a: 0x80e6, 0x024b: 0x80e6, + 0x024c: 0x80e6, 0x024d: 0x80dc, 0x024e: 0x80dc, 0x0250: 0x80e6, 0x0251: 0x80e6, + 0x0252: 0x80e6, 0x0253: 0x80dc, 0x0254: 0x80dc, 0x0255: 0x80dc, 0x0256: 0x80dc, 0x0257: 0x80e6, + 0x0258: 0x80e8, 0x0259: 0x80dc, 0x025a: 0x80dc, 0x025b: 0x80e6, 0x025c: 0x80e9, 0x025d: 0x80ea, + 0x025e: 0x80ea, 0x025f: 0x80e9, 0x0260: 0x80ea, 0x0261: 0x80ea, 0x0262: 0x80e9, 0x0263: 0x80e6, + 0x0264: 0x80e6, 0x0265: 0x80e6, 0x0266: 0x80e6, 0x0267: 0x80e6, 0x0268: 0x80e6, 0x0269: 0x80e6, + 0x026a: 0x80e6, 0x026b: 0x80e6, 0x026c: 0x80e6, 0x026d: 0x80e6, 0x026e: 0x80e6, 0x026f: 0x80e6, + 0x0274: 0x042d, + 0x027a: 0x4191, + 0x027e: 0x0105, // Block 0xa, offset 0x280 - 0x0280: 0x1124, 0x0281: 0x112b, 0x0282: 0x1132, 0x0283: 0x113b, 0x0284: 0x1144, 0x0285: 0x114d, - 0x0286: 0x1156, 0x0287: 0x115f, 0x0288: 0x1168, 0x0289: 0x116f, 0x028a: 0x1176, 0x028b: 0x117f, - 0x028c: 0x1188, 0x028d: 0x1191, 0x028e: 0x119a, 0x028f: 0x11a3, 0x0290: 0x11ac, 0x0291: 0x11b3, - 0x0292: 0x11ba, 0x0293: 0x11c3, 0x0294: 0x11cc, 0x0295: 0x11d5, 0x0296: 0x11de, 0x0297: 0x11e7, - 0x0298: 0x11f0, 0x0299: 0x11f7, 0x029a: 0x11fe, 0x029b: 0x1207, 0x029c: 0x1210, 0x029d: 0x1219, - 0x029e: 0x1222, 0x029f: 0x122b, 0x02a0: 0x1234, 0x02a1: 0x123b, 0x02a2: 0x1242, 0x02a3: 0x124b, - 0x02a4: 0x1254, 0x02a5: 0x125d, 0x02a6: 0x1266, 0x02a7: 0x126f, 0x02a8: 0x1278, 0x02a9: 0x127f, - 0x02aa: 0x1286, 0x02ab: 0x128f, 0x02ac: 0x1298, 0x02ad: 0x12a1, 0x02ae: 0x12aa, 0x02af: 0x12b3, - 0x02b0: 0x12bc, 0x02b1: 0x12c1, 0x02b2: 0x12c6, 0x02b3: 0x12cd, 0x02b4: 0x12d2, - 0x02b6: 0x12d9, 0x02b7: 0x12de, 0x02b8: 0x12e5, 0x02b9: 0x12ea, 0x02ba: 0x12ef, 0x02bb: 0x04ee, - 0x02bc: 0x12f4, 0x02bd: 0x12f9, 0x02be: 0x12fd, 0x02bf: 0x12f9, + 0x0284: 0x4146, 0x0285: 0x4379, + 0x0286: 0x34ce, 0x0287: 0x0394, 0x0288: 0x34ec, 0x0289: 0x34f8, 0x028a: 0x350a, + 0x028c: 0x3528, 0x028e: 0x353a, 0x028f: 0x3558, 0x0290: 0x3ced, 0x0291: 0x8800, + 0x0295: 0x8800, 0x0297: 0x8800, + 0x0299: 0x8800, + 0x029f: 0x8800, 0x02a1: 0x8800, + 0x02a5: 0x8800, 0x02a9: 0x8800, + 0x02aa: 0x351c, 0x02ab: 0x354c, 0x02ac: 0x47b5, 0x02ad: 0x357c, 0x02ae: 0x47df, 0x02af: 0x358e, + 0x02b0: 0x3d55, 0x02b1: 0x8800, 0x02b5: 0x8800, + 0x02b7: 0x8800, 0x02b9: 0x8800, + 0x02bf: 0x8800, // Block 0xb, offset 0x2c0 - 0x02c0: 0x1300, 0x02c1: 0x1309, 0x02c2: 0x130f, 0x02c3: 0x1316, 0x02c4: 0x131b, - 0x02c6: 0x1322, 0x02c7: 0x1327, 0x02c8: 0x132e, 0x02c9: 0x04f6, 0x02ca: 0x1333, 0x02cb: 0x04fb, - 0x02cc: 0x1338, 0x02cd: 0x1343, 0x02ce: 0x134f, 0x02cf: 0x135b, 0x02d0: 0x1361, 0x02d1: 0x1366, - 0x02d2: 0x136b, 0x02d3: 0x0514, 0x02d6: 0x1372, 0x02d7: 0x1377, - 0x02d8: 0x137e, 0x02d9: 0x1383, 0x02da: 0x1388, 0x02db: 0x0500, 0x02dd: 0x1393, - 0x02de: 0x139f, 0x02df: 0x13ab, 0x02e0: 0x13b1, 0x02e1: 0x13b6, 0x02e2: 0x13bb, 0x02e3: 0x0539, - 0x02e4: 0x13c2, 0x02e5: 0x13c7, 0x02e6: 0x13cc, 0x02e7: 0x13d1, 0x02e8: 0x13d8, 0x02e9: 0x13dd, - 0x02ea: 0x13e2, 0x02eb: 0x050a, 0x02ec: 0x13e7, 0x02ed: 0x13f1, 0x02ee: 0x04e8, 0x02ef: 0x13f7, - 0x02f2: 0x13f9, 0x02f3: 0x1400, 0x02f4: 0x1405, - 0x02f6: 0x140c, 0x02f7: 0x1411, 0x02f8: 0x1418, 0x02f9: 0x0505, 0x02fa: 0x141d, 0x02fb: 0x050f, - 0x02fc: 0x1422, 0x02fd: 0x0011, 0x02fe: 0x142a, + 0x02c1: 0x8800, 0x02c5: 0x8800, + 0x02c9: 0x8800, 0x02ca: 0x47f7, 0x02cb: 0x4815, + 0x02cc: 0x35ac, 0x02cd: 0x35c4, 0x02ce: 0x482d, 0x02d0: 0x047b, 0x02d1: 0x048d, + 0x02d2: 0x0469, 0x02d3: 0x420a, 0x02d4: 0x4210, 0x02d5: 0x04b7, 0x02d6: 0x04a5, + 0x02f0: 0x0493, 0x02f1: 0x04a8, 0x02f2: 0x04ab, 0x02f4: 0x0445, 0x02f5: 0x0484, + 0x02f9: 0x0463, // Block 0xc, offset 0x300 - 0x0300: 0x1486, 0x0301: 0x001c, 0x0302: 0x000d, 0x0303: 0x000f, 0x0304: 0x1488, 0x0305: 0x148a, - 0x0306: 0x148c, 0x0307: 0x148e, 0x0308: 0x1490, 0x0309: 0x1492, 0x030a: 0x1494, 0x030b: 0x1496, - 0x030c: 0x149a, 0x030d: 0x149c, 0x030e: 0x149e, 0x0310: 0x0007, 0x0311: 0x0941, - 0x0312: 0x001e, 0x0313: 0x04c7, 0x0314: 0x0943, 0x0315: 0x0494, 0x0316: 0x094e, 0x0317: 0x04c5, - 0x0318: 0x0950, 0x0319: 0x14a0, 0x031a: 0x0960, 0x031b: 0x02c8, 0x031c: 0x0962, - 0x0328: 0x14a2, + 0x0300: 0x3606, 0x0301: 0x3612, 0x0303: 0x3600, + 0x0306: 0x8800, 0x0307: 0x35ee, + 0x030c: 0x3642, 0x030d: 0x362a, 0x030e: 0x3654, 0x0310: 0x8800, + 0x0313: 0x8800, 0x0315: 0x8800, 0x0316: 0x8800, 0x0317: 0x8800, + 0x0318: 0x8800, 0x0319: 0x3636, 0x031a: 0x8800, + 0x031e: 0x8800, 0x0323: 0x8800, + 0x0327: 0x8800, + 0x032b: 0x8800, 0x032d: 0x8800, + 0x0330: 0x8800, 0x0333: 0x8800, 0x0335: 0x8800, + 0x0336: 0x8800, 0x0337: 0x8800, 0x0338: 0x8800, 0x0339: 0x36ba, 0x033a: 0x8800, + 0x033e: 0x8800, // Block 0xd, offset 0x340 - 0x0340: 0x14a5, 0x0341: 0x14a9, 0x0342: 0x14ad, 0x0343: 0x14af, 0x0345: 0x14b3, - 0x0346: 0x14b7, 0x0347: 0x14bb, 0x0349: 0x14be, 0x034a: 0x094c, 0x034b: 0x0916, - 0x034c: 0x0916, 0x034d: 0x0916, 0x034e: 0x0494, 0x034f: 0x14c2, 0x0350: 0x0918, 0x0351: 0x0918, - 0x0352: 0x091e, 0x0353: 0x04c5, 0x0355: 0x0922, 0x0356: 0x14c5, - 0x0359: 0x0929, 0x035a: 0x14c8, 0x035b: 0x092b, 0x035c: 0x092b, 0x035d: 0x092b, - 0x0360: 0x14ca, 0x0361: 0x14cd, 0x0362: 0x14d1, - 0x0364: 0x14d4, 0x0366: 0x14d6, 0x0368: 0x14d4, - 0x036a: 0x091c, 0x036b: 0x0046, 0x036c: 0x090b, 0x036d: 0x14ad, 0x036f: 0x0941, - 0x0370: 0x090f, 0x0371: 0x14d9, 0x0373: 0x0920, 0x0374: 0x001e, 0x0375: 0x14db, - 0x0376: 0x14de, 0x0377: 0x14e1, 0x0378: 0x14e4, 0x0379: 0x097c, 0x037b: 0x14e7, - 0x037c: 0x056f, 0x037d: 0x0973, 0x037e: 0x14eb, 0x037f: 0x14ee, + 0x0341: 0x3618, 0x0342: 0x369c, + 0x0350: 0x35f4, 0x0351: 0x3678, + 0x0352: 0x35fa, 0x0353: 0x367e, 0x0356: 0x360c, 0x0357: 0x3690, + 0x0358: 0x8800, 0x0359: 0x8800, 0x035a: 0x370e, 0x035b: 0x3714, 0x035c: 0x361e, 0x035d: 0x36a2, + 0x035e: 0x3624, 0x035f: 0x36a8, 0x0362: 0x3630, 0x0363: 0x36b4, + 0x0364: 0x363c, 0x0365: 0x36c0, 0x0366: 0x3648, 0x0367: 0x36cc, 0x0368: 0x8800, 0x0369: 0x8800, + 0x036a: 0x371a, 0x036b: 0x3720, 0x036c: 0x3672, 0x036d: 0x36f6, 0x036e: 0x364e, 0x036f: 0x36d2, + 0x0370: 0x365a, 0x0371: 0x36de, 0x0372: 0x3660, 0x0373: 0x36e4, 0x0374: 0x3666, 0x0375: 0x36ea, + 0x0378: 0x366c, 0x0379: 0x36f0, // Block 0xe, offset 0x380 - 0x0380: 0x14f1, 0x0385: 0x090d, - 0x0386: 0x093f, 0x0387: 0x0941, 0x0388: 0x097c, 0x0389: 0x0499, - 0x0390: 0x14f5, 0x0391: 0x14fb, - 0x0392: 0x1501, 0x0393: 0x1508, 0x0394: 0x150e, 0x0395: 0x1514, 0x0396: 0x151a, 0x0397: 0x1520, - 0x0398: 0x1526, 0x0399: 0x152c, 0x039a: 0x1532, 0x039b: 0x1538, 0x039c: 0x153e, 0x039d: 0x1544, - 0x039e: 0x154a, 0x039f: 0x1550, 0x03a0: 0x0918, 0x03a1: 0x1555, 0x03a2: 0x1558, 0x03a3: 0x155c, - 0x03a4: 0x155f, 0x03a5: 0x1561, 0x03a6: 0x1564, 0x03a7: 0x1568, 0x03a8: 0x156d, 0x03a9: 0x1570, - 0x03aa: 0x1572, 0x03ab: 0x1575, 0x03ac: 0x091e, 0x03ad: 0x14ad, 0x03ae: 0x090d, 0x03af: 0x0920, - 0x03b0: 0x097c, 0x03b1: 0x1579, 0x03b2: 0x157c, 0x03b3: 0x1580, 0x03b4: 0x096d, 0x03b5: 0x1583, - 0x03b6: 0x1586, 0x03b7: 0x158a, 0x03b8: 0x158f, 0x03b9: 0x04c7, 0x03ba: 0x1592, 0x03bb: 0x1595, - 0x03bc: 0x04c5, 0x03bd: 0x0984, 0x03be: 0x093f, 0x03bf: 0x0950, + 0x0387: 0x1c4e, + 0x0391: 0x80dc, + 0x0392: 0x80e6, 0x0393: 0x80e6, 0x0394: 0x80e6, 0x0395: 0x80e6, 0x0396: 0x80dc, 0x0397: 0x80e6, + 0x0398: 0x80e6, 0x0399: 0x80e6, 0x039a: 0x80de, 0x039b: 0x80dc, 0x039c: 0x80e6, 0x039d: 0x80e6, + 0x039e: 0x80e6, 0x039f: 0x80e6, 0x03a0: 0x80e6, 0x03a1: 0x80e6, 0x03a2: 0x80dc, 0x03a3: 0x80dc, + 0x03a4: 0x80dc, 0x03a5: 0x80dc, 0x03a6: 0x80dc, 0x03a7: 0x80dc, 0x03a8: 0x80e6, 0x03a9: 0x80e6, + 0x03aa: 0x80dc, 0x03ab: 0x80e6, 0x03ac: 0x80e6, 0x03ad: 0x80de, 0x03ae: 0x80e4, 0x03af: 0x80e6, + 0x03b0: 0x800a, 0x03b1: 0x800b, 0x03b2: 0x800c, 0x03b3: 0x800d, 0x03b4: 0x800e, 0x03b5: 0x800f, + 0x03b6: 0x8010, 0x03b7: 0x8011, 0x03b8: 0x8012, 0x03b9: 0x8013, 0x03ba: 0x8013, 0x03bb: 0x8014, + 0x03bc: 0x8015, 0x03bd: 0x8016, 0x03bf: 0x8017, // Block 0xf, offset 0x3c0 - 0x03e0: 0x001c, 0x03e1: 0x000d, 0x03e2: 0x000f, 0x03e3: 0x1488, - 0x03e4: 0x148a, 0x03e5: 0x148c, 0x03e6: 0x148e, 0x03e7: 0x1490, 0x03e8: 0x1492, 0x03e9: 0x16cb, - 0x03ea: 0x16ce, 0x03eb: 0x16d1, 0x03ec: 0x16d4, 0x03ed: 0x16d7, 0x03ee: 0x16da, 0x03ef: 0x16dd, - 0x03f0: 0x16e0, 0x03f1: 0x16e3, 0x03f2: 0x16e6, 0x03f3: 0x16e9, 0x03f4: 0x16ec, 0x03f5: 0x16f0, - 0x03f6: 0x16f4, 0x03f7: 0x16f8, 0x03f8: 0x16fc, 0x03f9: 0x1700, 0x03fa: 0x1704, 0x03fb: 0x1708, - 0x03fc: 0x170c, 0x03fd: 0x1710, 0x03fe: 0x1715, 0x03ff: 0x171a, + 0x03c8: 0x8800, 0x03ca: 0x8800, 0x03cb: 0x801b, + 0x03cc: 0x801c, 0x03cd: 0x801d, 0x03ce: 0x801e, 0x03cf: 0x801f, 0x03d0: 0x8020, 0x03d1: 0x8021, + 0x03d2: 0x8022, 0x03d3: 0x86e6, 0x03d4: 0x86e6, 0x03d5: 0x86dc, 0x03d6: 0x80dc, 0x03d7: 0x80e6, + 0x03d8: 0x80e6, 0x03d9: 0x80e6, 0x03da: 0x80e6, 0x03db: 0x80e6, 0x03dc: 0x80dc, 0x03dd: 0x80e6, + 0x03de: 0x80e6, 0x03df: 0x80dc, + 0x03f0: 0x8023, 0x03f5: 0x1c71, + 0x03f6: 0x1f00, 0x03f7: 0x1f3c, 0x03f8: 0x1f37, // Block 0x10, offset 0x400 - 0x0400: 0x171f, 0x0401: 0x1724, 0x0402: 0x1729, 0x0403: 0x172e, 0x0404: 0x1733, 0x0405: 0x1738, - 0x0406: 0x173d, 0x0407: 0x1742, 0x0408: 0x1747, 0x0409: 0x174a, 0x040a: 0x174d, 0x040b: 0x1750, - 0x040c: 0x1753, 0x040d: 0x1756, 0x040e: 0x1759, 0x040f: 0x175c, 0x0410: 0x175f, 0x0411: 0x1762, - 0x0412: 0x1766, 0x0413: 0x176a, 0x0414: 0x176e, 0x0415: 0x1772, 0x0416: 0x1776, 0x0417: 0x177a, - 0x0418: 0x177e, 0x0419: 0x1782, 0x041a: 0x1786, 0x041b: 0x178a, 0x041c: 0x178e, 0x041d: 0x1792, - 0x041e: 0x1796, 0x041f: 0x179a, 0x0420: 0x179e, 0x0421: 0x17a2, 0x0422: 0x17a6, 0x0423: 0x17aa, - 0x0424: 0x17ae, 0x0425: 0x17b2, 0x0426: 0x17b6, 0x0427: 0x17ba, 0x0428: 0x17be, 0x0429: 0x17c2, - 0x042a: 0x17c6, 0x042b: 0x17ca, 0x042c: 0x17ce, 0x042d: 0x17d2, 0x042e: 0x17d6, 0x042f: 0x17da, - 0x0430: 0x17de, 0x0431: 0x17e2, 0x0432: 0x17e6, 0x0433: 0x17ea, 0x0434: 0x17ee, 0x0435: 0x17f2, - 0x0436: 0x0906, 0x0437: 0x090b, 0x0438: 0x14ad, 0x0439: 0x090d, 0x043a: 0x090f, 0x043b: 0x14d9, - 0x043c: 0x0914, 0x043d: 0x0916, 0x043e: 0x0918, 0x043f: 0x091a, + 0x0405: 0x8800, + 0x0406: 0x0078, 0x0407: 0x8800, 0x0408: 0x007f, 0x0409: 0x8800, 0x040a: 0x0086, 0x040b: 0x8800, + 0x040c: 0x008d, 0x040d: 0x8800, 0x040e: 0x0094, 0x0411: 0x8800, + 0x0412: 0x009b, + 0x0434: 0x8007, 0x0435: 0x8600, + 0x043a: 0x8800, 0x043b: 0x00a2, + 0x043c: 0x8800, 0x043d: 0x00a9, 0x043e: 0x8800, 0x043f: 0x8800, // Block 0x11, offset 0x440 - 0x0440: 0x091c, 0x0441: 0x091e, 0x0442: 0x0920, 0x0443: 0x0922, 0x0444: 0x0924, 0x0445: 0x0929, - 0x0446: 0x14c8, 0x0447: 0x092b, 0x0448: 0x17f6, 0x0449: 0x092d, 0x044a: 0x092f, 0x044b: 0x155f, - 0x044c: 0x0931, 0x044d: 0x1570, 0x044e: 0x17f8, 0x044f: 0x14d4, 0x0450: 0x0007, 0x0451: 0x093d, - 0x0452: 0x0984, 0x0453: 0x093f, 0x0454: 0x0941, 0x0455: 0x098c, 0x0456: 0x094c, 0x0457: 0x0494, - 0x0458: 0x097c, 0x0459: 0x0499, 0x045a: 0x094e, 0x045b: 0x04c5, 0x045c: 0x0950, 0x045d: 0x14a0, - 0x045e: 0x001e, 0x045f: 0x0960, 0x0460: 0x17fa, 0x0461: 0x049b, 0x0462: 0x02c8, 0x0463: 0x0962, - 0x0464: 0x0964, 0x0465: 0x096d, 0x0466: 0x04a6, 0x0467: 0x04c7, 0x0468: 0x04a8, 0x0469: 0x09df, - 0x046a: 0x1486, + 0x0440: 0x0137, 0x0441: 0x0139, 0x0442: 0x013d, 0x0443: 0x0151, 0x0444: 0x03b5, 0x0445: 0x03b8, + 0x0446: 0x0951, 0x0447: 0x0153, 0x0448: 0x0157, 0x0449: 0x0159, 0x044a: 0x03c4, 0x044b: 0x03c7, + 0x044c: 0x03ca, 0x044d: 0x015d, 0x044f: 0x0165, 0x0450: 0x0169, 0x0451: 0x03a3, + 0x0452: 0x016d, 0x0453: 0x03be, 0x0454: 0x0955, 0x0455: 0x0959, 0x0456: 0x016f, 0x0457: 0x0177, + 0x0458: 0x0179, 0x0459: 0x0961, 0x045a: 0x03e8, 0x045b: 0x017b, 0x045c: 0x0965, 0x045d: 0x047b, + 0x045e: 0x047e, 0x045f: 0x0481, 0x0460: 0x04b7, 0x0461: 0x04ba, 0x0462: 0x0161, 0x0463: 0x0173, + 0x0464: 0x0179, 0x0465: 0x017b, 0x0466: 0x047b, 0x0467: 0x047e, 0x0468: 0x04a8, 0x0469: 0x04b7, + 0x046a: 0x04ba, + 0x0478: 0x04c9, // Block 0x12, offset 0x480 - 0x048c: 0x1b8a, 0x048e: 0x1b91, 0x0490: 0x1b98, - 0x0492: 0x1b9f, 0x0494: 0x1ba6, 0x0496: 0x1bad, - 0x0498: 0x1bb4, 0x049a: 0x1bbb, 0x049c: 0x1bc2, - 0x049e: 0x1bc9, 0x04a0: 0x1bd0, 0x04a2: 0x1bd7, - 0x04a5: 0x1bde, 0x04a7: 0x1be5, 0x04a9: 0x1bec, - 0x04b0: 0x1bf3, 0x04b1: 0x1bfa, 0x04b3: 0x1c01, 0x04b4: 0x1c08, - 0x04b6: 0x1c0f, 0x04b7: 0x1c16, 0x04b9: 0x1c1d, 0x04ba: 0x1c24, - 0x04bc: 0x1c2b, 0x04bd: 0x1c32, + 0x049b: 0x03bb, 0x049c: 0x0155, 0x049d: 0x03c1, + 0x049e: 0x039a, 0x049f: 0x03ca, 0x04a0: 0x015b, 0x04a1: 0x03cd, 0x04a2: 0x03d0, 0x04a3: 0x03d6, + 0x04a4: 0x03dc, 0x04a5: 0x03df, 0x04a6: 0x03e2, 0x04a7: 0x0969, 0x04a8: 0x0427, 0x04a9: 0x03e5, + 0x04aa: 0x096d, 0x04ab: 0x042a, 0x04ac: 0x03ee, 0x04ad: 0x03eb, 0x04ae: 0x03f1, 0x04af: 0x03f4, + 0x04b0: 0x03f7, 0x04b1: 0x03fa, 0x04b2: 0x03fd, 0x04b3: 0x0409, 0x04b4: 0x040c, 0x04b5: 0x03ac, + 0x04b6: 0x040f, 0x04b7: 0x0412, 0x04b8: 0x095d, 0x04b9: 0x0415, 0x04ba: 0x0418, 0x04bb: 0x0183, + 0x04bc: 0x041b, 0x04bd: 0x041e, 0x04be: 0x0421, 0x04bf: 0x048d, // Block 0x13, offset 0x4c0 - 0x04c0: 0x1ed8, 0x04c1: 0x1ede, 0x04c2: 0x1ee4, 0x04c3: 0x1eea, 0x04c4: 0x1ef0, 0x04c5: 0x1ef6, - 0x04c6: 0x1efc, 0x04c7: 0x1f02, 0x04c8: 0x1f08, 0x04c9: 0x1f0e, 0x04ca: 0x1f14, 0x04cb: 0x1f1a, - 0x04cc: 0x1f20, 0x04cd: 0x1f26, 0x04ce: 0x1f2c, 0x04cf: 0x1f35, 0x04d0: 0x1f3e, 0x04d1: 0x1f47, - 0x04d2: 0x1f50, 0x04d3: 0x1f59, 0x04d4: 0x1f62, 0x04d5: 0x1f6b, 0x04d6: 0x1f74, 0x04d7: 0x1f7d, - 0x04d8: 0x1f86, 0x04d9: 0x1f8f, 0x04da: 0x1f98, 0x04db: 0x1fa1, 0x04dc: 0x1faa, 0x04dd: 0x1fb3, - 0x04de: 0x1fc5, 0x04e0: 0x1fd4, 0x04e1: 0x1fda, 0x04e2: 0x1fe0, 0x04e3: 0x1fe6, - 0x04e4: 0x1fec, 0x04e5: 0x1ff2, 0x04e6: 0x1ff8, 0x04e7: 0x1ffe, 0x04e8: 0x2004, 0x04e9: 0x200a, - 0x04ea: 0x2010, 0x04eb: 0x2016, 0x04ec: 0x201c, 0x04ed: 0x2022, 0x04ee: 0x2028, 0x04ef: 0x202e, - 0x04f0: 0x2034, 0x04f1: 0x203a, 0x04f2: 0x2040, 0x04f3: 0x2046, 0x04f4: 0x204c, 0x04f5: 0x2052, - 0x04f6: 0x2058, 0x04f7: 0x205e, 0x04f8: 0x2064, 0x04f9: 0x206a, 0x04fa: 0x2070, 0x04fb: 0x2076, - 0x04fc: 0x207c, 0x04fd: 0x2082, 0x04fe: 0x2088, 0x04ff: 0x208e, + 0x04c0: 0x2e7c, 0x04c1: 0x3188, 0x04c2: 0x2e86, 0x04c3: 0x3192, 0x04c4: 0x2e8b, 0x04c5: 0x3197, + 0x04c6: 0x2e90, 0x04c7: 0x319c, 0x04c8: 0x37b1, 0x04c9: 0x3940, 0x04ca: 0x2ea9, 0x04cb: 0x31b5, + 0x04cc: 0x2eb3, 0x04cd: 0x31bf, 0x04ce: 0x2ec2, 0x04cf: 0x31ce, 0x04d0: 0x2eb8, 0x04d1: 0x31c4, + 0x04d2: 0x2ebd, 0x04d3: 0x31c9, 0x04d4: 0x37d4, 0x04d5: 0x3963, 0x04d6: 0x37db, 0x04d7: 0x396a, + 0x04d8: 0x2efe, 0x04d9: 0x320a, 0x04da: 0x2f03, 0x04db: 0x320f, 0x04dc: 0x37e9, 0x04dd: 0x3978, + 0x04de: 0x2f08, 0x04df: 0x3214, 0x04e0: 0x2f17, 0x04e1: 0x3223, 0x04e2: 0x2f35, 0x04e3: 0x3241, + 0x04e4: 0x2f44, 0x04e5: 0x3250, 0x04e6: 0x2f3a, 0x04e7: 0x3246, 0x04e8: 0x2f49, 0x04e9: 0x3255, + 0x04ea: 0x2f4e, 0x04eb: 0x325a, 0x04ec: 0x2f94, 0x04ed: 0x32a0, 0x04ee: 0x37f0, 0x04ef: 0x397f, + 0x04f0: 0x2f9e, 0x04f1: 0x32af, 0x04f2: 0x2fa8, 0x04f3: 0x32b9, 0x04f4: 0x2fb2, 0x04f5: 0x32c3, + 0x04f6: 0x467b, 0x04f7: 0x470c, 0x04f8: 0x37f7, 0x04f9: 0x3986, 0x04fa: 0x2fcb, 0x04fb: 0x32dc, + 0x04fc: 0x2fc6, 0x04fd: 0x32d7, 0x04fe: 0x2fd0, 0x04ff: 0x32e1, // Block 0x14, offset 0x500 - 0x0500: 0x2094, 0x0501: 0x209a, 0x0502: 0x20a0, 0x0503: 0x20a6, 0x0504: 0x20ac, 0x0505: 0x20b0, - 0x0506: 0x192e, 0x0507: 0x20b4, - 0x0510: 0x20b8, 0x0511: 0x20bc, - 0x0512: 0x20bf, 0x0513: 0x20c2, 0x0514: 0x20c5, 0x0515: 0x20c8, 0x0516: 0x20cb, 0x0517: 0x20ce, - 0x0518: 0x20d1, 0x0519: 0x20d4, 0x051a: 0x20d7, 0x051b: 0x20da, 0x051c: 0x20dd, 0x051d: 0x20e0, - 0x051e: 0x20e3, 0x051f: 0x20e6, 0x0520: 0x1d38, 0x0521: 0x1d44, 0x0522: 0x1d50, 0x0523: 0x1d58, - 0x0524: 0x1d78, 0x0525: 0x1d7c, 0x0526: 0x1d88, 0x0527: 0x1d90, 0x0528: 0x1d94, 0x0529: 0x1d9c, - 0x052a: 0x1da0, 0x052b: 0x1da4, 0x052c: 0x1da8, 0x052d: 0x1dac, 0x052e: 0x20e9, 0x052f: 0x20f0, - 0x0530: 0x20f7, 0x0531: 0x20fe, 0x0532: 0x2105, 0x0533: 0x210c, 0x0534: 0x2113, 0x0535: 0x211a, - 0x0536: 0x2121, 0x0537: 0x2128, 0x0538: 0x212f, 0x0539: 0x2136, 0x053a: 0x213d, 0x053b: 0x2144, - 0x053c: 0x214b, 0x053d: 0x215b, 0x053e: 0x2168, + 0x0500: 0x2fd5, 0x0501: 0x32e6, 0x0502: 0x2fda, 0x0503: 0x32eb, 0x0504: 0x2fee, 0x0505: 0x32ff, + 0x0506: 0x2ff8, 0x0507: 0x3309, 0x0508: 0x3007, 0x0509: 0x3318, 0x050a: 0x3002, 0x050b: 0x3313, + 0x050c: 0x381a, 0x050d: 0x39a9, 0x050e: 0x3828, 0x050f: 0x39b7, 0x0510: 0x382f, 0x0511: 0x39be, + 0x0512: 0x3836, 0x0513: 0x39c5, 0x0514: 0x3034, 0x0515: 0x3345, 0x0516: 0x3039, 0x0517: 0x334a, + 0x0518: 0x3043, 0x0519: 0x3354, 0x051a: 0x46a8, 0x051b: 0x4739, 0x051c: 0x387c, 0x051d: 0x3a0b, + 0x051e: 0x305c, 0x051f: 0x336d, 0x0520: 0x3066, 0x0521: 0x3377, 0x0522: 0x46b7, 0x0523: 0x4748, + 0x0524: 0x3883, 0x0525: 0x3a12, 0x0526: 0x388a, 0x0527: 0x3a19, 0x0528: 0x3891, 0x0529: 0x3a20, + 0x052a: 0x3075, 0x052b: 0x3386, 0x052c: 0x307f, 0x052d: 0x3395, 0x052e: 0x3093, 0x052f: 0x33a9, + 0x0530: 0x308e, 0x0531: 0x33a4, 0x0532: 0x30cf, 0x0533: 0x33e5, 0x0534: 0x30de, 0x0535: 0x33f4, + 0x0536: 0x30d9, 0x0537: 0x33ef, 0x0538: 0x3898, 0x0539: 0x3a27, 0x053a: 0x389f, 0x053b: 0x3a2e, + 0x053c: 0x30e3, 0x053d: 0x33f9, 0x053e: 0x30e8, 0x053f: 0x33fe, // Block 0x15, offset 0x540 - 0x0540: 0x1826, 0x0541: 0x183e, 0x0542: 0x1eb0, 0x0543: 0x1eb4, 0x0544: 0x216f, 0x0545: 0x2173, - 0x0546: 0x2177, 0x0547: 0x1852, 0x0548: 0x217b, 0x0549: 0x1882, 0x054a: 0x194a, 0x054b: 0x197a, - 0x054c: 0x1976, 0x054d: 0x194e, 0x054e: 0x1abe, 0x054f: 0x18a2, 0x0550: 0x1942, 0x0551: 0x217f, - 0x0552: 0x2183, 0x0553: 0x2187, 0x0554: 0x218b, 0x0555: 0x218f, 0x0556: 0x2193, 0x0557: 0x2197, - 0x0558: 0x219b, 0x0559: 0x219f, 0x055a: 0x21a3, 0x055b: 0x18ba, 0x055c: 0x21a7, 0x055d: 0x21ab, - 0x055e: 0x21af, 0x055f: 0x21b3, 0x0560: 0x21b7, 0x0561: 0x21bb, 0x0562: 0x21bf, 0x0563: 0x21c3, - 0x0564: 0x1eb8, 0x0565: 0x1ebc, 0x0566: 0x1ec0, 0x0567: 0x21c7, 0x0568: 0x21cb, 0x0569: 0x21cf, - 0x056a: 0x21d3, 0x056b: 0x21d7, 0x056c: 0x21db, 0x056d: 0x21df, 0x056e: 0x21e3, 0x056f: 0x21e7, - 0x0570: 0x21eb, 0x0571: 0x21ef, 0x0572: 0x21f2, 0x0573: 0x21f5, 0x0574: 0x21f8, 0x0575: 0x21fb, - 0x0576: 0x21fe, 0x0577: 0x2201, 0x0578: 0x2204, 0x0579: 0x2207, 0x057a: 0x220a, 0x057b: 0x220d, - 0x057c: 0x2210, 0x057d: 0x2213, 0x057e: 0x2216, 0x057f: 0x2219, + 0x0540: 0x30ed, 0x0541: 0x3403, 0x0542: 0x30f2, 0x0543: 0x3408, 0x0544: 0x3101, 0x0545: 0x3417, + 0x0546: 0x30fc, 0x0547: 0x3412, 0x0548: 0x3106, 0x0549: 0x3421, 0x054a: 0x310b, 0x054b: 0x3426, + 0x054c: 0x3110, 0x054d: 0x342b, 0x054e: 0x312e, 0x054f: 0x3449, 0x0550: 0x3147, 0x0551: 0x3467, + 0x0552: 0x3156, 0x0553: 0x3476, 0x0554: 0x315b, 0x0555: 0x347b, 0x0556: 0x325f, 0x0557: 0x338b, + 0x0558: 0x341c, 0x0559: 0x3458, 0x055a: 0x0731, 0x055b: 0x41c3, + 0x0560: 0x4658, 0x0561: 0x46e9, 0x0562: 0x2e68, 0x0563: 0x3174, + 0x0564: 0x375d, 0x0565: 0x38ec, 0x0566: 0x3756, 0x0567: 0x38e5, 0x0568: 0x376b, 0x0569: 0x38fa, + 0x056a: 0x3764, 0x056b: 0x38f3, 0x056c: 0x37a3, 0x056d: 0x3932, 0x056e: 0x3779, 0x056f: 0x3908, + 0x0570: 0x3772, 0x0571: 0x3901, 0x0572: 0x3787, 0x0573: 0x3916, 0x0574: 0x3780, 0x0575: 0x390f, + 0x0576: 0x37aa, 0x0577: 0x3939, 0x0578: 0x466c, 0x0579: 0x46fd, 0x057a: 0x2ee5, 0x057b: 0x31f1, + 0x057c: 0x2ed1, 0x057d: 0x31dd, 0x057e: 0x37bf, 0x057f: 0x394e, // Block 0x16, offset 0x580 - 0x0580: 0x2325, 0x0581: 0x2335, 0x0582: 0x2342, 0x0583: 0x2352, 0x0584: 0x235c, 0x0585: 0x236c, - 0x0586: 0x2376, 0x0587: 0x2380, 0x0588: 0x2393, 0x0589: 0x23a0, 0x058a: 0x23aa, 0x058b: 0x23b4, - 0x058c: 0x23be, 0x058d: 0x23cb, 0x058e: 0x23d8, 0x058f: 0x23e5, 0x0590: 0x23f2, 0x0591: 0x23ff, - 0x0592: 0x240c, 0x0593: 0x2419, 0x0594: 0x242c, 0x0595: 0x2433, 0x0596: 0x2446, 0x0597: 0x2459, - 0x0598: 0x2469, 0x0599: 0x2476, 0x059a: 0x2489, 0x059b: 0x249c, 0x059c: 0x24a9, 0x059d: 0x24b3, - 0x059e: 0x24bd, 0x059f: 0x24ca, 0x05a0: 0x24d7, 0x05a1: 0x24e7, 0x05a2: 0x24f7, 0x05a3: 0x2501, - 0x05a4: 0x250b, 0x05a5: 0x2518, 0x05a6: 0x2522, 0x05a7: 0x252c, 0x05a8: 0x2533, 0x05a9: 0x253a, - 0x05aa: 0x2544, 0x05ab: 0x254e, 0x05ac: 0x2561, 0x05ad: 0x256e, 0x05ae: 0x257e, 0x05af: 0x2591, - 0x05b0: 0x259e, 0x05b1: 0x25a8, 0x05b2: 0x25b2, 0x05b3: 0x25c5, 0x05b4: 0x25d2, 0x05b5: 0x25e5, - 0x05b6: 0x25ef, 0x05b7: 0x25ff, 0x05b8: 0x2609, 0x05b9: 0x2616, 0x05ba: 0x2620, 0x05bb: 0x262d, - 0x05bc: 0x263d, 0x05bd: 0x264a, 0x05be: 0x265a, 0x05bf: 0x2667, + 0x0580: 0x37b8, 0x0581: 0x3947, 0x0582: 0x37cd, 0x0583: 0x395c, 0x0584: 0x37c6, 0x0585: 0x3955, + 0x0586: 0x37e2, 0x0587: 0x3971, 0x0588: 0x2f76, 0x0589: 0x3282, 0x058a: 0x2f8a, 0x058b: 0x3296, + 0x058c: 0x469e, 0x058d: 0x472f, 0x058e: 0x301b, 0x058f: 0x332c, 0x0590: 0x3805, 0x0591: 0x3994, + 0x0592: 0x37fe, 0x0593: 0x398d, 0x0594: 0x3813, 0x0595: 0x39a2, 0x0596: 0x380c, 0x0597: 0x399b, + 0x0598: 0x386e, 0x0599: 0x39fd, 0x059a: 0x3852, 0x059b: 0x39e1, 0x059c: 0x384b, 0x059d: 0x39da, + 0x059e: 0x3860, 0x059f: 0x39ef, 0x05a0: 0x3859, 0x05a1: 0x39e8, 0x05a2: 0x3867, 0x05a3: 0x39f6, + 0x05a4: 0x30ca, 0x05a5: 0x33e0, 0x05a6: 0x30ac, 0x05a7: 0x33c2, 0x05a8: 0x38c9, 0x05a9: 0x3a58, + 0x05aa: 0x38c2, 0x05ab: 0x3a51, 0x05ac: 0x38d7, 0x05ad: 0x3a66, 0x05ae: 0x38d0, 0x05af: 0x3a5f, + 0x05b0: 0x38de, 0x05b1: 0x3a6d, 0x05b2: 0x3115, 0x05b3: 0x3430, 0x05b4: 0x313d, 0x05b5: 0x345d, + 0x05b6: 0x3138, 0x05b7: 0x3453, 0x05b8: 0x3124, 0x05b9: 0x343f, // Block 0x17, offset 0x5c0 - 0x05c0: 0x266e, 0x05c1: 0x267e, 0x05c2: 0x2688, 0x05c3: 0x2692, 0x05c4: 0x269f, 0x05c5: 0x26a9, - 0x05c6: 0x26b3, 0x05c7: 0x26bd, 0x05c8: 0x26cd, 0x05c9: 0x26da, 0x05ca: 0x26e1, 0x05cb: 0x26f4, - 0x05cc: 0x26fe, 0x05cd: 0x270e, 0x05ce: 0x271b, 0x05cf: 0x2728, 0x05d0: 0x2732, 0x05d1: 0x273c, - 0x05d2: 0x2749, 0x05d3: 0x2750, 0x05d4: 0x275d, 0x05d5: 0x276d, 0x05d6: 0x2774, 0x05d7: 0x2787, - 0x05d8: 0x2791, 0x05d9: 0x2796, 0x05da: 0x279b, 0x05db: 0x27a0, 0x05dc: 0x27a5, 0x05dd: 0x27aa, - 0x05de: 0x27af, 0x05df: 0x27b4, 0x05e0: 0x27b9, 0x05e1: 0x27be, 0x05e2: 0x27c3, 0x05e3: 0x27c9, - 0x05e4: 0x27cf, 0x05e5: 0x27d5, 0x05e6: 0x27db, 0x05e7: 0x27e1, 0x05e8: 0x27e7, 0x05e9: 0x27ed, - 0x05ea: 0x27f3, 0x05eb: 0x27f9, 0x05ec: 0x27ff, 0x05ed: 0x2805, 0x05ee: 0x280b, 0x05ef: 0x2811, - 0x05f0: 0x2817, 0x05f1: 0x281d, 0x05f2: 0x2821, 0x05f3: 0x2824, 0x05f4: 0x2827, 0x05f5: 0x282b, - 0x05f6: 0x282e, 0x05f7: 0x2831, 0x05f8: 0x2834, 0x05f9: 0x2838, 0x05fa: 0x283c, 0x05fb: 0x283f, - 0x05fc: 0x2846, 0x05fd: 0x284d, 0x05fe: 0x2854, 0x05ff: 0x285b, + 0x05c0: 0x47bb, 0x05c1: 0x47c1, 0x05c2: 0x48d5, 0x05c3: 0x48ed, 0x05c4: 0x48dd, 0x05c5: 0x48f5, + 0x05c6: 0x48e5, 0x05c7: 0x48fd, 0x05c8: 0x4761, 0x05c9: 0x4767, 0x05ca: 0x4845, 0x05cb: 0x485d, + 0x05cc: 0x484d, 0x05cd: 0x4865, 0x05ce: 0x4855, 0x05cf: 0x486d, 0x05d0: 0x47cd, 0x05d1: 0x47d3, + 0x05d2: 0x3c9d, 0x05d3: 0x3cad, 0x05d4: 0x3ca5, 0x05d5: 0x3cb5, + 0x05d8: 0x476d, 0x05d9: 0x4773, 0x05da: 0x3bcd, 0x05db: 0x3bdd, 0x05dc: 0x3bd5, 0x05dd: 0x3be5, + 0x05e0: 0x47e5, 0x05e1: 0x47eb, 0x05e2: 0x4905, 0x05e3: 0x491d, + 0x05e4: 0x490d, 0x05e5: 0x4925, 0x05e6: 0x4915, 0x05e7: 0x492d, 0x05e8: 0x4779, 0x05e9: 0x477f, + 0x05ea: 0x4875, 0x05eb: 0x488d, 0x05ec: 0x487d, 0x05ed: 0x4895, 0x05ee: 0x4885, 0x05ef: 0x489d, + 0x05f0: 0x47fd, 0x05f1: 0x4803, 0x05f2: 0x3cfd, 0x05f3: 0x3d15, 0x05f4: 0x3d05, 0x05f5: 0x3d1d, + 0x05f6: 0x3d0d, 0x05f7: 0x3d25, 0x05f8: 0x4785, 0x05f9: 0x478b, 0x05fa: 0x3bfd, 0x05fb: 0x3c15, + 0x05fc: 0x3c05, 0x05fd: 0x3c1d, 0x05fe: 0x3c0d, 0x05ff: 0x3c25, // Block 0x18, offset 0x600 - 0x0600: 0x2868, 0x0601: 0x286b, 0x0602: 0x286e, 0x0603: 0x2872, 0x0604: 0x2875, 0x0605: 0x2878, - 0x0606: 0x287b, 0x0607: 0x287e, 0x0608: 0x2881, 0x0609: 0x2885, 0x060a: 0x288a, 0x060b: 0x288d, - 0x060c: 0x2890, 0x060d: 0x2894, 0x060e: 0x2898, 0x060f: 0x289b, 0x0610: 0x289e, 0x0611: 0x28a1, - 0x0612: 0x28a5, 0x0613: 0x28a9, 0x0614: 0x28ad, 0x0615: 0x28b1, 0x0616: 0x28b5, 0x0617: 0x28b8, - 0x0618: 0x28bb, 0x0619: 0x28be, 0x061a: 0x28c1, 0x061b: 0x28c4, 0x061c: 0x28c8, 0x061d: 0x28cb, - 0x061e: 0x28ce, 0x061f: 0x28d1, 0x0620: 0x28d5, 0x0621: 0x28d9, 0x0622: 0x28dc, 0x0623: 0x28e0, - 0x0624: 0x28e4, 0x0625: 0x28e8, 0x0626: 0x28eb, 0x0627: 0x28ef, 0x0628: 0x28f5, 0x0629: 0x28fc, - 0x062a: 0x28ff, 0x062b: 0x2903, 0x062c: 0x2907, 0x062d: 0x290b, 0x062e: 0x290f, 0x062f: 0x2917, - 0x0630: 0x2920, 0x0631: 0x2923, 0x0632: 0x2926, 0x0633: 0x292a, 0x0634: 0x292d, 0x0635: 0x2930, - 0x0636: 0x2933, 0x0637: 0x2937, 0x0638: 0x293a, 0x0639: 0x293d, 0x063a: 0x2940, 0x063b: 0x2943, - 0x063c: 0x2946, 0x063d: 0x294a, 0x063e: 0x294d, 0x063f: 0x2950, + 0x0600: 0x4809, 0x0601: 0x480f, 0x0602: 0x3d2d, 0x0603: 0x3d3d, 0x0604: 0x3d35, 0x0605: 0x3d45, + 0x0608: 0x4791, 0x0609: 0x4797, 0x060a: 0x3c2d, 0x060b: 0x3c3d, + 0x060c: 0x3c35, 0x060d: 0x3c45, 0x0610: 0x481b, 0x0611: 0x4821, + 0x0612: 0x3d65, 0x0613: 0x3d7d, 0x0614: 0x3d6d, 0x0615: 0x3d85, 0x0616: 0x3d75, 0x0617: 0x3d8d, + 0x0619: 0x479d, 0x061b: 0x3c4d, 0x061d: 0x3c55, + 0x061f: 0x3c5d, 0x0620: 0x4833, 0x0621: 0x4839, 0x0622: 0x4935, 0x0623: 0x494d, + 0x0624: 0x493d, 0x0625: 0x4955, 0x0626: 0x4945, 0x0627: 0x495d, 0x0628: 0x47a3, 0x0629: 0x47a9, + 0x062a: 0x48a5, 0x062b: 0x48bd, 0x062c: 0x48ad, 0x062d: 0x48c5, 0x062e: 0x48b5, 0x062f: 0x48cd, + 0x0630: 0x47af, 0x0631: 0x421c, 0x0632: 0x3576, 0x0633: 0x4222, 0x0634: 0x47d9, 0x0635: 0x4228, + 0x0636: 0x3588, 0x0637: 0x422e, 0x0638: 0x35a6, 0x0639: 0x4234, 0x063a: 0x35be, 0x063b: 0x423a, + 0x063c: 0x4827, 0x063d: 0x4240, // Block 0x19, offset 0x640 - 0x0640: 0x2953, 0x0641: 0x2957, 0x0642: 0x295b, 0x0643: 0x2960, 0x0644: 0x2963, 0x0645: 0x2966, - 0x0646: 0x2969, 0x0647: 0x2970, 0x0648: 0x2974, 0x0649: 0x2977, 0x064a: 0x297a, 0x064b: 0x297d, - 0x064c: 0x2980, 0x064d: 0x2983, 0x064e: 0x2986, 0x064f: 0x2989, 0x0650: 0x298c, 0x0651: 0x298f, - 0x0652: 0x2992, 0x0653: 0x2996, 0x0654: 0x2999, 0x0655: 0x299c, 0x0656: 0x29a0, 0x0657: 0x29a4, - 0x0658: 0x29a7, 0x0659: 0x29ac, 0x065a: 0x29b0, 0x065b: 0x29b3, 0x065c: 0x29b6, 0x065d: 0x29b9, - 0x065e: 0x29bc, 0x065f: 0x29c2, 0x0660: 0x29c8, 0x0661: 0x29cd, 0x0662: 0x29d2, 0x0663: 0x29d7, - 0x0664: 0x29dc, 0x0665: 0x29e1, 0x0666: 0x29e6, 0x0667: 0x29eb, 0x0668: 0x29f0, 0x0669: 0x29f5, - 0x066a: 0x29fb, 0x066b: 0x2a01, 0x066c: 0x2a07, 0x066d: 0x2a0d, 0x066e: 0x2a13, 0x066f: 0x2a19, - 0x0670: 0x2a1f, 0x0671: 0x2a25, 0x0672: 0x2a2b, 0x0673: 0x2a31, 0x0674: 0x2a37, 0x0675: 0x2a3d, - 0x0676: 0x2a43, 0x0677: 0x2a49, 0x0678: 0x2a4f, 0x0679: 0x2a55, 0x067a: 0x2a5b, 0x067b: 0x2a61, - 0x067c: 0x2a67, 0x067d: 0x2a6d, 0x067e: 0x2a73, 0x067f: 0x2a79, + 0x0640: 0x3c85, 0x0641: 0x3c8d, 0x0642: 0x4069, 0x0643: 0x4087, 0x0644: 0x4073, 0x0645: 0x4091, + 0x0646: 0x407d, 0x0647: 0x409b, 0x0648: 0x3bbd, 0x0649: 0x3bc5, 0x064a: 0x3fb5, 0x064b: 0x3fd3, + 0x064c: 0x3fbf, 0x064d: 0x3fdd, 0x064e: 0x3fc9, 0x064f: 0x3fe7, 0x0650: 0x3ccd, 0x0651: 0x3cd5, + 0x0652: 0x40a5, 0x0653: 0x40c3, 0x0654: 0x40af, 0x0655: 0x40cd, 0x0656: 0x40b9, 0x0657: 0x40d7, + 0x0658: 0x3bed, 0x0659: 0x3bf5, 0x065a: 0x3ff1, 0x065b: 0x400f, 0x065c: 0x3ffb, 0x065d: 0x4019, + 0x065e: 0x4005, 0x065f: 0x4023, 0x0660: 0x3da5, 0x0661: 0x3dad, 0x0662: 0x40e1, 0x0663: 0x40ff, + 0x0664: 0x40eb, 0x0665: 0x4109, 0x0666: 0x40f5, 0x0667: 0x4113, 0x0668: 0x3c65, 0x0669: 0x3c6d, + 0x066a: 0x402d, 0x066b: 0x404b, 0x066c: 0x4037, 0x066d: 0x4055, 0x066e: 0x4041, 0x066f: 0x405f, + 0x0670: 0x356a, 0x0671: 0x3564, 0x0672: 0x3c75, 0x0673: 0x3570, 0x0674: 0x3c7d, + 0x0676: 0x47c7, 0x0677: 0x3c95, 0x0678: 0x34da, 0x0679: 0x34d4, 0x067a: 0x34c8, 0x067b: 0x41ec, + 0x067c: 0x34e0, 0x067d: 0x4173, 0x067e: 0x0490, 0x067f: 0x4173, // Block 0x1a, offset 0x680 - 0x0680: 0x2fce, 0x0681: 0x2fd2, 0x0682: 0x2fd6, 0x0683: 0x2fda, 0x0684: 0x2fde, 0x0685: 0x2fe2, - 0x0686: 0x2fe6, 0x0687: 0x2fea, 0x0688: 0x2fee, 0x0689: 0x2eed, 0x068a: 0x2ff2, 0x068b: 0x2ef1, - 0x068c: 0x2ff6, 0x068d: 0x2ffa, 0x068e: 0x2ffe, 0x068f: 0x3002, 0x0690: 0x3006, 0x0691: 0x2e6d, - 0x0692: 0x2b15, 0x0693: 0x300a, 0x0694: 0x300e, 0x0695: 0x195a, 0x0696: 0x2c25, 0x0697: 0x2d71, - 0x0698: 0x3012, 0x0699: 0x3016, 0x069a: 0x2f0d, 0x069b: 0x301a, 0x069c: 0x2f11, 0x069d: 0x301e, - 0x069e: 0x3022, 0x069f: 0x3026, 0x06a0: 0x2e75, 0x06a1: 0x302a, 0x06a2: 0x302e, 0x06a3: 0x3032, - 0x06a4: 0x3036, 0x06a5: 0x303a, 0x06a6: 0x2e79, 0x06a7: 0x303e, 0x06a8: 0x3042, 0x06a9: 0x3046, - 0x06aa: 0x304a, 0x06ab: 0x304e, 0x06ac: 0x3052, 0x06ad: 0x2f41, 0x06ae: 0x3056, 0x06af: 0x305a, - 0x06b0: 0x2cb1, 0x06b1: 0x305e, 0x06b2: 0x2f51, 0x06b3: 0x3062, 0x06b4: 0x3066, 0x06b5: 0x306a, - 0x06b6: 0x306e, 0x06b7: 0x3072, 0x06b8: 0x2f65, 0x06b9: 0x3076, 0x06ba: 0x2e99, 0x06bb: 0x307a, - 0x06bc: 0x2f69, 0x06bd: 0x2bd9, 0x06be: 0x307e, 0x06bf: 0x2f6d, + 0x0680: 0x418c, 0x0681: 0x4380, 0x0682: 0x3cbd, 0x0683: 0x3582, 0x0684: 0x3cc5, + 0x0686: 0x47f1, 0x0687: 0x3cdd, 0x0688: 0x34e6, 0x0689: 0x41f2, 0x068a: 0x34f2, 0x068b: 0x41f8, + 0x068c: 0x34fe, 0x068d: 0x4387, 0x068e: 0x438e, 0x068f: 0x4395, 0x0690: 0x359a, 0x0691: 0x3594, + 0x0692: 0x3ce5, 0x0693: 0x43e2, 0x0696: 0x35a0, 0x0697: 0x3cf5, + 0x0698: 0x3516, 0x0699: 0x3510, 0x069a: 0x3504, 0x069b: 0x41fe, 0x069d: 0x439c, + 0x069e: 0x43a3, 0x069f: 0x43aa, 0x06a0: 0x35d0, 0x06a1: 0x35ca, 0x06a2: 0x3d4d, 0x06a3: 0x43ea, + 0x06a4: 0x35b2, 0x06a5: 0x35b8, 0x06a6: 0x35d6, 0x06a7: 0x3d5d, 0x06a8: 0x3546, 0x06a9: 0x3540, + 0x06aa: 0x3534, 0x06ab: 0x420a, 0x06ac: 0x352e, 0x06ad: 0x4372, 0x06ae: 0x4379, 0x06af: 0x014f, + 0x06b2: 0x3d95, 0x06b3: 0x35dc, 0x06b4: 0x3d9d, + 0x06b6: 0x483f, 0x06b7: 0x3db5, 0x06b8: 0x3522, 0x06b9: 0x4204, 0x06ba: 0x3552, 0x06bb: 0x4216, + 0x06bc: 0x355e, 0x06bd: 0x4146, 0x06be: 0x4178, // Block 0x1b, offset 0x6c0 - 0x06c0: 0x3082, 0x06c1: 0x2f75, 0x06c2: 0x3086, 0x06c3: 0x308a, 0x06c4: 0x308e, 0x06c5: 0x3092, - 0x06c6: 0x3096, 0x06c7: 0x2f7d, 0x06c8: 0x2e8d, 0x06c9: 0x309a, 0x06ca: 0x2f81, 0x06cb: 0x309e, - 0x06cc: 0x2f85, 0x06cd: 0x30a2, 0x06ce: 0x1b76, 0x06cf: 0x30a6, 0x06d0: 0x30ab, 0x06d1: 0x30b0, - 0x06d2: 0x30b5, 0x06d3: 0x30b9, 0x06d4: 0x30bd, 0x06d5: 0x30c1, 0x06d6: 0x30c6, 0x06d7: 0x30cb, - 0x06d8: 0x30d0, 0x06d9: 0x30d4, + 0x06c0: 0x0729, 0x06c1: 0x072d, 0x06c2: 0x0115, 0x06c3: 0x07a5, 0x06c5: 0x0739, + 0x06c6: 0x073d, 0x06c7: 0x03a9, 0x06c9: 0x07a9, 0x06ca: 0x015d, 0x06cb: 0x011f, + 0x06cc: 0x011f, 0x06cd: 0x011f, 0x06ce: 0x015f, 0x06cf: 0x039d, 0x06d0: 0x0121, 0x06d1: 0x0121, + 0x06d2: 0x0127, 0x06d3: 0x0167, 0x06d5: 0x012b, 0x06d6: 0x02a7, + 0x06d9: 0x012f, 0x06da: 0x0131, 0x06db: 0x0133, 0x06dc: 0x0133, 0x06dd: 0x0133, + 0x06e0: 0x02b9, 0x06e1: 0x0719, 0x06e2: 0x02c2, + 0x06e4: 0x0143, 0x06e6: 0x0475, 0x06e8: 0x0143, + 0x06ea: 0x0125, 0x06eb: 0x41be, 0x06ec: 0x0113, 0x06ed: 0x0115, 0x06ef: 0x0159, + 0x06f0: 0x0119, 0x06f1: 0x011b, 0x06f3: 0x0129, 0x06f4: 0x016d, 0x06f5: 0x04cc, + 0x06f6: 0x04cf, 0x06f7: 0x04d2, 0x06f8: 0x04d5, 0x06f9: 0x0161, 0x06fb: 0x06e9, + 0x06fc: 0x04a5, 0x06fd: 0x047e, 0x06fe: 0x0436, 0x06ff: 0x045d, // Block 0x1c, offset 0x700 - 0x0700: 0x30d8, 0x0701: 0x30db, 0x0702: 0x30de, 0x0703: 0x30e1, 0x0704: 0x30e5, 0x0705: 0x30e9, - 0x0706: 0x30e9, - 0x0713: 0x30ec, 0x0714: 0x30f1, 0x0715: 0x30f6, 0x0716: 0x30fb, 0x0717: 0x3100, - 0x071d: 0x3105, - 0x071f: 0x310a, 0x0720: 0x310f, 0x0721: 0x14db, 0x0722: 0x14e4, 0x0723: 0x3112, - 0x0724: 0x3115, 0x0725: 0x3118, 0x0726: 0x311b, 0x0727: 0x311e, 0x0728: 0x3121, 0x0729: 0x1494, - 0x072a: 0x3124, 0x072b: 0x3129, 0x072c: 0x312e, 0x072d: 0x3135, 0x072e: 0x313c, 0x072f: 0x3141, - 0x0730: 0x3146, 0x0731: 0x314b, 0x0732: 0x3150, 0x0733: 0x3155, 0x0734: 0x315a, 0x0735: 0x315f, - 0x0736: 0x3164, 0x0738: 0x3169, 0x0739: 0x316e, 0x073a: 0x3173, 0x073b: 0x3178, - 0x073c: 0x317d, 0x073e: 0x3182, + 0x0700: 0x09a1, 0x0705: 0x0117, + 0x0706: 0x0157, 0x0707: 0x0159, 0x0708: 0x0161, 0x0709: 0x0163, + 0x0710: 0x2341, 0x0711: 0x234d, + 0x0712: 0x2401, 0x0713: 0x2329, 0x0714: 0x23ad, 0x0715: 0x2335, 0x0716: 0x23b3, 0x0717: 0x23cb, + 0x0718: 0x23d7, 0x0719: 0x233b, 0x071a: 0x23dd, 0x071b: 0x2347, 0x071c: 0x23d1, 0x071d: 0x23e3, + 0x071e: 0x23e9, 0x071f: 0x1ba9, 0x0720: 0x0121, 0x0721: 0x027a, 0x0722: 0x06f5, 0x0723: 0x0283, + 0x0724: 0x013b, 0x0725: 0x02c5, 0x0726: 0x0721, 0x0727: 0x1c35, 0x0728: 0x0286, 0x0729: 0x013f, + 0x072a: 0x02d1, 0x072b: 0x0725, 0x072c: 0x0127, 0x072d: 0x0115, 0x072e: 0x0117, 0x072f: 0x0129, + 0x0730: 0x0161, 0x0731: 0x02fe, 0x0732: 0x0769, 0x0733: 0x0307, 0x0734: 0x017b, 0x0735: 0x037c, + 0x0736: 0x079d, 0x0737: 0x1c49, 0x0738: 0x030a, 0x0739: 0x017f, 0x073a: 0x037f, 0x073b: 0x07a1, + 0x073c: 0x0167, 0x073d: 0x0155, 0x073e: 0x0157, 0x073f: 0x0169, // Block 0x1d, offset 0x740 - 0x0740: 0x3187, 0x0741: 0x318c, 0x0743: 0x3191, 0x0744: 0x3196, - 0x0746: 0x319b, 0x0747: 0x31a0, 0x0748: 0x31a5, 0x0749: 0x31aa, 0x074a: 0x31af, 0x074b: 0x31b4, - 0x074c: 0x31b9, 0x074d: 0x31be, 0x074e: 0x31c3, 0x074f: 0x31c8, 0x0750: 0x31cd, 0x0751: 0x31cd, - 0x0752: 0x31d0, 0x0753: 0x31d0, 0x0754: 0x31d0, 0x0755: 0x31d0, 0x0756: 0x31d3, 0x0757: 0x31d3, - 0x0758: 0x31d3, 0x0759: 0x31d3, 0x075a: 0x31d6, 0x075b: 0x31d6, 0x075c: 0x31d6, 0x075d: 0x31d6, - 0x075e: 0x31d9, 0x075f: 0x31d9, 0x0760: 0x31d9, 0x0761: 0x31d9, 0x0762: 0x31dc, 0x0763: 0x31dc, - 0x0764: 0x31dc, 0x0765: 0x31dc, 0x0766: 0x31df, 0x0767: 0x31df, 0x0768: 0x31df, 0x0769: 0x31df, - 0x076a: 0x31e2, 0x076b: 0x31e2, 0x076c: 0x31e2, 0x076d: 0x31e2, 0x076e: 0x31e5, 0x076f: 0x31e5, - 0x0770: 0x31e5, 0x0771: 0x31e5, 0x0772: 0x31e8, 0x0773: 0x31e8, 0x0774: 0x31e8, 0x0775: 0x31e8, - 0x0776: 0x31eb, 0x0777: 0x31eb, 0x0778: 0x31eb, 0x0779: 0x31eb, 0x077a: 0x31ee, 0x077b: 0x31ee, - 0x077c: 0x31ee, 0x077d: 0x31ee, 0x077e: 0x31f1, 0x077f: 0x31f1, + 0x0741: 0x3aeb, 0x0743: 0x8800, 0x0744: 0x3af2, 0x0745: 0x8800, + 0x0747: 0x3af9, 0x0748: 0x8800, 0x0749: 0x3b00, + 0x074d: 0x8800, + 0x0760: 0x2e4a, 0x0761: 0x8800, 0x0762: 0x3b0e, + 0x0764: 0x8800, 0x0765: 0x8800, + 0x076d: 0x3b07, 0x076e: 0x2e45, 0x076f: 0x2e4f, + 0x0770: 0x3b15, 0x0771: 0x3b1c, 0x0772: 0x8800, 0x0773: 0x8800, 0x0774: 0x3b23, 0x0775: 0x3b2a, + 0x0776: 0x8800, 0x0777: 0x8800, 0x0778: 0x3b31, 0x0779: 0x3b38, 0x077a: 0x8800, 0x077b: 0x8800, + 0x077c: 0x8800, 0x077d: 0x8800, // Block 0x1e, offset 0x780 - 0x0780: 0x31f1, 0x0781: 0x31f1, 0x0782: 0x31f4, 0x0783: 0x31f4, 0x0784: 0x31f7, 0x0785: 0x31f7, - 0x0786: 0x31fa, 0x0787: 0x31fa, 0x0788: 0x31fd, 0x0789: 0x31fd, 0x078a: 0x3200, 0x078b: 0x3200, - 0x078c: 0x3203, 0x078d: 0x3203, 0x078e: 0x3206, 0x078f: 0x3206, 0x0790: 0x3206, 0x0791: 0x3206, - 0x0792: 0x3209, 0x0793: 0x3209, 0x0794: 0x3209, 0x0795: 0x3209, 0x0796: 0x320c, 0x0797: 0x320c, - 0x0798: 0x320c, 0x0799: 0x320c, 0x079a: 0x320f, 0x079b: 0x320f, 0x079c: 0x320f, 0x079d: 0x320f, - 0x079e: 0x3212, 0x079f: 0x3212, 0x07a0: 0x3215, 0x07a1: 0x3215, 0x07a2: 0x3215, 0x07a3: 0x3215, - 0x07a4: 0x06ba, 0x07a5: 0x06ba, 0x07a6: 0x3218, 0x07a7: 0x3218, 0x07a8: 0x3218, 0x07a9: 0x3218, - 0x07aa: 0x321b, 0x07ab: 0x321b, 0x07ac: 0x321b, 0x07ad: 0x321b, 0x07ae: 0x321e, 0x07af: 0x321e, - 0x07b0: 0x06c4, 0x07b1: 0x06c4, + 0x0780: 0x3b3f, 0x0781: 0x3b46, 0x0782: 0x8800, 0x0783: 0x8800, 0x0784: 0x3b5b, 0x0785: 0x3b62, + 0x0786: 0x8800, 0x0787: 0x8800, 0x0788: 0x3b69, 0x0789: 0x3b70, + 0x0791: 0x8800, + 0x0792: 0x8800, + 0x07a2: 0x8800, + 0x07a8: 0x8800, 0x07a9: 0x8800, + 0x07ab: 0x8800, 0x07ac: 0x3b85, 0x07ad: 0x3b8c, 0x07ae: 0x3b93, 0x07af: 0x3b9a, + 0x07b2: 0x8800, 0x07b3: 0x8800, 0x07b4: 0x8800, 0x07b5: 0x8800, // Block 0x1f, offset 0x7c0 - 0x07d3: 0x3221, 0x07d4: 0x3221, 0x07d5: 0x3221, 0x07d6: 0x3221, 0x07d7: 0x3224, - 0x07d8: 0x3224, 0x07d9: 0x3227, 0x07da: 0x3227, 0x07db: 0x322a, 0x07dc: 0x322a, 0x07dd: 0x06b0, - 0x07de: 0x322d, 0x07df: 0x322d, 0x07e0: 0x3230, 0x07e1: 0x3230, 0x07e2: 0x3233, 0x07e3: 0x3233, - 0x07e4: 0x3236, 0x07e5: 0x3236, 0x07e6: 0x3236, 0x07e7: 0x3236, 0x07e8: 0x3239, 0x07e9: 0x3239, - 0x07ea: 0x323c, 0x07eb: 0x323c, 0x07ec: 0x3243, 0x07ed: 0x3243, 0x07ee: 0x324a, 0x07ef: 0x324a, - 0x07f0: 0x3251, 0x07f1: 0x3251, 0x07f2: 0x3258, 0x07f3: 0x3258, 0x07f4: 0x325f, 0x07f5: 0x325f, - 0x07f6: 0x3266, 0x07f7: 0x3266, 0x07f8: 0x3266, 0x07f9: 0x326d, 0x07fa: 0x326d, 0x07fb: 0x326d, - 0x07fc: 0x3274, 0x07fd: 0x3274, 0x07fe: 0x3274, 0x07ff: 0x3274, + 0x07e0: 0x00f1, 0x07e1: 0x00f3, 0x07e2: 0x00f5, 0x07e3: 0x00f7, + 0x07e4: 0x00f9, 0x07e5: 0x00fb, 0x07e6: 0x00fd, 0x07e7: 0x00ff, 0x07e8: 0x0101, 0x07e9: 0x01a2, + 0x07ea: 0x01a5, 0x07eb: 0x01a8, 0x07ec: 0x01ab, 0x07ed: 0x01ae, 0x07ee: 0x01b1, 0x07ef: 0x01b4, + 0x07f0: 0x01b7, 0x07f1: 0x01ba, 0x07f2: 0x01bd, 0x07f3: 0x01c6, 0x07f4: 0x05b9, 0x07f5: 0x05bd, + 0x07f6: 0x05c1, 0x07f7: 0x05c5, 0x07f8: 0x05c9, 0x07f9: 0x05cd, 0x07fa: 0x05d1, 0x07fb: 0x05d5, + 0x07fc: 0x05d9, 0x07fd: 0x1b6d, 0x07fe: 0x1b72, 0x07ff: 0x1b77, // Block 0x20, offset 0x800 - 0x0800: 0x33ba, 0x0801: 0x33bf, 0x0802: 0x33c4, 0x0803: 0x33c9, 0x0804: 0x33ce, 0x0805: 0x33d3, - 0x0806: 0x33d8, 0x0807: 0x33dd, 0x0808: 0x33e2, 0x0809: 0x33e7, 0x080a: 0x33ec, 0x080b: 0x33f1, - 0x080c: 0x33f6, 0x080d: 0x33fb, 0x080e: 0x3400, 0x080f: 0x3405, 0x0810: 0x340a, 0x0811: 0x340f, - 0x0812: 0x3414, 0x0813: 0x3419, 0x0814: 0x341e, 0x0815: 0x3423, 0x0816: 0x3428, 0x0817: 0x342d, - 0x0818: 0x3432, 0x0819: 0x3437, 0x081a: 0x343c, 0x081b: 0x3441, 0x081c: 0x3446, 0x081d: 0x344b, - 0x081e: 0x3450, 0x081f: 0x3456, 0x0820: 0x345c, 0x0821: 0x3462, 0x0822: 0x3468, 0x0823: 0x346e, - 0x0824: 0x3474, 0x0825: 0x347b, 0x0826: 0x3285, 0x0827: 0x3482, 0x0828: 0x326d, 0x0829: 0x328c, - 0x082a: 0x3489, 0x082b: 0x348e, 0x082c: 0x32a2, 0x082d: 0x3493, 0x082e: 0x32a7, 0x082f: 0x32ac, - 0x0830: 0x3498, 0x0831: 0x349d, 0x0832: 0x32c0, 0x0833: 0x34a2, 0x0834: 0x32c5, 0x0835: 0x32ca, - 0x0836: 0x34a7, 0x0837: 0x34ac, 0x0838: 0x32d4, 0x0839: 0x34b1, 0x083a: 0x32d9, 0x083b: 0x32de, - 0x083c: 0x336f, 0x083d: 0x3374, 0x083e: 0x3383, 0x083f: 0x3388, + 0x0800: 0x1b7c, 0x0801: 0x1b81, 0x0802: 0x1b86, 0x0803: 0x1b8b, 0x0804: 0x1b90, 0x0805: 0x1b95, + 0x0806: 0x1b9a, 0x0807: 0x1b9f, 0x0808: 0x019f, 0x0809: 0x01c3, 0x080a: 0x01e7, 0x080b: 0x020b, + 0x080c: 0x022f, 0x080d: 0x0238, 0x080e: 0x023e, 0x080f: 0x0244, 0x0810: 0x024a, 0x0811: 0x06b1, + 0x0812: 0x06b5, 0x0813: 0x06b9, 0x0814: 0x06bd, 0x0815: 0x06c1, 0x0816: 0x06c5, 0x0817: 0x06c9, + 0x0818: 0x06cd, 0x0819: 0x06d1, 0x081a: 0x06d5, 0x081b: 0x06d9, 0x081c: 0x0645, 0x081d: 0x0649, + 0x081e: 0x064d, 0x081f: 0x0651, 0x0820: 0x0655, 0x0821: 0x0659, 0x0822: 0x065d, 0x0823: 0x0661, + 0x0824: 0x0665, 0x0825: 0x0669, 0x0826: 0x066d, 0x0827: 0x0671, 0x0828: 0x0675, 0x0829: 0x0679, + 0x082a: 0x067d, 0x082b: 0x0681, 0x082c: 0x0685, 0x082d: 0x0689, 0x082e: 0x068d, 0x082f: 0x0691, + 0x0830: 0x0695, 0x0831: 0x0699, 0x0832: 0x069d, 0x0833: 0x06a1, 0x0834: 0x06a5, 0x0835: 0x06a9, + 0x0836: 0x0111, 0x0837: 0x0113, 0x0838: 0x0115, 0x0839: 0x0117, 0x083a: 0x0119, 0x083b: 0x011b, + 0x083c: 0x011d, 0x083d: 0x011f, 0x083e: 0x0121, 0x083f: 0x0123, // Block 0x21, offset 0x840 - 0x0840: 0x338d, 0x0841: 0x33a1, 0x0842: 0x33a6, 0x0843: 0x33ab, 0x0844: 0x33b0, 0x0845: 0x33c4, - 0x0846: 0x33c9, 0x0847: 0x33ce, 0x0848: 0x34b6, 0x0849: 0x33e2, 0x084a: 0x34bb, 0x084b: 0x34c0, - 0x084c: 0x3400, 0x084d: 0x34c5, 0x084e: 0x3405, 0x084f: 0x340a, 0x0850: 0x344b, 0x0851: 0x34ca, - 0x0852: 0x34cf, 0x0853: 0x3432, 0x0854: 0x34d4, 0x0855: 0x3437, 0x0856: 0x343c, 0x0857: 0x3277, - 0x0858: 0x327e, 0x0859: 0x34d9, 0x085a: 0x3285, 0x085b: 0x34e0, 0x085c: 0x3293, 0x085d: 0x3298, - 0x085e: 0x329d, 0x085f: 0x32a2, 0x0860: 0x34e7, 0x0861: 0x32b1, 0x0862: 0x32b6, 0x0863: 0x32bb, - 0x0864: 0x32c0, 0x0865: 0x34ec, 0x0866: 0x32d4, 0x0867: 0x32e3, 0x0868: 0x32e8, 0x0869: 0x32ed, - 0x086a: 0x32f2, 0x086b: 0x32f7, 0x086c: 0x3301, 0x086d: 0x3306, 0x086e: 0x330b, 0x086f: 0x3310, - 0x0870: 0x3315, 0x0871: 0x331a, 0x0872: 0x34f1, 0x0873: 0x331f, 0x0874: 0x3324, 0x0875: 0x3329, - 0x0876: 0x332e, 0x0877: 0x3333, 0x0878: 0x3338, 0x0879: 0x3342, 0x087a: 0x3347, 0x087b: 0x334c, - 0x087c: 0x3351, 0x087d: 0x3356, 0x087e: 0x335b, 0x087f: 0x3360, + 0x0840: 0x0bfd, 0x0841: 0x0c21, 0x0842: 0x0c2d, 0x0843: 0x0c3d, 0x0844: 0x0c45, 0x0845: 0x0c51, + 0x0846: 0x0c59, 0x0847: 0x0c61, 0x0848: 0x0c6d, 0x0849: 0x0cc1, 0x084a: 0x0cd9, 0x084b: 0x0ce9, + 0x084c: 0x0cf9, 0x084d: 0x0d09, 0x084e: 0x0d19, 0x084f: 0x0d39, 0x0850: 0x0d3d, 0x0851: 0x0d41, + 0x0852: 0x0d75, 0x0853: 0x0d9d, 0x0854: 0x0dad, 0x0855: 0x0db5, 0x0856: 0x0db9, 0x0857: 0x0dc5, + 0x0858: 0x0de1, 0x0859: 0x0de5, 0x085a: 0x0dfd, 0x085b: 0x0e01, 0x085c: 0x0e09, 0x085d: 0x0e19, + 0x085e: 0x0eb5, 0x085f: 0x0ec9, 0x0860: 0x0f09, 0x0861: 0x0f1d, 0x0862: 0x0f25, 0x0863: 0x0f29, + 0x0864: 0x0f39, 0x0865: 0x0f55, 0x0866: 0x0f81, 0x0867: 0x0f8d, 0x0868: 0x0fad, 0x0869: 0x0fb9, + 0x086a: 0x0fbd, 0x086b: 0x0fc1, 0x086c: 0x0fd9, 0x086d: 0x0fdd, 0x086e: 0x1009, 0x086f: 0x1015, + 0x0870: 0x101d, 0x0871: 0x1025, 0x0872: 0x1035, 0x0873: 0x103d, 0x0874: 0x1045, 0x0875: 0x1071, + 0x0876: 0x1075, 0x0877: 0x107d, 0x0878: 0x1081, 0x0879: 0x1089, 0x087a: 0x1091, 0x087b: 0x10a1, + 0x087c: 0x10bd, 0x087d: 0x1135, 0x087e: 0x1149, 0x087f: 0x114d, // Block 0x22, offset 0x880 - 0x0880: 0x3365, 0x0881: 0x336a, 0x0882: 0x3379, 0x0883: 0x337e, 0x0884: 0x3392, 0x0885: 0x3397, - 0x0886: 0x339c, 0x0887: 0x33a1, 0x0888: 0x33a6, 0x0889: 0x33b5, 0x088a: 0x33ba, 0x088b: 0x33bf, - 0x088c: 0x33c4, 0x088d: 0x34f6, 0x088e: 0x33d3, 0x088f: 0x33d8, 0x0890: 0x33dd, 0x0891: 0x33e2, - 0x0892: 0x33f1, 0x0893: 0x33f6, 0x0894: 0x33fb, 0x0895: 0x3400, 0x0896: 0x34fb, 0x0897: 0x340f, - 0x0898: 0x3414, 0x0899: 0x3500, 0x089a: 0x3423, 0x089b: 0x3428, 0x089c: 0x342d, 0x089d: 0x3432, - 0x089e: 0x3505, 0x089f: 0x3285, 0x08a0: 0x34e0, 0x08a1: 0x32a2, 0x08a2: 0x34e7, 0x08a3: 0x32c0, - 0x08a4: 0x34ec, 0x08a5: 0x32d4, 0x08a6: 0x350a, 0x08a7: 0x3315, 0x08a8: 0x350f, 0x08a9: 0x3514, - 0x08aa: 0x3519, 0x08ab: 0x33a1, 0x08ac: 0x33a6, 0x08ad: 0x33c4, 0x08ae: 0x3400, 0x08af: 0x34fb, - 0x08b0: 0x3432, 0x08b1: 0x3505, 0x08b2: 0x351e, 0x08b3: 0x3525, 0x08b4: 0x352c, 0x08b5: 0x3533, - 0x08b6: 0x3538, 0x08b7: 0x353d, 0x08b8: 0x3542, 0x08b9: 0x3547, 0x08ba: 0x354c, 0x08bb: 0x3551, - 0x08bc: 0x3556, 0x08bd: 0x355b, 0x08be: 0x3560, 0x08bf: 0x3565, + 0x0880: 0x11cd, 0x0881: 0x11d1, 0x0882: 0x11e5, 0x0883: 0x11e9, 0x0884: 0x11f1, 0x0885: 0x11f9, + 0x0886: 0x1201, 0x0887: 0x120d, 0x0888: 0x1235, 0x0889: 0x1245, 0x088a: 0x1259, 0x088b: 0x12c9, + 0x088c: 0x12d5, 0x088d: 0x12e5, 0x088e: 0x12f1, 0x088f: 0x12fd, 0x0890: 0x1305, 0x0891: 0x1309, + 0x0892: 0x130d, 0x0893: 0x1311, 0x0894: 0x1315, 0x0895: 0x13cd, 0x0896: 0x1415, 0x0897: 0x1421, + 0x0898: 0x1425, 0x0899: 0x1429, 0x089a: 0x142d, 0x089b: 0x1435, 0x089c: 0x1439, 0x089d: 0x144d, + 0x089e: 0x1469, 0x089f: 0x1471, 0x08a0: 0x14b1, 0x08a1: 0x14b5, 0x08a2: 0x14bd, 0x08a3: 0x14c1, + 0x08a4: 0x14c9, 0x08a5: 0x14cd, 0x08a6: 0x14f1, 0x08a7: 0x14f5, 0x08a8: 0x1511, 0x08a9: 0x1515, + 0x08aa: 0x1519, 0x08ab: 0x151d, 0x08ac: 0x1531, 0x08ad: 0x1555, 0x08ae: 0x1559, 0x08af: 0x155d, + 0x08b0: 0x1581, 0x08b1: 0x15c1, 0x08b2: 0x15c5, 0x08b3: 0x15e5, 0x08b4: 0x15f5, 0x08b5: 0x15fd, + 0x08b6: 0x161d, 0x08b7: 0x1641, 0x08b8: 0x1685, 0x08b9: 0x168d, 0x08ba: 0x16a1, 0x08bb: 0x16ad, + 0x08bc: 0x16b5, 0x08bd: 0x16bd, 0x08be: 0x16c1, 0x08bf: 0x16c5, // Block 0x23, offset 0x8c0 - 0x08c0: 0x16c7, 0x08c1: 0x391e, 0x08c2: 0x3922, 0x08c3: 0x3926, 0x08c4: 0x392a, - 0x08c7: 0x392e, 0x08c8: 0x3930, 0x08c9: 0x146c, 0x08ca: 0x146c, 0x08cb: 0x146c, - 0x08cc: 0x146c, 0x08cd: 0x3900, 0x08ce: 0x3900, 0x08cf: 0x3900, 0x08d0: 0x38e0, 0x08d1: 0x38e2, - 0x08d2: 0x143e, 0x08d4: 0x04e1, 0x08d5: 0x38ea, 0x08d6: 0x38ee, 0x08d7: 0x38ec, - 0x08d8: 0x38f8, 0x08d9: 0x149c, 0x08da: 0x149e, 0x08db: 0x3902, 0x08dc: 0x3904, 0x08dd: 0x3906, - 0x08de: 0x390a, 0x08df: 0x3932, 0x08e0: 0x3934, 0x08e1: 0x3936, 0x08e2: 0x1494, 0x08e3: 0x3938, - 0x08e4: 0x393a, 0x08e5: 0x393c, 0x08e6: 0x149a, 0x08e8: 0x393e, 0x08e9: 0x3940, - 0x08ea: 0x3942, 0x08eb: 0x3944, - 0x08f0: 0x3946, 0x08f1: 0x394a, 0x08f2: 0x394f, 0x08f4: 0x3953, - 0x08f6: 0x3957, 0x08f7: 0x395b, 0x08f8: 0x3960, 0x08f9: 0x3964, 0x08fa: 0x3969, 0x08fb: 0x396d, - 0x08fc: 0x3972, 0x08fd: 0x3976, 0x08fe: 0x397b, 0x08ff: 0x397f, + 0x08c0: 0x16dd, 0x08c1: 0x16e1, 0x08c2: 0x16fd, 0x08c3: 0x1705, 0x08c4: 0x170d, 0x08c5: 0x1711, + 0x08c6: 0x171d, 0x08c7: 0x1725, 0x08c8: 0x1729, 0x08c9: 0x172d, 0x08ca: 0x1735, 0x08cb: 0x1739, + 0x08cc: 0x17d9, 0x08cd: 0x17ed, 0x08ce: 0x1821, 0x08cf: 0x1825, 0x08d0: 0x182d, 0x08d1: 0x1859, + 0x08d2: 0x1861, 0x08d3: 0x1869, 0x08d4: 0x1871, 0x08d5: 0x18ad, 0x08d6: 0x18b1, 0x08d7: 0x18b9, + 0x08d8: 0x18bd, 0x08d9: 0x18c1, 0x08da: 0x18ed, 0x08db: 0x18f1, 0x08dc: 0x18f9, 0x08dd: 0x190d, + 0x08de: 0x1911, 0x08df: 0x192d, 0x08e0: 0x1935, 0x08e1: 0x1939, 0x08e2: 0x195d, 0x08e3: 0x1979, + 0x08e4: 0x1989, 0x08e5: 0x198d, 0x08e6: 0x1995, 0x08e7: 0x19c1, 0x08e8: 0x19c5, 0x08e9: 0x19d5, + 0x08ea: 0x19f9, 0x08eb: 0x1a01, 0x08ec: 0x1a11, 0x08ed: 0x1a29, 0x08ee: 0x1a31, 0x08ef: 0x1a35, + 0x08f0: 0x1a39, 0x08f1: 0x1a3d, 0x08f2: 0x1a49, 0x08f3: 0x1a4d, 0x08f4: 0x1a55, 0x08f5: 0x1a71, + 0x08f6: 0x1a75, 0x08f7: 0x1a79, 0x08f8: 0x1a91, 0x08f9: 0x1a95, 0x08fa: 0x1a9d, 0x08fb: 0x1ab1, + 0x08fc: 0x1ab5, 0x08fd: 0x1ab9, 0x08fe: 0x1ac1, 0x08ff: 0x1ac5, // Block 0x24, offset 0x900 - 0x0900: 0x3984, 0x0901: 0x068d, 0x0902: 0x068d, 0x0903: 0x0692, 0x0904: 0x0692, 0x0905: 0x0697, - 0x0906: 0x0697, 0x0907: 0x069c, 0x0908: 0x069c, 0x0909: 0x06a1, 0x090a: 0x06a1, 0x090b: 0x06a1, - 0x090c: 0x06a1, 0x090d: 0x3987, 0x090e: 0x3987, 0x090f: 0x398a, 0x0910: 0x398a, 0x0911: 0x398a, - 0x0912: 0x398a, 0x0913: 0x398d, 0x0914: 0x398d, 0x0915: 0x3990, 0x0916: 0x3990, 0x0917: 0x3990, - 0x0918: 0x3990, 0x0919: 0x3993, 0x091a: 0x3993, 0x091b: 0x3993, 0x091c: 0x3993, 0x091d: 0x3996, - 0x091e: 0x3996, 0x091f: 0x3996, 0x0920: 0x3996, 0x0921: 0x3999, 0x0922: 0x3999, 0x0923: 0x3999, - 0x0924: 0x3999, 0x0925: 0x399c, 0x0926: 0x399c, 0x0927: 0x399c, 0x0928: 0x399c, 0x0929: 0x399f, - 0x092a: 0x399f, 0x092b: 0x39a2, 0x092c: 0x39a2, 0x092d: 0x39a5, 0x092e: 0x39a5, 0x092f: 0x39a8, - 0x0930: 0x39a8, 0x0931: 0x39ab, 0x0932: 0x39ab, 0x0933: 0x39ab, 0x0934: 0x39ab, 0x0935: 0x39ae, - 0x0936: 0x39ae, 0x0937: 0x39ae, 0x0938: 0x39ae, 0x0939: 0x39b1, 0x093a: 0x39b1, 0x093b: 0x39b1, - 0x093c: 0x39b1, 0x093d: 0x39b4, 0x093e: 0x39b4, 0x093f: 0x39b4, + 0x0906: 0x8800, 0x090b: 0x8800, + 0x090c: 0x3ded, 0x090d: 0x8800, 0x090e: 0x3df5, 0x090f: 0x8800, 0x0910: 0x3dfd, 0x0911: 0x8800, + 0x0912: 0x3e05, 0x0913: 0x8800, 0x0914: 0x3e0d, 0x0915: 0x8800, 0x0916: 0x3e15, 0x0917: 0x8800, + 0x0918: 0x3e1d, 0x0919: 0x8800, 0x091a: 0x3e25, 0x091b: 0x8800, 0x091c: 0x3e2d, 0x091d: 0x8800, + 0x091e: 0x3e35, 0x091f: 0x8800, 0x0920: 0x3e3d, 0x0921: 0x8800, 0x0922: 0x3e45, + 0x0924: 0x8800, 0x0925: 0x3e4d, 0x0926: 0x8800, 0x0927: 0x3e55, 0x0928: 0x8800, 0x0929: 0x3e5d, + 0x092f: 0x8800, + 0x0930: 0x3e65, 0x0931: 0x3e6d, 0x0932: 0x8800, 0x0933: 0x3e75, 0x0934: 0x3e7d, 0x0935: 0x8800, + 0x0936: 0x3e85, 0x0937: 0x3e8d, 0x0938: 0x8800, 0x0939: 0x3e95, 0x093a: 0x3e9d, 0x093b: 0x8800, + 0x093c: 0x3ea5, 0x093d: 0x3ead, // Block 0x25, offset 0x940 - 0x0940: 0x39b4, 0x0941: 0x39b7, 0x0942: 0x39b7, 0x0943: 0x39b7, 0x0944: 0x39b7, 0x0945: 0x39ba, - 0x0946: 0x39ba, 0x0947: 0x39ba, 0x0948: 0x39ba, 0x0949: 0x39bd, 0x094a: 0x39bd, 0x094b: 0x39bd, - 0x094c: 0x39bd, 0x094d: 0x39c0, 0x094e: 0x39c0, 0x094f: 0x39c0, 0x0950: 0x39c0, 0x0951: 0x39c3, - 0x0952: 0x39c3, 0x0953: 0x39c3, 0x0954: 0x39c3, 0x0955: 0x39c6, 0x0956: 0x39c6, 0x0957: 0x39c6, - 0x0958: 0x39c6, 0x0959: 0x39c9, 0x095a: 0x39c9, 0x095b: 0x39c9, 0x095c: 0x39c9, 0x095d: 0x39cc, - 0x095e: 0x39cc, 0x095f: 0x39cc, 0x0960: 0x39cc, 0x0961: 0x39cf, 0x0962: 0x39cf, 0x0963: 0x39cf, - 0x0964: 0x39cf, 0x0965: 0x39d2, 0x0966: 0x39d2, 0x0967: 0x39d2, 0x0968: 0x39d2, 0x0969: 0x39d5, - 0x096a: 0x39d5, 0x096b: 0x39d5, 0x096c: 0x39d5, 0x096d: 0x39d8, 0x096e: 0x39d8, 0x096f: 0x3239, - 0x0970: 0x3239, 0x0971: 0x39db, 0x0972: 0x39db, 0x0973: 0x39db, 0x0974: 0x39db, 0x0975: 0x39de, - 0x0976: 0x39de, 0x0977: 0x39e5, 0x0978: 0x39e5, 0x0979: 0x39ec, 0x097a: 0x39ec, 0x097b: 0x39f3, - 0x097c: 0x39f3, + 0x0954: 0x3de5, + 0x0959: 0x8608, 0x095a: 0x8608, 0x095b: 0x41c8, 0x095c: 0x41ce, 0x095d: 0x8800, + 0x095e: 0x3eb5, 0x095f: 0x2830, + 0x0966: 0x8800, + 0x096b: 0x8800, 0x096c: 0x3ec5, 0x096d: 0x8800, 0x096e: 0x3ecd, 0x096f: 0x8800, + 0x0970: 0x3ed5, 0x0971: 0x8800, 0x0972: 0x3edd, 0x0973: 0x8800, 0x0974: 0x3ee5, 0x0975: 0x8800, + 0x0976: 0x3eed, 0x0977: 0x8800, 0x0978: 0x3ef5, 0x0979: 0x8800, 0x097a: 0x3efd, 0x097b: 0x8800, + 0x097c: 0x3f05, 0x097d: 0x8800, 0x097e: 0x3f0d, 0x097f: 0x8800, // Block 0x26, offset 0x980 - 0x0981: 0x38ec, 0x0982: 0x39f8, 0x0983: 0x3932, 0x0984: 0x3940, 0x0985: 0x3942, - 0x0986: 0x3934, 0x0987: 0x39fa, 0x0988: 0x149c, 0x0989: 0x149e, 0x098a: 0x3936, 0x098b: 0x1494, - 0x098c: 0x38e0, 0x098d: 0x3938, 0x098e: 0x143e, 0x098f: 0x39fc, 0x0990: 0x1486, 0x0991: 0x001c, - 0x0992: 0x000d, 0x0993: 0x000f, 0x0994: 0x1488, 0x0995: 0x148a, 0x0996: 0x148c, 0x0997: 0x148e, - 0x0998: 0x1490, 0x0999: 0x1492, 0x099a: 0x38ea, 0x099b: 0x04e1, 0x099c: 0x393a, 0x099d: 0x149a, - 0x099e: 0x393c, 0x099f: 0x38ee, 0x09a0: 0x3944, 0x09a1: 0x0906, 0x09a2: 0x090b, 0x09a3: 0x14ad, - 0x09a4: 0x090d, 0x09a5: 0x090f, 0x09a6: 0x14d9, 0x09a7: 0x0914, 0x09a8: 0x0916, 0x09a9: 0x0918, - 0x09aa: 0x091a, 0x09ab: 0x091c, 0x09ac: 0x091e, 0x09ad: 0x0920, 0x09ae: 0x0922, 0x09af: 0x0924, - 0x09b0: 0x0929, 0x09b1: 0x14c8, 0x09b2: 0x092b, 0x09b3: 0x17f6, 0x09b4: 0x092d, 0x09b5: 0x092f, - 0x09b6: 0x155f, 0x09b7: 0x0931, 0x09b8: 0x1570, 0x09b9: 0x17f8, 0x09ba: 0x14d4, 0x09bb: 0x392e, - 0x09bc: 0x393e, 0x09bd: 0x3930, 0x09be: 0x39fe, 0x09bf: 0x3900, + 0x0980: 0x3f15, 0x0981: 0x8800, 0x0982: 0x3f1d, 0x0984: 0x8800, 0x0985: 0x3f25, + 0x0986: 0x8800, 0x0987: 0x3f2d, 0x0988: 0x8800, 0x0989: 0x3f35, + 0x098f: 0x8800, 0x0990: 0x3f3d, 0x0991: 0x3f45, + 0x0992: 0x8800, 0x0993: 0x3f4d, 0x0994: 0x3f55, 0x0995: 0x8800, 0x0996: 0x3f5d, 0x0997: 0x3f65, + 0x0998: 0x8800, 0x0999: 0x3f6d, 0x099a: 0x3f75, 0x099b: 0x8800, 0x099c: 0x3f7d, 0x099d: 0x3f85, + 0x09af: 0x8800, + 0x09b0: 0x8800, 0x09b1: 0x8800, 0x09b2: 0x8800, 0x09b4: 0x3ebd, + 0x09b7: 0x3f8d, 0x09b8: 0x3f95, 0x09b9: 0x3f9d, 0x09ba: 0x3fa5, + 0x09bd: 0x8800, 0x09be: 0x3fad, 0x09bf: 0x2845, // Block 0x27, offset 0x9c0 - 0x09c0: 0x13f7, 0x09c1: 0x0007, 0x09c2: 0x093d, 0x09c3: 0x0984, 0x09c4: 0x093f, 0x09c5: 0x0941, - 0x09c6: 0x098c, 0x09c7: 0x094c, 0x09c8: 0x0494, 0x09c9: 0x097c, 0x09ca: 0x0499, 0x09cb: 0x094e, - 0x09cc: 0x04c5, 0x09cd: 0x0950, 0x09ce: 0x14a0, 0x09cf: 0x001e, 0x09d0: 0x0960, 0x09d1: 0x17fa, - 0x09d2: 0x049b, 0x09d3: 0x02c8, 0x09d4: 0x0962, 0x09d5: 0x0964, 0x09d6: 0x096d, 0x09d7: 0x04a6, - 0x09d8: 0x04c7, 0x09d9: 0x04a8, 0x09da: 0x09df, 0x09db: 0x3902, 0x09dc: 0x3a00, 0x09dd: 0x3904, - 0x09de: 0x3a02, 0x09df: 0x3a04, 0x09e0: 0x3a08, 0x09e1: 0x38e6, 0x09e2: 0x391e, 0x09e3: 0x3922, - 0x09e4: 0x38e2, 0x09e5: 0x3a0c, 0x09e6: 0x2321, 0x09e7: 0x3a10, 0x09e8: 0x3a14, 0x09e9: 0x3a18, - 0x09ea: 0x3a1c, 0x09eb: 0x3a20, 0x09ec: 0x3a24, 0x09ed: 0x3a28, 0x09ee: 0x3a2c, 0x09ef: 0x3a30, - 0x09f0: 0x3a34, 0x09f1: 0x2269, 0x09f2: 0x226d, 0x09f3: 0x2271, 0x09f4: 0x2275, 0x09f5: 0x2279, - 0x09f6: 0x227d, 0x09f7: 0x2281, 0x09f8: 0x2285, 0x09f9: 0x2289, 0x09fa: 0x228d, 0x09fb: 0x2291, - 0x09fc: 0x2295, 0x09fd: 0x2299, 0x09fe: 0x229d, 0x09ff: 0x22a1, + 0x09c0: 0x0875, 0x09c1: 0x0879, 0x09c2: 0x0949, 0x09c3: 0x094d, 0x09c4: 0x087d, 0x09c5: 0x0881, + 0x09c6: 0x0885, 0x09c7: 0x08e1, 0x09c8: 0x08e5, 0x09c9: 0x08e9, 0x09ca: 0x08ed, 0x09cb: 0x08f1, + 0x09cc: 0x08f5, 0x09cd: 0x08f9, 0x09ce: 0x08fd, + 0x09d2: 0x0bfd, 0x09d3: 0x0c59, 0x09d4: 0x0c09, 0x09d5: 0x0eb9, 0x09d6: 0x0c0d, 0x09d7: 0x0c25, + 0x09d8: 0x0c11, 0x09d9: 0x14d1, 0x09da: 0x0c45, 0x09db: 0x0c19, 0x09dc: 0x0c01, 0x09dd: 0x0f3d, + 0x09de: 0x0ecd, 0x09df: 0x0c6d, // Block 0x28, offset 0xa00 - 0x0a00: 0x0906, 0x0a01: 0x090b, 0x0a02: 0x14ad, 0x0a03: 0x090d, 0x0a04: 0x090f, 0x0a05: 0x14d9, - 0x0a06: 0x0914, 0x0a07: 0x0916, 0x0a08: 0x0918, 0x0a09: 0x091a, 0x0a0a: 0x091c, 0x0a0b: 0x091e, - 0x0a0c: 0x0920, 0x0a0d: 0x0922, 0x0a0e: 0x0924, 0x0a0f: 0x0929, 0x0a10: 0x14c8, 0x0a11: 0x092b, - 0x0a12: 0x17f6, 0x0a13: 0x092d, 0x0a14: 0x092f, 0x0a15: 0x155f, 0x0a16: 0x0931, 0x0a17: 0x1570, - 0x0a18: 0x17f8, 0x0a19: 0x14d4, 0x0a1a: 0x0007, 0x0a1b: 0x093d, 0x0a1c: 0x0984, 0x0a1d: 0x093f, - 0x0a1e: 0x0941, 0x0a1f: 0x098c, 0x0a20: 0x094c, 0x0a21: 0x0494, 0x0a22: 0x097c, 0x0a23: 0x0499, - 0x0a24: 0x094e, 0x0a25: 0x04c5, 0x0a26: 0x0950, 0x0a27: 0x14a0, 0x0a28: 0x001e, 0x0a29: 0x0960, - 0x0a2a: 0x17fa, 0x0a2b: 0x049b, 0x0a2c: 0x02c8, 0x0a2d: 0x0962, 0x0a2e: 0x0964, 0x0a2f: 0x096d, - 0x0a30: 0x04a6, 0x0a31: 0x04c7, 0x0a32: 0x04a8, 0x0a33: 0x09df, 0x0a34: 0x0906, 0x0a35: 0x090b, - 0x0a36: 0x14ad, 0x0a37: 0x090d, 0x0a38: 0x090f, 0x0a39: 0x14d9, 0x0a3a: 0x0914, 0x0a3b: 0x0916, - 0x0a3c: 0x0918, 0x0a3d: 0x091a, 0x0a3e: 0x091c, 0x0a3f: 0x091e, + 0x0a00: 0x2167, 0x0a01: 0x216d, 0x0a02: 0x2173, 0x0a03: 0x2179, 0x0a04: 0x217f, 0x0a05: 0x2185, + 0x0a06: 0x218b, 0x0a07: 0x2191, 0x0a08: 0x2197, 0x0a09: 0x219d, 0x0a0a: 0x21a3, 0x0a0b: 0x21a9, + 0x0a0c: 0x21af, 0x0a0d: 0x21b5, 0x0a0e: 0x28a2, 0x0a0f: 0x28ab, 0x0a10: 0x28b4, 0x0a11: 0x28bd, + 0x0a12: 0x28c6, 0x0a13: 0x28cf, 0x0a14: 0x28d8, 0x0a15: 0x28e1, 0x0a16: 0x28ea, 0x0a17: 0x28fc, + 0x0a18: 0x2905, 0x0a19: 0x290e, 0x0a1a: 0x2917, 0x0a1b: 0x2920, 0x0a1c: 0x28f3, 0x0a1d: 0x2d45, + 0x0a1e: 0x2c76, 0x0a20: 0x21bb, 0x0a21: 0x21d3, 0x0a22: 0x21c7, 0x0a23: 0x221b, + 0x0a24: 0x21d9, 0x0a25: 0x21f7, 0x0a26: 0x21c1, 0x0a27: 0x21f1, 0x0a28: 0x21cd, 0x0a29: 0x2203, + 0x0a2a: 0x2233, 0x0a2b: 0x2251, 0x0a2c: 0x224b, 0x0a2d: 0x223f, 0x0a2e: 0x228d, 0x0a2f: 0x2221, + 0x0a30: 0x222d, 0x0a31: 0x2245, 0x0a32: 0x2239, 0x0a33: 0x2263, 0x0a34: 0x220f, 0x0a35: 0x2257, + 0x0a36: 0x2281, 0x0a37: 0x2269, 0x0a38: 0x21fd, 0x0a39: 0x21df, 0x0a3a: 0x2215, 0x0a3b: 0x2227, + 0x0a3c: 0x225d, 0x0a3d: 0x21e5, 0x0a3e: 0x2287, 0x0a3f: 0x2209, // Block 0x29, offset 0xa40 - 0x0a40: 0x0920, 0x0a41: 0x0922, 0x0a42: 0x0924, 0x0a43: 0x0929, 0x0a44: 0x14c8, 0x0a45: 0x092b, - 0x0a46: 0x17f6, 0x0a47: 0x092d, 0x0a48: 0x092f, 0x0a49: 0x155f, 0x0a4a: 0x0931, 0x0a4b: 0x1570, - 0x0a4c: 0x17f8, 0x0a4d: 0x14d4, 0x0a4e: 0x0007, 0x0a4f: 0x093d, 0x0a50: 0x0984, 0x0a51: 0x093f, - 0x0a52: 0x0941, 0x0a53: 0x098c, 0x0a54: 0x094c, 0x0a56: 0x097c, 0x0a57: 0x0499, - 0x0a58: 0x094e, 0x0a59: 0x04c5, 0x0a5a: 0x0950, 0x0a5b: 0x14a0, 0x0a5c: 0x001e, 0x0a5d: 0x0960, - 0x0a5e: 0x17fa, 0x0a5f: 0x049b, 0x0a60: 0x02c8, 0x0a61: 0x0962, 0x0a62: 0x0964, 0x0a63: 0x096d, - 0x0a64: 0x04a6, 0x0a65: 0x04c7, 0x0a66: 0x04a8, 0x0a67: 0x09df, 0x0a68: 0x0906, 0x0a69: 0x090b, - 0x0a6a: 0x14ad, 0x0a6b: 0x090d, 0x0a6c: 0x090f, 0x0a6d: 0x14d9, 0x0a6e: 0x0914, 0x0a6f: 0x0916, - 0x0a70: 0x0918, 0x0a71: 0x091a, 0x0a72: 0x091c, 0x0a73: 0x091e, 0x0a74: 0x0920, 0x0a75: 0x0922, - 0x0a76: 0x0924, 0x0a77: 0x0929, 0x0a78: 0x14c8, 0x0a79: 0x092b, 0x0a7a: 0x17f6, 0x0a7b: 0x092d, - 0x0a7c: 0x092f, 0x0a7d: 0x155f, 0x0a7e: 0x0931, 0x0a7f: 0x1570, + 0x0a40: 0x226f, 0x0a41: 0x21eb, 0x0a42: 0x2275, 0x0a43: 0x227b, 0x0a44: 0x0e6d, 0x0a45: 0x1041, + 0x0a46: 0x11e5, 0x0a47: 0x1605, + 0x0a50: 0x0715, 0x0a51: 0x01c9, + 0x0a52: 0x01cc, 0x0a53: 0x01cf, 0x0a54: 0x01d2, 0x0a55: 0x01d5, 0x0a56: 0x01d8, 0x0a57: 0x01db, + 0x0a58: 0x01de, 0x0a59: 0x01e1, 0x0a5a: 0x01ea, 0x0a5b: 0x01ed, 0x0a5c: 0x01f0, 0x0a5d: 0x01f3, + 0x0a5e: 0x01f6, 0x0a5f: 0x01f9, 0x0a60: 0x07d9, 0x0a61: 0x07e1, 0x0a62: 0x07e5, 0x0a63: 0x07ed, + 0x0a64: 0x07f1, 0x0a65: 0x07f5, 0x0a66: 0x07fd, 0x0a67: 0x0805, 0x0a68: 0x0809, 0x0a69: 0x0811, + 0x0a6a: 0x0815, 0x0a6b: 0x0819, 0x0a6c: 0x081d, 0x0a6d: 0x0821, 0x0a6e: 0x27a4, 0x0a6f: 0x27ab, + 0x0a70: 0x27b2, 0x0a71: 0x27b9, 0x0a72: 0x27c0, 0x0a73: 0x27c7, 0x0a74: 0x27ce, 0x0a75: 0x27d5, + 0x0a76: 0x27e3, 0x0a77: 0x27ea, 0x0a78: 0x27f1, 0x0a79: 0x27f8, 0x0a7a: 0x27ff, 0x0a7b: 0x2806, + 0x0a7c: 0x2c95, 0x0a7d: 0x2b0a, 0x0a7e: 0x27dc, // Block 0x2a, offset 0xa80 - 0x0a80: 0x17f8, 0x0a81: 0x14d4, 0x0a82: 0x0007, 0x0a83: 0x093d, 0x0a84: 0x0984, 0x0a85: 0x093f, - 0x0a86: 0x0941, 0x0a87: 0x098c, 0x0a88: 0x094c, 0x0a89: 0x0494, 0x0a8a: 0x097c, 0x0a8b: 0x0499, - 0x0a8c: 0x094e, 0x0a8d: 0x04c5, 0x0a8e: 0x0950, 0x0a8f: 0x14a0, 0x0a90: 0x001e, 0x0a91: 0x0960, - 0x0a92: 0x17fa, 0x0a93: 0x049b, 0x0a94: 0x02c8, 0x0a95: 0x0962, 0x0a96: 0x0964, 0x0a97: 0x096d, - 0x0a98: 0x04a6, 0x0a99: 0x04c7, 0x0a9a: 0x04a8, 0x0a9b: 0x09df, 0x0a9c: 0x0906, - 0x0a9e: 0x14ad, 0x0a9f: 0x090d, 0x0aa2: 0x0914, - 0x0aa5: 0x091a, 0x0aa6: 0x091c, 0x0aa9: 0x0922, - 0x0aaa: 0x0924, 0x0aab: 0x0929, 0x0aac: 0x14c8, 0x0aae: 0x17f6, 0x0aaf: 0x092d, - 0x0ab0: 0x092f, 0x0ab1: 0x155f, 0x0ab2: 0x0931, 0x0ab3: 0x1570, 0x0ab4: 0x17f8, 0x0ab5: 0x14d4, - 0x0ab6: 0x0007, 0x0ab7: 0x093d, 0x0ab8: 0x0984, 0x0ab9: 0x093f, 0x0abb: 0x098c, - 0x0abd: 0x0494, 0x0abe: 0x097c, 0x0abf: 0x0499, + 0x0a80: 0x0bfd, 0x0a81: 0x0c59, 0x0a82: 0x0c09, 0x0a83: 0x0eb9, 0x0a84: 0x0c5d, 0x0a85: 0x0ced, + 0x0a86: 0x0c05, 0x0a87: 0x0ce9, 0x0a88: 0x0c49, 0x0a89: 0x0dc5, 0x0a8a: 0x1245, 0x0a8b: 0x13cd, + 0x0a8c: 0x1315, 0x0a8d: 0x1259, 0x0a8e: 0x1995, 0x0a8f: 0x0ec9, 0x0a90: 0x120d, 0x0a91: 0x1289, + 0x0a92: 0x1249, 0x0a93: 0x1589, 0x0a94: 0x0e39, 0x0a95: 0x1441, 0x0a96: 0x18c5, 0x0a97: 0x159d, + 0x0a98: 0x0d81, 0x0a99: 0x15cd, 0x0a9a: 0x14d9, 0x0a9b: 0x0f55, 0x0a9c: 0x194d, 0x0a9d: 0x0cbd, + 0x0a9e: 0x0de9, 0x0a9f: 0x1335, 0x0aa0: 0x1a59, 0x0aa1: 0x0c81, 0x0aa2: 0x0d11, 0x0aa3: 0x12d9, + 0x0aa4: 0x0c0d, 0x0aa5: 0x0c25, 0x0aa6: 0x0c11, 0x0aa7: 0x1019, 0x0aa8: 0x0e2d, 0x0aa9: 0x0dbd, + 0x0aaa: 0x0f95, 0x0aab: 0x0f89, 0x0aac: 0x1529, 0x0aad: 0x0c7d, 0x0aae: 0x18d9, 0x0aaf: 0x0dd9, + 0x0ab0: 0x0f31, 0x0ab1: 0x01fc, 0x0ab2: 0x01ff, 0x0ab3: 0x0202, 0x0ab4: 0x0205, 0x0ab5: 0x020e, + 0x0ab6: 0x0211, 0x0ab7: 0x0214, 0x0ab8: 0x0217, 0x0ab9: 0x021a, 0x0aba: 0x021d, 0x0abb: 0x0220, + 0x0abc: 0x0223, 0x0abd: 0x0226, 0x0abe: 0x0229, 0x0abf: 0x0232, // Block 0x2b, offset 0xac0 - 0x0ac0: 0x094e, 0x0ac1: 0x04c5, 0x0ac2: 0x0950, 0x0ac3: 0x14a0, 0x0ac5: 0x0960, - 0x0ac6: 0x17fa, 0x0ac7: 0x049b, 0x0ac8: 0x02c8, 0x0ac9: 0x0962, 0x0aca: 0x0964, 0x0acb: 0x096d, - 0x0acc: 0x04a6, 0x0acd: 0x04c7, 0x0ace: 0x04a8, 0x0acf: 0x09df, 0x0ad0: 0x0906, 0x0ad1: 0x090b, - 0x0ad2: 0x14ad, 0x0ad3: 0x090d, 0x0ad4: 0x090f, 0x0ad5: 0x14d9, 0x0ad6: 0x0914, 0x0ad7: 0x0916, - 0x0ad8: 0x0918, 0x0ad9: 0x091a, 0x0ada: 0x091c, 0x0adb: 0x091e, 0x0adc: 0x0920, 0x0add: 0x0922, - 0x0ade: 0x0924, 0x0adf: 0x0929, 0x0ae0: 0x14c8, 0x0ae1: 0x092b, 0x0ae2: 0x17f6, 0x0ae3: 0x092d, - 0x0ae4: 0x092f, 0x0ae5: 0x155f, 0x0ae6: 0x0931, 0x0ae7: 0x1570, 0x0ae8: 0x17f8, 0x0ae9: 0x14d4, - 0x0aea: 0x0007, 0x0aeb: 0x093d, 0x0aec: 0x0984, 0x0aed: 0x093f, 0x0aee: 0x0941, 0x0aef: 0x098c, - 0x0af0: 0x094c, 0x0af1: 0x0494, 0x0af2: 0x097c, 0x0af3: 0x0499, 0x0af4: 0x094e, 0x0af5: 0x04c5, - 0x0af6: 0x0950, 0x0af7: 0x14a0, 0x0af8: 0x001e, 0x0af9: 0x0960, 0x0afa: 0x17fa, 0x0afb: 0x049b, - 0x0afc: 0x02c8, 0x0afd: 0x0962, 0x0afe: 0x0964, 0x0aff: 0x096d, + 0x0ac0: 0x1bb3, 0x0ac1: 0x1bc2, 0x0ac2: 0x1bd1, 0x0ac3: 0x1be0, 0x0ac4: 0x1bef, 0x0ac5: 0x1bfe, + 0x0ac6: 0x1c0d, 0x0ac7: 0x1c1c, 0x0ac8: 0x1c2b, 0x0ac9: 0x229f, 0x0aca: 0x22b1, 0x0acb: 0x22c3, + 0x0acc: 0x0274, 0x0acd: 0x0755, 0x0ace: 0x02ec, 0x0acf: 0x06f9, 0x0ad0: 0x0a09, 0x0ad1: 0x0a11, + 0x0ad2: 0x0a19, 0x0ad3: 0x0a21, 0x0ad4: 0x0a29, 0x0ad5: 0x0a2d, 0x0ad6: 0x0a31, 0x0ad7: 0x0a35, + 0x0ad8: 0x0a39, 0x0ad9: 0x0a3d, 0x0ada: 0x0a41, 0x0adb: 0x0a45, 0x0adc: 0x0a49, 0x0add: 0x0a4d, + 0x0ade: 0x0a51, 0x0adf: 0x0a55, 0x0ae0: 0x0a59, 0x0ae1: 0x0a61, 0x0ae2: 0x0a65, 0x0ae3: 0x0a69, + 0x0ae4: 0x0a6d, 0x0ae5: 0x0a71, 0x0ae6: 0x0a75, 0x0ae7: 0x0a79, 0x0ae8: 0x0a7d, 0x0ae9: 0x0a81, + 0x0aea: 0x0a85, 0x0aeb: 0x0a89, 0x0aec: 0x0a8d, 0x0aed: 0x0a91, 0x0aee: 0x0a95, 0x0aef: 0x0a99, + 0x0af0: 0x0a9d, 0x0af1: 0x0aa1, 0x0af2: 0x0aa5, 0x0af3: 0x0aad, 0x0af4: 0x0ab5, 0x0af5: 0x0abd, + 0x0af6: 0x0ac1, 0x0af7: 0x0ac5, 0x0af8: 0x0ac9, 0x0af9: 0x0acd, 0x0afa: 0x0ad1, 0x0afb: 0x0ad5, + 0x0afc: 0x0ad9, 0x0afd: 0x0add, 0x0afe: 0x0ae1, // Block 0x2c, offset 0xb00 - 0x0b00: 0x04a6, 0x0b01: 0x04c7, 0x0b02: 0x04a8, 0x0b03: 0x09df, 0x0b04: 0x0906, 0x0b05: 0x090b, - 0x0b07: 0x090d, 0x0b08: 0x090f, 0x0b09: 0x14d9, 0x0b0a: 0x0914, - 0x0b0d: 0x091a, 0x0b0e: 0x091c, 0x0b0f: 0x091e, 0x0b10: 0x0920, 0x0b11: 0x0922, - 0x0b12: 0x0924, 0x0b13: 0x0929, 0x0b14: 0x14c8, 0x0b16: 0x17f6, 0x0b17: 0x092d, - 0x0b18: 0x092f, 0x0b19: 0x155f, 0x0b1a: 0x0931, 0x0b1b: 0x1570, 0x0b1c: 0x17f8, - 0x0b1e: 0x0007, 0x0b1f: 0x093d, 0x0b20: 0x0984, 0x0b21: 0x093f, 0x0b22: 0x0941, 0x0b23: 0x098c, - 0x0b24: 0x094c, 0x0b25: 0x0494, 0x0b26: 0x097c, 0x0b27: 0x0499, 0x0b28: 0x094e, 0x0b29: 0x04c5, - 0x0b2a: 0x0950, 0x0b2b: 0x14a0, 0x0b2c: 0x001e, 0x0b2d: 0x0960, 0x0b2e: 0x17fa, 0x0b2f: 0x049b, - 0x0b30: 0x02c8, 0x0b31: 0x0962, 0x0b32: 0x0964, 0x0b33: 0x096d, 0x0b34: 0x04a6, 0x0b35: 0x04c7, - 0x0b36: 0x04a8, 0x0b37: 0x09df, 0x0b38: 0x0906, 0x0b39: 0x090b, 0x0b3b: 0x090d, - 0x0b3c: 0x090f, 0x0b3d: 0x14d9, 0x0b3e: 0x0914, + 0x0b00: 0x2ca5, 0x0b01: 0x2b31, 0x0b02: 0x2cb5, 0x0b03: 0x29fc, 0x0b04: 0x45d3, 0x0b05: 0x2a06, + 0x0b06: 0x2a10, 0x0b07: 0x4617, 0x0b08: 0x2b3e, 0x0b09: 0x2a1a, 0x0b0a: 0x2a24, 0x0b0b: 0x2a2e, + 0x0b0c: 0x2b65, 0x0b0d: 0x2b72, 0x0b0e: 0x2b4b, 0x0b0f: 0x2b58, 0x0b10: 0x452b, 0x0b11: 0x2b7f, + 0x0b12: 0x2b8c, 0x0b13: 0x2d57, 0x0b14: 0x2837, 0x0b15: 0x2d6a, 0x0b16: 0x2d7d, 0x0b17: 0x2cc5, + 0x0b18: 0x2b99, 0x0b19: 0x2d90, 0x0b1a: 0x2da3, 0x0b1b: 0x2ba6, 0x0b1c: 0x2a38, 0x0b1d: 0x2a42, + 0x0b1e: 0x4539, 0x0b1f: 0x2bb3, 0x0b20: 0x2cd5, 0x0b21: 0x45e4, 0x0b22: 0x2a4c, 0x0b23: 0x2a56, + 0x0b24: 0x2bc0, 0x0b25: 0x2a60, 0x0b26: 0x2a6a, 0x0b27: 0x284c, 0x0b28: 0x2853, 0x0b29: 0x2a74, + 0x0b2a: 0x2a7e, 0x0b2b: 0x2db6, 0x0b2c: 0x2bcd, 0x0b2d: 0x2ce5, 0x0b2e: 0x2dc9, 0x0b2f: 0x2bda, + 0x0b30: 0x2a92, 0x0b31: 0x2a88, 0x0b32: 0x462b, 0x0b33: 0x2be7, 0x0b34: 0x2ddc, 0x0b35: 0x2a9c, + 0x0b36: 0x2cf5, 0x0b37: 0x2aa6, 0x0b38: 0x2c01, 0x0b39: 0x2ab0, 0x0b3a: 0x2c0e, 0x0b3b: 0x45f5, + 0x0b3c: 0x2bf4, 0x0b3d: 0x2d05, 0x0b3e: 0x2c1b, 0x0b3f: 0x285a, // Block 0x2d, offset 0xb40 - 0x0b40: 0x0918, 0x0b41: 0x091a, 0x0b42: 0x091c, 0x0b43: 0x091e, 0x0b44: 0x0920, - 0x0b46: 0x0924, 0x0b4a: 0x17f6, 0x0b4b: 0x092d, - 0x0b4c: 0x092f, 0x0b4d: 0x155f, 0x0b4e: 0x0931, 0x0b4f: 0x1570, 0x0b50: 0x17f8, - 0x0b52: 0x0007, 0x0b53: 0x093d, 0x0b54: 0x0984, 0x0b55: 0x093f, 0x0b56: 0x0941, 0x0b57: 0x098c, - 0x0b58: 0x094c, 0x0b59: 0x0494, 0x0b5a: 0x097c, 0x0b5b: 0x0499, 0x0b5c: 0x094e, 0x0b5d: 0x04c5, - 0x0b5e: 0x0950, 0x0b5f: 0x14a0, 0x0b60: 0x001e, 0x0b61: 0x0960, 0x0b62: 0x17fa, 0x0b63: 0x049b, - 0x0b64: 0x02c8, 0x0b65: 0x0962, 0x0b66: 0x0964, 0x0b67: 0x096d, 0x0b68: 0x04a6, 0x0b69: 0x04c7, - 0x0b6a: 0x04a8, 0x0b6b: 0x09df, 0x0b6c: 0x0906, 0x0b6d: 0x090b, 0x0b6e: 0x14ad, 0x0b6f: 0x090d, - 0x0b70: 0x090f, 0x0b71: 0x14d9, 0x0b72: 0x0914, 0x0b73: 0x0916, 0x0b74: 0x0918, 0x0b75: 0x091a, - 0x0b76: 0x091c, 0x0b77: 0x091e, 0x0b78: 0x0920, 0x0b79: 0x0922, 0x0b7a: 0x0924, 0x0b7b: 0x0929, - 0x0b7c: 0x14c8, 0x0b7d: 0x092b, 0x0b7e: 0x17f6, 0x0b7f: 0x092d, + 0x0b40: 0x4606, 0x0b41: 0x2aba, 0x0b42: 0x2ac4, 0x0b43: 0x2c28, 0x0b44: 0x2ace, 0x0b45: 0x2ad8, + 0x0b46: 0x2ae2, 0x0b47: 0x2d15, 0x0b48: 0x2c35, 0x0b49: 0x2861, 0x0b4a: 0x2def, 0x0b4b: 0x4520, + 0x0b4c: 0x2d25, 0x0b4d: 0x2c42, 0x0b4e: 0x4547, 0x0b4f: 0x2aec, 0x0b50: 0x2af6, 0x0b51: 0x2c4f, + 0x0b52: 0x2868, 0x0b53: 0x2c5c, 0x0b54: 0x2d35, 0x0b55: 0x286f, 0x0b56: 0x2e02, 0x0b57: 0x2b00, + 0x0b58: 0x1ba4, 0x0b59: 0x1bb8, 0x0b5a: 0x1bc7, 0x0b5b: 0x1bd6, 0x0b5c: 0x1be5, 0x0b5d: 0x1bf4, + 0x0b5e: 0x1c03, 0x0b5f: 0x1c12, 0x0b60: 0x1c21, 0x0b61: 0x1c30, 0x0b62: 0x22a5, 0x0b63: 0x22b7, + 0x0b64: 0x22c9, 0x0b65: 0x22d5, 0x0b66: 0x22e1, 0x0b67: 0x22ed, 0x0b68: 0x22f9, 0x0b69: 0x2305, + 0x0b6a: 0x2311, 0x0b6b: 0x231d, 0x0b6c: 0x2359, 0x0b6d: 0x2365, 0x0b6e: 0x2371, 0x0b6f: 0x237d, + 0x0b70: 0x2389, 0x0b71: 0x0765, 0x0b72: 0x02e0, 0x0b73: 0x0256, 0x0b74: 0x0735, 0x0b75: 0x0361, + 0x0b76: 0x0370, 0x0b77: 0x02e6, 0x0b78: 0x074d, 0x0b79: 0x0751, 0x0b7a: 0x0280, 0x0b7b: 0x287d, + 0x0b7c: 0x288b, 0x0b7d: 0x2876, 0x0b7e: 0x2884, 0x0b7f: 0x2c69, // Block 0x2e, offset 0xb80 - 0x0b80: 0x092f, 0x0b81: 0x155f, 0x0b82: 0x0931, 0x0b83: 0x1570, 0x0b84: 0x17f8, 0x0b85: 0x14d4, - 0x0b86: 0x0007, 0x0b87: 0x093d, 0x0b88: 0x0984, 0x0b89: 0x093f, 0x0b8a: 0x0941, 0x0b8b: 0x098c, - 0x0b8c: 0x094c, 0x0b8d: 0x0494, 0x0b8e: 0x097c, 0x0b8f: 0x0499, 0x0b90: 0x094e, 0x0b91: 0x04c5, - 0x0b92: 0x0950, 0x0b93: 0x14a0, 0x0b94: 0x001e, 0x0b95: 0x0960, 0x0b96: 0x17fa, 0x0b97: 0x049b, - 0x0b98: 0x02c8, 0x0b99: 0x0962, 0x0b9a: 0x0964, 0x0b9b: 0x096d, 0x0b9c: 0x04a6, 0x0b9d: 0x04c7, - 0x0b9e: 0x04a8, 0x0b9f: 0x09df, 0x0ba0: 0x0906, 0x0ba1: 0x090b, 0x0ba2: 0x14ad, 0x0ba3: 0x090d, - 0x0ba4: 0x090f, 0x0ba5: 0x14d9, 0x0ba6: 0x0914, 0x0ba7: 0x0916, 0x0ba8: 0x0918, 0x0ba9: 0x091a, - 0x0baa: 0x091c, 0x0bab: 0x091e, 0x0bac: 0x0920, 0x0bad: 0x0922, 0x0bae: 0x0924, 0x0baf: 0x0929, - 0x0bb0: 0x14c8, 0x0bb1: 0x092b, 0x0bb2: 0x17f6, 0x0bb3: 0x092d, 0x0bb4: 0x092f, 0x0bb5: 0x155f, - 0x0bb6: 0x0931, 0x0bb7: 0x1570, 0x0bb8: 0x17f8, 0x0bb9: 0x14d4, 0x0bba: 0x0007, 0x0bbb: 0x093d, - 0x0bbc: 0x0984, 0x0bbd: 0x093f, 0x0bbe: 0x0941, 0x0bbf: 0x098c, + 0x0b80: 0x0364, 0x0b81: 0x034c, 0x0b82: 0x07b1, 0x0b83: 0x0334, 0x0b84: 0x030d, 0x0b85: 0x0289, + 0x0b86: 0x0298, 0x0b87: 0x0268, 0x0b88: 0x0741, 0x0b89: 0x1c3f, 0x0b8a: 0x0367, 0x0b8b: 0x034f, + 0x0b8c: 0x07b5, 0x0b8d: 0x07c1, 0x0b8e: 0x0340, 0x0b8f: 0x0316, 0x0b90: 0x0277, 0x0b91: 0x076d, + 0x0b92: 0x0701, 0x0b93: 0x06ed, 0x0b94: 0x071d, 0x0b95: 0x07c5, 0x0b96: 0x0343, 0x0b97: 0x02e3, + 0x0b98: 0x0319, 0x0b99: 0x02f8, 0x0b9a: 0x035b, 0x0b9b: 0x07c9, 0x0b9c: 0x0346, 0x0b9d: 0x02da, + 0x0b9e: 0x031c, 0x0b9f: 0x078d, 0x0ba0: 0x0745, 0x0ba1: 0x032e, 0x0ba2: 0x0775, 0x0ba3: 0x0791, + 0x0ba4: 0x0749, 0x0ba5: 0x0331, 0x0ba6: 0x0779, 0x0ba7: 0x23fb, 0x0ba8: 0x240f, 0x0ba9: 0x02b0, + 0x0baa: 0x0771, 0x0bab: 0x0705, 0x0bac: 0x06f1, 0x0bad: 0x0799, 0x0bae: 0x2892, 0x0baf: 0x2929, + 0x0bb0: 0x0373, 0x0bb1: 0x035e, 0x0bb2: 0x07cd, 0x0bb3: 0x0349, 0x0bb4: 0x036a, 0x0bb5: 0x0352, + 0x0bb6: 0x07b9, 0x0bb7: 0x0337, 0x0bb8: 0x0310, 0x0bb9: 0x029b, 0x0bba: 0x036d, 0x0bbb: 0x0355, + 0x0bbc: 0x07bd, 0x0bbd: 0x033a, 0x0bbe: 0x0313, 0x0bbf: 0x029e, // Block 0x2f, offset 0xbc0 - 0x0bc0: 0x094c, 0x0bc1: 0x0494, 0x0bc2: 0x097c, 0x0bc3: 0x0499, 0x0bc4: 0x094e, 0x0bc5: 0x04c5, - 0x0bc6: 0x0950, 0x0bc7: 0x14a0, 0x0bc8: 0x001e, 0x0bc9: 0x0960, 0x0bca: 0x17fa, 0x0bcb: 0x049b, - 0x0bcc: 0x02c8, 0x0bcd: 0x0962, 0x0bce: 0x0964, 0x0bcf: 0x096d, 0x0bd0: 0x04a6, 0x0bd1: 0x04c7, - 0x0bd2: 0x04a8, 0x0bd3: 0x09df, 0x0bd4: 0x0906, 0x0bd5: 0x090b, 0x0bd6: 0x14ad, 0x0bd7: 0x090d, - 0x0bd8: 0x090f, 0x0bd9: 0x14d9, 0x0bda: 0x0914, 0x0bdb: 0x0916, 0x0bdc: 0x0918, 0x0bdd: 0x091a, - 0x0bde: 0x091c, 0x0bdf: 0x091e, 0x0be0: 0x0920, 0x0be1: 0x0922, 0x0be2: 0x0924, 0x0be3: 0x0929, - 0x0be4: 0x14c8, 0x0be5: 0x092b, 0x0be6: 0x17f6, 0x0be7: 0x092d, 0x0be8: 0x092f, 0x0be9: 0x155f, - 0x0bea: 0x0931, 0x0beb: 0x1570, 0x0bec: 0x17f8, 0x0bed: 0x14d4, 0x0bee: 0x0007, 0x0bef: 0x093d, - 0x0bf0: 0x0984, 0x0bf1: 0x093f, 0x0bf2: 0x0941, 0x0bf3: 0x098c, 0x0bf4: 0x094c, 0x0bf5: 0x0494, - 0x0bf6: 0x097c, 0x0bf7: 0x0499, 0x0bf8: 0x094e, 0x0bf9: 0x04c5, 0x0bfa: 0x0950, 0x0bfb: 0x14a0, - 0x0bfc: 0x001e, 0x0bfd: 0x0960, 0x0bfe: 0x17fa, 0x0bff: 0x049b, + 0x0bc0: 0x077d, 0x0bc1: 0x0709, 0x0bc2: 0x1c3a, 0x0bc3: 0x0259, 0x0bc4: 0x02d4, 0x0bc5: 0x02d7, + 0x0bc6: 0x2408, 0x0bc7: 0x06e5, 0x0bc8: 0x02dd, 0x0bc9: 0x026b, 0x0bca: 0x02fb, 0x0bcb: 0x026e, + 0x0bcc: 0x0304, 0x0bcd: 0x028c, 0x0bce: 0x028f, 0x0bcf: 0x031f, 0x0bd0: 0x0325, 0x0bd1: 0x0328, + 0x0bd2: 0x0781, 0x0bd3: 0x032b, 0x0bd4: 0x033d, 0x0bd5: 0x0789, 0x0bd6: 0x0795, 0x0bd7: 0x02aa, + 0x0bd8: 0x1c44, 0x0bd9: 0x070d, 0x0bda: 0x02ad, 0x0bdb: 0x0376, 0x0bdc: 0x02bf, 0x0bdd: 0x02ce, + 0x0bde: 0x23f5, 0x0bdf: 0x23ef, 0x0be0: 0x1bae, 0x0be1: 0x1bbd, 0x0be2: 0x1bcc, 0x0be3: 0x1bdb, + 0x0be4: 0x1bea, 0x0be5: 0x1bf9, 0x0be6: 0x1c08, 0x0be7: 0x1c17, 0x0be8: 0x1c26, 0x0be9: 0x2299, + 0x0bea: 0x22ab, 0x0beb: 0x22bd, 0x0bec: 0x22cf, 0x0bed: 0x22db, 0x0bee: 0x22e7, 0x0bef: 0x22f3, + 0x0bf0: 0x22ff, 0x0bf1: 0x230b, 0x0bf2: 0x2317, 0x0bf3: 0x2353, 0x0bf4: 0x235f, 0x0bf5: 0x236b, + 0x0bf6: 0x2377, 0x0bf7: 0x2383, 0x0bf8: 0x238f, 0x0bf9: 0x2395, 0x0bfa: 0x239b, 0x0bfb: 0x23a1, + 0x0bfc: 0x23a7, 0x0bfd: 0x23b9, 0x0bfe: 0x23bf, 0x0bff: 0x0761, // Block 0x30, offset 0xc00 - 0x0c00: 0x02c8, 0x0c01: 0x0962, 0x0c02: 0x0964, 0x0c03: 0x096d, 0x0c04: 0x04a6, 0x0c05: 0x04c7, - 0x0c06: 0x04a8, 0x0c07: 0x09df, 0x0c08: 0x0906, 0x0c09: 0x090b, 0x0c0a: 0x14ad, 0x0c0b: 0x090d, - 0x0c0c: 0x090f, 0x0c0d: 0x14d9, 0x0c0e: 0x0914, 0x0c0f: 0x0916, 0x0c10: 0x0918, 0x0c11: 0x091a, - 0x0c12: 0x091c, 0x0c13: 0x091e, 0x0c14: 0x0920, 0x0c15: 0x0922, 0x0c16: 0x0924, 0x0c17: 0x0929, - 0x0c18: 0x14c8, 0x0c19: 0x092b, 0x0c1a: 0x17f6, 0x0c1b: 0x092d, 0x0c1c: 0x092f, 0x0c1d: 0x155f, - 0x0c1e: 0x0931, 0x0c1f: 0x1570, 0x0c20: 0x17f8, 0x0c21: 0x14d4, 0x0c22: 0x0007, 0x0c23: 0x093d, - 0x0c24: 0x0984, 0x0c25: 0x093f, 0x0c26: 0x0941, 0x0c27: 0x098c, 0x0c28: 0x094c, 0x0c29: 0x0494, - 0x0c2a: 0x097c, 0x0c2b: 0x0499, 0x0c2c: 0x094e, 0x0c2d: 0x04c5, 0x0c2e: 0x0950, 0x0c2f: 0x14a0, - 0x0c30: 0x001e, 0x0c31: 0x0960, 0x0c32: 0x17fa, 0x0c33: 0x049b, 0x0c34: 0x02c8, 0x0c35: 0x0962, - 0x0c36: 0x0964, 0x0c37: 0x096d, 0x0c38: 0x04a6, 0x0c39: 0x04c7, 0x0c3a: 0x04a8, 0x0c3b: 0x09df, - 0x0c3c: 0x0906, 0x0c3d: 0x090b, 0x0c3e: 0x14ad, 0x0c3f: 0x090d, + 0x0c00: 0x18b5, 0x0c01: 0x1239, 0x0c02: 0x1911, 0x0c03: 0x18dd, 0x0c04: 0x1395, 0x0c05: 0x0c29, + 0x0c06: 0x0e1d, 0x0c07: 0x1b5d, 0x0c08: 0x1b5d, 0x0c09: 0x0f49, 0x0c0a: 0x1995, 0x0c0b: 0x0e81, + 0x0c0c: 0x0f45, 0x0c0d: 0x112d, 0x0c0e: 0x150d, 0x0c0f: 0x169d, 0x0c10: 0x17d5, 0x0c11: 0x1811, + 0x0c12: 0x1845, 0x0c13: 0x1959, 0x0c14: 0x12b1, 0x0c15: 0x133d, 0x0c16: 0x13e9, 0x0c17: 0x1481, + 0x0c18: 0x179d, 0x0c19: 0x197d, 0x0c1a: 0x1aa5, 0x0c1b: 0x0c4d, 0x0c1c: 0x0df1, 0x0c1d: 0x12c5, + 0x0c1e: 0x140d, 0x0c1f: 0x17d1, 0x0c20: 0x1af5, 0x0c21: 0x0ff1, 0x0c22: 0x13b5, 0x0c23: 0x17c1, + 0x0c24: 0x1855, 0x0c25: 0x1161, 0x0c26: 0x16f9, 0x0c27: 0x181d, 0x0c28: 0x105d, 0x0c29: 0x124d, + 0x0c2a: 0x1355, 0x0c2b: 0x1459, 0x0c2c: 0x1965, 0x0c2d: 0x0c8d, 0x0c2e: 0x0d25, 0x0c2f: 0x0d91, + 0x0c30: 0x11c9, 0x0c31: 0x12bd, 0x0c32: 0x1409, 0x0c33: 0x152d, 0x0c34: 0x16b5, 0x0c35: 0x17c9, + 0x0c36: 0x17e1, 0x0c37: 0x1905, 0x0c38: 0x1a21, 0x0c39: 0x1ad5, 0x0c3a: 0x1af1, 0x0c3b: 0x1569, + 0x0c3c: 0x15a9, 0x0c3d: 0x1661, 0x0c3e: 0x1781, 0x0c3f: 0x19b1, // Block 0x31, offset 0xc40 - 0x0c40: 0x090f, 0x0c41: 0x14d9, 0x0c42: 0x0914, 0x0c43: 0x0916, 0x0c44: 0x0918, 0x0c45: 0x091a, - 0x0c46: 0x091c, 0x0c47: 0x091e, 0x0c48: 0x0920, 0x0c49: 0x0922, 0x0c4a: 0x0924, 0x0c4b: 0x0929, - 0x0c4c: 0x14c8, 0x0c4d: 0x092b, 0x0c4e: 0x17f6, 0x0c4f: 0x092d, 0x0c50: 0x092f, 0x0c51: 0x155f, - 0x0c52: 0x0931, 0x0c53: 0x1570, 0x0c54: 0x17f8, 0x0c55: 0x14d4, 0x0c56: 0x0007, 0x0c57: 0x093d, - 0x0c58: 0x0984, 0x0c59: 0x093f, 0x0c5a: 0x0941, 0x0c5b: 0x098c, 0x0c5c: 0x094c, 0x0c5d: 0x0494, - 0x0c5e: 0x097c, 0x0c5f: 0x0499, 0x0c60: 0x094e, 0x0c61: 0x04c5, 0x0c62: 0x0950, 0x0c63: 0x14a0, - 0x0c64: 0x001e, 0x0c65: 0x0960, 0x0c66: 0x17fa, 0x0c67: 0x049b, 0x0c68: 0x02c8, 0x0c69: 0x0962, - 0x0c6a: 0x0964, 0x0c6b: 0x096d, 0x0c6c: 0x04a6, 0x0c6d: 0x04c7, 0x0c6e: 0x04a8, 0x0c6f: 0x09df, - 0x0c70: 0x0906, 0x0c71: 0x090b, 0x0c72: 0x14ad, 0x0c73: 0x090d, 0x0c74: 0x090f, 0x0c75: 0x14d9, - 0x0c76: 0x0914, 0x0c77: 0x0916, 0x0c78: 0x0918, 0x0c79: 0x091a, 0x0c7a: 0x091c, 0x0c7b: 0x091e, - 0x0c7c: 0x0920, 0x0c7d: 0x0922, 0x0c7e: 0x0924, 0x0c7f: 0x0929, + 0x0c40: 0x1afd, 0x0c41: 0x1889, 0x0c42: 0x0f05, 0x0c43: 0x1079, 0x0c44: 0x1619, 0x0c45: 0x16d9, + 0x0c46: 0x143d, 0x0c47: 0x1571, 0x0c48: 0x18d5, 0x0c49: 0x1a19, 0x0c4a: 0x0f01, 0x0c4b: 0x0fcd, + 0x0c4c: 0x12b5, 0x0c4d: 0x1369, 0x0c4e: 0x139d, 0x0c4f: 0x1651, 0x0c50: 0x1679, 0x0c51: 0x19dd, + 0x0c52: 0x0d8d, 0x0c53: 0x16e5, 0x0c54: 0x0d31, 0x0c55: 0x0d2d, 0x0c56: 0x15d5, 0x0c57: 0x1665, + 0x0c58: 0x1799, 0x0c59: 0x19e5, 0x0c5a: 0x18a5, 0x0c5b: 0x1165, 0x0c5c: 0x12b1, 0x0c5d: 0x1895, + 0x0c5e: 0x0c35, 0x0c5f: 0x0fa1, 0x0c60: 0x10d1, 0x0c61: 0x146d, 0x0c62: 0x14ed, 0x0c63: 0x0db1, + 0x0c64: 0x1579, 0x0c65: 0x0c9d, 0x0c66: 0x10b5, 0x0c67: 0x0c15, 0x0c68: 0x1329, 0x0c69: 0x11e1, + 0x0c6a: 0x164d, 0x0c6b: 0x0e05, 0x0c6c: 0x0ef1, 0x0c6d: 0x1539, 0x0c6e: 0x17a1, 0x0c6f: 0x1879, + 0x0c70: 0x12f5, 0x0c71: 0x1935, 0x0c72: 0x1321, 0x0c73: 0x1175, 0x0c74: 0x1759, 0x0c75: 0x1195, + 0x0c76: 0x14e9, 0x0c77: 0x0c69, 0x0c78: 0x0ce5, 0x0c79: 0x0d29, 0x0c7a: 0x1291, 0x0c7b: 0x1639, + 0x0c7c: 0x1731, 0x0c7d: 0x1885, 0x0c7e: 0x1991, 0x0c7f: 0x0d99, // Block 0x32, offset 0xc80 - 0x0c80: 0x14c8, 0x0c81: 0x092b, 0x0c82: 0x17f6, 0x0c83: 0x092d, 0x0c84: 0x092f, 0x0c85: 0x155f, - 0x0c86: 0x0931, 0x0c87: 0x1570, 0x0c88: 0x17f8, 0x0c89: 0x14d4, 0x0c8a: 0x0007, 0x0c8b: 0x093d, - 0x0c8c: 0x0984, 0x0c8d: 0x093f, 0x0c8e: 0x0941, 0x0c8f: 0x098c, 0x0c90: 0x094c, 0x0c91: 0x0494, - 0x0c92: 0x097c, 0x0c93: 0x0499, 0x0c94: 0x094e, 0x0c95: 0x04c5, 0x0c96: 0x0950, 0x0c97: 0x14a0, - 0x0c98: 0x001e, 0x0c99: 0x0960, 0x0c9a: 0x17fa, 0x0c9b: 0x049b, 0x0c9c: 0x02c8, 0x0c9d: 0x0962, - 0x0c9e: 0x0964, 0x0c9f: 0x096d, 0x0ca0: 0x04a6, 0x0ca1: 0x04c7, 0x0ca2: 0x04a8, 0x0ca3: 0x09df, - 0x0ca4: 0x3b27, 0x0ca5: 0x3b2a, 0x0ca8: 0x3b2d, 0x0ca9: 0x3b30, - 0x0caa: 0x14eb, 0x0cab: 0x3b33, 0x0cac: 0x3b36, 0x0cad: 0x3b39, 0x0cae: 0x3b3c, 0x0caf: 0x057b, - 0x0cb0: 0x3b3f, 0x0cb1: 0x3b42, 0x0cb2: 0x3b45, 0x0cb3: 0x3b48, 0x0cb4: 0x3b4b, 0x0cb5: 0x3b4e, - 0x0cb6: 0x3b51, 0x0cb7: 0x14ee, 0x0cb8: 0x3b54, 0x0cb9: 0x057b, 0x0cba: 0x0581, 0x0cbb: 0x3b57, - 0x0cbc: 0x055f, 0x0cbd: 0x3b5a, 0x0cbe: 0x3b5d, 0x0cbf: 0x3b60, + 0x0c80: 0x0e4d, 0x0c81: 0x0f55, 0x0c82: 0x106d, 0x0c83: 0x11fd, 0x0c84: 0x13b9, 0x0c85: 0x157d, + 0x0c86: 0x19cd, 0x0c87: 0x1aad, 0x0c88: 0x1b01, 0x0c89: 0x1b19, 0x0c8a: 0x0d75, 0x0c8b: 0x1231, + 0x0c8c: 0x12e1, 0x0c8d: 0x1929, 0x0c8e: 0x1039, 0x0c8f: 0x1115, 0x0c90: 0x1131, 0x0c91: 0x11c1, + 0x0c92: 0x13a9, 0x0c93: 0x13f5, 0x0c94: 0x14a5, 0x0c95: 0x15c9, 0x0c96: 0x166d, 0x0c97: 0x16d1, + 0x0c98: 0x1919, 0x0c99: 0x17a9, 0x0c9a: 0x1941, 0x0c9b: 0x19b5, 0x0c9c: 0x0d4d, 0x0c9d: 0x0d79, + 0x0c9e: 0x0e61, 0x0c9f: 0x13e5, 0x0ca0: 0x1831, 0x0ca1: 0x1879, 0x0ca2: 0x1059, 0x0ca3: 0x10c9, + 0x0ca4: 0x118d, 0x0ca5: 0x12ed, 0x0ca6: 0x1615, 0x0ca7: 0x1461, 0x0ca8: 0x0c79, 0x0ca9: 0x0ebd, + 0x0caa: 0x0fa1, 0x0cab: 0x1005, 0x0cac: 0x10d5, 0x0cad: 0x147d, 0x0cae: 0x1499, 0x0caf: 0x16a9, + 0x0cb0: 0x16c9, 0x0cb1: 0x1999, 0x0cb2: 0x1a15, 0x0cb3: 0x1a25, 0x0cb4: 0x1a61, 0x0cb5: 0x0c91, + 0x0cb6: 0x15bd, 0x0cb7: 0x1985, 0x0cb8: 0x19fd, 0x0cb9: 0x10ed, 0x0cba: 0x0c55, 0x0cbb: 0x0cb5, + 0x0cbc: 0x0fa5, 0x0cbd: 0x0fc5, 0x0cbe: 0x11ed, 0x0cbf: 0x12b1, // Block 0x33, offset 0xcc0 - 0x0cc0: 0x14d6, 0x0cc1: 0x3b63, 0x0cc2: 0x3b67, 0x0cc3: 0x0559, 0x0cc4: 0x0973, 0x0cc5: 0x0976, - 0x0cc6: 0x057e, 0x0cc7: 0x3b6a, 0x0cc8: 0x3b6d, 0x0cc9: 0x055c, 0x0cca: 0x12fd, 0x0ccb: 0x0572, - 0x0ccc: 0x3b70, 0x0ccd: 0x0015, 0x0cce: 0x3b73, 0x0ccf: 0x3b76, 0x0cd0: 0x3b79, 0x0cd1: 0x056f, - 0x0cd2: 0x0575, 0x0cd3: 0x0578, 0x0cd4: 0x3b7c, 0x0cd5: 0x3b7f, 0x0cd6: 0x3b82, 0x0cd7: 0x056c, - 0x0cd8: 0x0979, 0x0cd9: 0x3b85, 0x0cda: 0x3b88, 0x0cdb: 0x3b8b, 0x0cdc: 0x057e, 0x0cdd: 0x055c, - 0x0cde: 0x0572, 0x0cdf: 0x056c, 0x0ce0: 0x0575, 0x0ce1: 0x056f, 0x0ce2: 0x3b2d, 0x0ce3: 0x3b30, - 0x0ce4: 0x14eb, 0x0ce5: 0x3b33, 0x0ce6: 0x3b36, 0x0ce7: 0x3b39, 0x0ce8: 0x3b3c, 0x0ce9: 0x057b, - 0x0cea: 0x3b3f, 0x0ceb: 0x3b42, 0x0cec: 0x3b45, 0x0ced: 0x3b48, 0x0cee: 0x3b4b, 0x0cef: 0x3b4e, - 0x0cf0: 0x3b51, 0x0cf1: 0x14ee, 0x0cf2: 0x3b54, 0x0cf3: 0x057b, 0x0cf4: 0x0581, 0x0cf5: 0x3b57, - 0x0cf6: 0x055f, 0x0cf7: 0x3b5a, 0x0cf8: 0x3b5d, 0x0cf9: 0x3b60, 0x0cfa: 0x14d6, 0x0cfb: 0x3b63, - 0x0cfc: 0x3b67, 0x0cfd: 0x0559, 0x0cfe: 0x0973, 0x0cff: 0x0976, + 0x0cc0: 0x1401, 0x0cc1: 0x1509, 0x0cc2: 0x17b5, 0x0cc3: 0x1955, 0x0cc4: 0x1b55, 0x0cc5: 0x1221, + 0x0cc6: 0x19d9, 0x0cc7: 0x0d71, 0x0cc8: 0x126d, 0x0cc9: 0x1279, 0x0cca: 0x134d, 0x0ccb: 0x1385, + 0x0ccc: 0x1489, 0x0ccd: 0x14e5, 0x0cce: 0x1565, 0x0ccf: 0x1649, 0x0cd0: 0x1a6d, 0x0cd1: 0x0ced, + 0x0cd2: 0x1141, 0x0cd3: 0x19e9, 0x0cd4: 0x0ca5, 0x0cd5: 0x0fe9, 0x0cd6: 0x136d, 0x0cd7: 0x191d, + 0x0cd8: 0x10a5, 0x0cd9: 0x10f5, 0x0cda: 0x1281, 0x0cdb: 0x146d, 0x0cdc: 0x19f1, 0x0cdd: 0x0d55, + 0x0cde: 0x0e3d, 0x0cdf: 0x0fd5, 0x0ce0: 0x1211, 0x0ce1: 0x125d, 0x0ce2: 0x129d, 0x0ce3: 0x1331, + 0x0ce4: 0x1485, 0x0ce5: 0x14f9, 0x0ce6: 0x1695, 0x0ce7: 0x1835, 0x0ce8: 0x1841, 0x0ce9: 0x198d, + 0x0cea: 0x1a09, 0x0ceb: 0x0dc1, 0x0cec: 0x1389, 0x0ced: 0x0e41, 0x0cee: 0x1405, 0x0cef: 0x14a9, + 0x0cf0: 0x17c5, 0x0cf1: 0x19f5, 0x0cf2: 0x1add, 0x0cf3: 0x1b05, 0x0cf4: 0x1275, 0x0cf5: 0x1365, + 0x0cf6: 0x1701, 0x0cf7: 0x15f5, 0x0cf8: 0x1601, 0x0cf9: 0x1625, 0x0cfa: 0x1455, 0x0cfb: 0x13dd, + 0x0cfc: 0x18a1, 0x0cfd: 0x0c71, 0x0cfe: 0x1769, 0x0cff: 0x0d59, // Block 0x34, offset 0xd00 - 0x0d00: 0x057e, 0x0d01: 0x3b6a, 0x0d02: 0x3b6d, 0x0d03: 0x055c, 0x0d04: 0x12fd, 0x0d05: 0x0572, - 0x0d06: 0x3b70, 0x0d07: 0x0015, 0x0d08: 0x3b73, 0x0d09: 0x3b76, 0x0d0a: 0x3b79, 0x0d0b: 0x056f, - 0x0d0c: 0x0575, 0x0d0d: 0x0578, 0x0d0e: 0x3b7c, 0x0d0f: 0x3b7f, 0x0d10: 0x3b82, 0x0d11: 0x056c, - 0x0d12: 0x0979, 0x0d13: 0x3b85, 0x0d14: 0x3b88, 0x0d15: 0x3b8b, 0x0d16: 0x057e, 0x0d17: 0x055c, - 0x0d18: 0x0572, 0x0d19: 0x056c, 0x0d1a: 0x0575, 0x0d1b: 0x056f, 0x0d1c: 0x3b2d, 0x0d1d: 0x3b30, - 0x0d1e: 0x14eb, 0x0d1f: 0x3b33, 0x0d20: 0x3b36, 0x0d21: 0x3b39, 0x0d22: 0x3b3c, 0x0d23: 0x057b, - 0x0d24: 0x3b3f, 0x0d25: 0x3b42, 0x0d26: 0x3b45, 0x0d27: 0x3b48, 0x0d28: 0x3b4b, 0x0d29: 0x3b4e, - 0x0d2a: 0x3b51, 0x0d2b: 0x14ee, 0x0d2c: 0x3b54, 0x0d2d: 0x057b, 0x0d2e: 0x0581, 0x0d2f: 0x3b57, - 0x0d30: 0x055f, 0x0d31: 0x3b5a, 0x0d32: 0x3b5d, 0x0d33: 0x3b60, 0x0d34: 0x14d6, 0x0d35: 0x3b63, - 0x0d36: 0x3b67, 0x0d37: 0x0559, 0x0d38: 0x0973, 0x0d39: 0x0976, 0x0d3a: 0x057e, 0x0d3b: 0x3b6a, - 0x0d3c: 0x3b6d, 0x0d3d: 0x055c, 0x0d3e: 0x12fd, 0x0d3f: 0x0572, + 0x0d00: 0x0d49, 0x0d01: 0x1049, 0x0d02: 0x1169, 0x0d03: 0x1631, 0x0d04: 0x0f91, 0x0d05: 0x1341, + 0x0d06: 0x122d, 0x0d07: 0x1925, 0x0d08: 0x1825, 0x0d09: 0x19e1, 0x0d0a: 0x1861, 0x0d0b: 0x1065, + 0x0d0c: 0x0cc5, 0x0d0d: 0x0e99, 0x0d10: 0x0eed, + 0x0d12: 0x121d, 0x0d15: 0x0d35, 0x0d16: 0x145d, 0x0d17: 0x1521, + 0x0d18: 0x1585, 0x0d19: 0x15a1, 0x0d1a: 0x15a5, 0x0d1b: 0x15b9, 0x0d1c: 0x1a2d, 0x0d1d: 0x1629, + 0x0d1e: 0x16ad, 0x0d20: 0x17cd, 0x0d22: 0x1891, + 0x0d25: 0x1945, 0x0d26: 0x196d, + 0x0d2a: 0x1a81, 0x0d2b: 0x1a85, 0x0d2c: 0x1a89, 0x0d2d: 0x1aed, + 0x0d30: 0x0c95, 0x0d31: 0x0cb9, 0x0d32: 0x0ccd, 0x0d33: 0x0d89, 0x0d34: 0x0d95, 0x0d35: 0x0dd5, + 0x0d36: 0x0e89, 0x0d37: 0x0ea5, 0x0d38: 0x0ead, 0x0d39: 0x0ee9, 0x0d3a: 0x0ef5, 0x0d3b: 0x0fd1, + 0x0d3c: 0x0fd9, 0x0d3d: 0x10e1, 0x0d3e: 0x1109, 0x0d3f: 0x1111, // Block 0x35, offset 0xd40 - 0x0d40: 0x3b70, 0x0d41: 0x0015, 0x0d42: 0x3b73, 0x0d43: 0x3b76, 0x0d44: 0x3b79, 0x0d45: 0x056f, - 0x0d46: 0x0575, 0x0d47: 0x0578, 0x0d48: 0x3b7c, 0x0d49: 0x3b7f, 0x0d4a: 0x3b82, 0x0d4b: 0x056c, - 0x0d4c: 0x0979, 0x0d4d: 0x3b85, 0x0d4e: 0x3b88, 0x0d4f: 0x3b8b, 0x0d50: 0x057e, 0x0d51: 0x055c, - 0x0d52: 0x0572, 0x0d53: 0x056c, 0x0d54: 0x0575, 0x0d55: 0x056f, 0x0d56: 0x3b2d, 0x0d57: 0x3b30, - 0x0d58: 0x14eb, 0x0d59: 0x3b33, 0x0d5a: 0x3b36, 0x0d5b: 0x3b39, 0x0d5c: 0x3b3c, 0x0d5d: 0x057b, - 0x0d5e: 0x3b3f, 0x0d5f: 0x3b42, 0x0d60: 0x3b45, 0x0d61: 0x3b48, 0x0d62: 0x3b4b, 0x0d63: 0x3b4e, - 0x0d64: 0x3b51, 0x0d65: 0x14ee, 0x0d66: 0x3b54, 0x0d67: 0x057b, 0x0d68: 0x0581, 0x0d69: 0x3b57, - 0x0d6a: 0x055f, 0x0d6b: 0x3b5a, 0x0d6c: 0x3b5d, 0x0d6d: 0x3b60, 0x0d6e: 0x14d6, 0x0d6f: 0x3b63, - 0x0d70: 0x3b67, 0x0d71: 0x0559, 0x0d72: 0x0973, 0x0d73: 0x0976, 0x0d74: 0x057e, 0x0d75: 0x3b6a, - 0x0d76: 0x3b6d, 0x0d77: 0x055c, 0x0d78: 0x12fd, 0x0d79: 0x0572, 0x0d7a: 0x3b70, 0x0d7b: 0x0015, - 0x0d7c: 0x3b73, 0x0d7d: 0x3b76, 0x0d7e: 0x3b79, 0x0d7f: 0x056f, + 0x0d40: 0x1129, 0x0d41: 0x11d5, 0x0d42: 0x1205, 0x0d43: 0x1225, 0x0d44: 0x1295, 0x0d45: 0x1359, + 0x0d46: 0x1375, 0x0d47: 0x13a5, 0x0d48: 0x13f9, 0x0d49: 0x1419, 0x0d4a: 0x148d, 0x0d4b: 0x156d, + 0x0d4c: 0x1589, 0x0d4d: 0x1591, 0x0d4e: 0x158d, 0x0d4f: 0x1595, 0x0d50: 0x1599, 0x0d51: 0x159d, + 0x0d52: 0x15b1, 0x0d53: 0x15b5, 0x0d54: 0x15d9, 0x0d55: 0x15ed, 0x0d56: 0x1609, 0x0d57: 0x166d, + 0x0d58: 0x1675, 0x0d59: 0x167d, 0x0d5a: 0x1691, 0x0d5b: 0x16b9, 0x0d5c: 0x1709, 0x0d5d: 0x173d, + 0x0d5e: 0x173d, 0x0d5f: 0x17a5, 0x0d60: 0x184d, 0x0d61: 0x1865, 0x0d62: 0x1899, 0x0d63: 0x189d, + 0x0d64: 0x18e1, 0x0d65: 0x18e5, 0x0d66: 0x193d, 0x0d67: 0x1945, 0x0d68: 0x1a0d, 0x0d69: 0x1a51, + 0x0d6a: 0x1a69, 0x0d6b: 0x10d9, 0x0d6c: 0x2018, 0x0d6d: 0x1721, + 0x0d70: 0x0c1d, 0x0d71: 0x0d21, 0x0d72: 0x0ce1, 0x0d73: 0x0c89, 0x0d74: 0x0cc9, 0x0d75: 0x0cf5, + 0x0d76: 0x0d85, 0x0d77: 0x0da1, 0x0d78: 0x0e89, 0x0d79: 0x0e75, 0x0d7a: 0x0e85, 0x0d7b: 0x0ea1, + 0x0d7c: 0x0eed, 0x0d7d: 0x0efd, 0x0d7e: 0x0f41, 0x0d7f: 0x0f4d, // Block 0x36, offset 0xd80 - 0x0d80: 0x0575, 0x0d81: 0x0578, 0x0d82: 0x3b7c, 0x0d83: 0x3b7f, 0x0d84: 0x3b82, 0x0d85: 0x056c, - 0x0d86: 0x0979, 0x0d87: 0x3b85, 0x0d88: 0x3b88, 0x0d89: 0x3b8b, 0x0d8a: 0x057e, 0x0d8b: 0x055c, - 0x0d8c: 0x0572, 0x0d8d: 0x056c, 0x0d8e: 0x0575, 0x0d8f: 0x056f, 0x0d90: 0x3b2d, 0x0d91: 0x3b30, - 0x0d92: 0x14eb, 0x0d93: 0x3b33, 0x0d94: 0x3b36, 0x0d95: 0x3b39, 0x0d96: 0x3b3c, 0x0d97: 0x057b, - 0x0d98: 0x3b3f, 0x0d99: 0x3b42, 0x0d9a: 0x3b45, 0x0d9b: 0x3b48, 0x0d9c: 0x3b4b, 0x0d9d: 0x3b4e, - 0x0d9e: 0x3b51, 0x0d9f: 0x14ee, 0x0da0: 0x3b54, 0x0da1: 0x057b, 0x0da2: 0x0581, 0x0da3: 0x3b57, - 0x0da4: 0x055f, 0x0da5: 0x3b5a, 0x0da6: 0x3b5d, 0x0da7: 0x3b60, 0x0da8: 0x14d6, 0x0da9: 0x3b63, - 0x0daa: 0x3b67, 0x0dab: 0x0559, 0x0dac: 0x0973, 0x0dad: 0x0976, 0x0dae: 0x057e, 0x0daf: 0x3b6a, - 0x0db0: 0x3b6d, 0x0db1: 0x055c, 0x0db2: 0x12fd, 0x0db3: 0x0572, 0x0db4: 0x3b70, 0x0db5: 0x0015, - 0x0db6: 0x3b73, 0x0db7: 0x3b76, 0x0db8: 0x3b79, 0x0db9: 0x056f, 0x0dba: 0x0575, 0x0dbb: 0x0578, - 0x0dbc: 0x3b7c, 0x0dbd: 0x3b7f, 0x0dbe: 0x3b82, 0x0dbf: 0x056c, + 0x0d80: 0x0f69, 0x0d81: 0x0f79, 0x0d82: 0x1061, 0x0d83: 0x1069, 0x0d84: 0x1099, 0x0d85: 0x10b9, + 0x0d86: 0x10e9, 0x0d87: 0x1101, 0x0d88: 0x10f1, 0x0d89: 0x1111, 0x0d8a: 0x1105, 0x0d8b: 0x1129, + 0x0d8c: 0x1145, 0x0d8d: 0x119d, 0x0d8e: 0x11a9, 0x0d8f: 0x11b1, 0x0d90: 0x11d9, 0x0d91: 0x121d, + 0x0d92: 0x124d, 0x0d93: 0x1251, 0x0d94: 0x1265, 0x0d95: 0x12e5, 0x0d96: 0x12f5, 0x0d97: 0x134d, + 0x0d98: 0x1399, 0x0d99: 0x1391, 0x0d9a: 0x13a5, 0x0d9b: 0x13c1, 0x0d9c: 0x13f9, 0x0d9d: 0x1551, + 0x0d9e: 0x141d, 0x0d9f: 0x1451, 0x0da0: 0x145d, 0x0da1: 0x149d, 0x0da2: 0x14b9, 0x0da3: 0x14dd, + 0x0da4: 0x1501, 0x0da5: 0x1505, 0x0da6: 0x1521, 0x0da7: 0x1525, 0x0da8: 0x1535, 0x0da9: 0x1549, + 0x0daa: 0x1545, 0x0dab: 0x1575, 0x0dac: 0x15f1, 0x0dad: 0x1609, 0x0dae: 0x1621, 0x0daf: 0x1659, + 0x0db0: 0x166d, 0x0db1: 0x1689, 0x0db2: 0x16b9, 0x0db3: 0x176d, 0x0db4: 0x1795, 0x0db5: 0x1809, + 0x0db6: 0x1851, 0x0db7: 0x185d, 0x0db8: 0x1865, 0x0db9: 0x187d, 0x0dba: 0x1891, 0x0dbb: 0x1881, + 0x0dbc: 0x1899, 0x0dbd: 0x1895, 0x0dbe: 0x188d, 0x0dbf: 0x189d, // Block 0x37, offset 0xdc0 - 0x0dc0: 0x0979, 0x0dc1: 0x3b85, 0x0dc2: 0x3b88, 0x0dc3: 0x3b8b, 0x0dc4: 0x057e, 0x0dc5: 0x055c, - 0x0dc6: 0x0572, 0x0dc7: 0x056c, 0x0dc8: 0x0575, 0x0dc9: 0x056f, 0x0dca: 0x3b8f, 0x0dcb: 0x3b92, - 0x0dce: 0x1486, 0x0dcf: 0x001c, 0x0dd0: 0x000d, 0x0dd1: 0x000f, - 0x0dd2: 0x1488, 0x0dd3: 0x148a, 0x0dd4: 0x148c, 0x0dd5: 0x148e, 0x0dd6: 0x1490, 0x0dd7: 0x1492, - 0x0dd8: 0x1486, 0x0dd9: 0x001c, 0x0dda: 0x000d, 0x0ddb: 0x000f, 0x0ddc: 0x1488, 0x0ddd: 0x148a, - 0x0dde: 0x148c, 0x0ddf: 0x148e, 0x0de0: 0x1490, 0x0de1: 0x1492, 0x0de2: 0x1486, 0x0de3: 0x001c, - 0x0de4: 0x000d, 0x0de5: 0x000f, 0x0de6: 0x1488, 0x0de7: 0x148a, 0x0de8: 0x148c, 0x0de9: 0x148e, - 0x0dea: 0x1490, 0x0deb: 0x1492, 0x0dec: 0x1486, 0x0ded: 0x001c, 0x0dee: 0x000d, 0x0def: 0x000f, - 0x0df0: 0x1488, 0x0df1: 0x148a, 0x0df2: 0x148c, 0x0df3: 0x148e, 0x0df4: 0x1490, 0x0df5: 0x1492, - 0x0df6: 0x1486, 0x0df7: 0x001c, 0x0df8: 0x000d, 0x0df9: 0x000f, 0x0dfa: 0x1488, 0x0dfb: 0x148a, - 0x0dfc: 0x148c, 0x0dfd: 0x148e, 0x0dfe: 0x1490, 0x0dff: 0x1492, + 0x0dc0: 0x18a9, 0x0dc1: 0x18e5, 0x0dc2: 0x1921, 0x0dc3: 0x1951, 0x0dc4: 0x1981, 0x0dc5: 0x19a1, + 0x0dc6: 0x19ed, 0x0dc7: 0x1a0d, 0x0dc8: 0x1a2d, 0x0dc9: 0x1a41, 0x0dca: 0x1a51, 0x0dcb: 0x1a5d, + 0x0dcc: 0x1a69, 0x0dcd: 0x1abd, 0x0dce: 0x1b5d, 0x0dcf: 0x1faf, 0x0dd0: 0x1faa, 0x0dd1: 0x1fdc, + 0x0dd2: 0x0b45, 0x0dd3: 0x0b6d, 0x0dd4: 0x0b71, 0x0dd5: 0x205e, 0x0dd6: 0x208b, 0x0dd7: 0x2103, + 0x0dd8: 0x1b49, 0x0dd9: 0x1b59, // Block 0x38, offset 0xe00 - 0x0e00: 0x3b95, 0x0e01: 0x3b98, 0x0e02: 0x3b9b, 0x0e03: 0x3b9e, 0x0e04: 0x3ba1, 0x0e05: 0x3ba4, - 0x0e06: 0x3ba7, 0x0e07: 0x3baa, 0x0e08: 0x3bad, 0x0e09: 0x3bb0, 0x0e0a: 0x3bb3, - 0x0e10: 0x3bb6, 0x0e11: 0x3bba, - 0x0e12: 0x3bbe, 0x0e13: 0x3bc2, 0x0e14: 0x3bc6, 0x0e15: 0x3bca, 0x0e16: 0x3bce, 0x0e17: 0x3bd2, - 0x0e18: 0x3bd6, 0x0e19: 0x3bda, 0x0e1a: 0x3bde, 0x0e1b: 0x3be2, 0x0e1c: 0x3be6, 0x0e1d: 0x3bea, - 0x0e1e: 0x3bee, 0x0e1f: 0x3bf2, 0x0e20: 0x3bf6, 0x0e21: 0x3bfa, 0x0e22: 0x3bfe, 0x0e23: 0x3c02, - 0x0e24: 0x3c06, 0x0e25: 0x3c0a, 0x0e26: 0x3c0e, 0x0e27: 0x3c12, 0x0e28: 0x3c16, 0x0e29: 0x3c1a, - 0x0e2a: 0x3c1e, 0x0e2b: 0x14ad, 0x0e2c: 0x092b, 0x0e2d: 0x3c26, 0x0e2e: 0x3c29, - 0x0e30: 0x0906, 0x0e31: 0x090b, 0x0e32: 0x14ad, 0x0e33: 0x090d, 0x0e34: 0x090f, 0x0e35: 0x14d9, - 0x0e36: 0x0914, 0x0e37: 0x0916, 0x0e38: 0x0918, 0x0e39: 0x091a, 0x0e3a: 0x091c, 0x0e3b: 0x091e, - 0x0e3c: 0x0920, 0x0e3d: 0x0922, 0x0e3e: 0x0924, 0x0e3f: 0x0929, + 0x0e00: 0x02ef, 0x0e01: 0x02f2, 0x0e02: 0x02f5, 0x0e03: 0x0759, 0x0e04: 0x075d, 0x0e05: 0x0379, + 0x0e06: 0x0379, + 0x0e13: 0x1c62, 0x0e14: 0x1c53, 0x0e15: 0x1c58, 0x0e16: 0x1c67, 0x0e17: 0x1c5d, + 0x0e1d: 0x428e, + 0x0e1e: 0x801a, 0x0e1f: 0x4300, 0x0e20: 0x04e4, 0x0e21: 0x04cc, 0x0e22: 0x04d5, 0x0e23: 0x04d8, + 0x0e24: 0x04db, 0x0e25: 0x04de, 0x0e26: 0x04e1, 0x0e27: 0x04e7, 0x0e28: 0x04ea, 0x0e29: 0x00e5, + 0x0e2a: 0x42ee, 0x0e2b: 0x42f4, 0x0e2c: 0x43f2, 0x0e2d: 0x43fa, 0x0e2e: 0x4246, 0x0e2f: 0x424c, + 0x0e30: 0x4252, 0x0e31: 0x4258, 0x0e32: 0x4264, 0x0e33: 0x426a, 0x0e34: 0x4270, 0x0e35: 0x427c, + 0x0e36: 0x4282, 0x0e38: 0x4288, 0x0e39: 0x4294, 0x0e3a: 0x429a, 0x0e3b: 0x42a0, + 0x0e3c: 0x42ac, 0x0e3e: 0x42b2, // Block 0x39, offset 0xe40 - 0x0e40: 0x3c3f, 0x0e41: 0x3c46, 0x0e42: 0x2291, - 0x0e50: 0x1922, 0x0e51: 0x3c4d, - 0x0e52: 0x3c51, 0x0e53: 0x1cb3, 0x0e54: 0x183e, 0x0e55: 0x3c55, 0x0e56: 0x3c59, 0x0e57: 0x1ed0, - 0x0e58: 0x3c5d, 0x0e59: 0x3c61, 0x0e5a: 0x3c65, 0x0e5b: 0x2d49, 0x0e5c: 0x3c69, 0x0e5d: 0x3c6d, - 0x0e5e: 0x3c71, 0x0e5f: 0x3c75, 0x0e60: 0x3c79, 0x0e61: 0x3c7d, 0x0e62: 0x19b2, 0x0e63: 0x3c81, - 0x0e64: 0x3c85, 0x0e65: 0x3c89, 0x0e66: 0x3c8d, 0x0e67: 0x3c91, 0x0e68: 0x3c95, 0x0e69: 0x1826, - 0x0e6a: 0x1eb0, 0x0e6b: 0x3c99, 0x0e6c: 0x21c7, 0x0e6d: 0x1ebc, 0x0e6e: 0x21cb, 0x0e6f: 0x3c9d, - 0x0e70: 0x1a92, 0x0e71: 0x3ca1, 0x0e72: 0x3ca5, 0x0e73: 0x3ca9, 0x0e74: 0x3cad, 0x0e75: 0x3cb1, - 0x0e76: 0x2183, 0x0e77: 0x194a, 0x0e78: 0x3cb5, 0x0e79: 0x3cb9, 0x0e7a: 0x3cbd, + 0x0e40: 0x42b8, 0x0e41: 0x42be, 0x0e43: 0x42c4, 0x0e44: 0x42ca, + 0x0e46: 0x42d6, 0x0e47: 0x42dc, 0x0e48: 0x42e2, 0x0e49: 0x42e8, 0x0e4a: 0x42fa, 0x0e4b: 0x4276, + 0x0e4c: 0x425e, 0x0e4d: 0x42a6, 0x0e4e: 0x42d0, 0x0e4f: 0x1c6c, 0x0e50: 0x054a, 0x0e51: 0x054a, + 0x0e52: 0x0553, 0x0e53: 0x0553, 0x0e54: 0x0553, 0x0e55: 0x0553, 0x0e56: 0x0556, 0x0e57: 0x0556, + 0x0e58: 0x0556, 0x0e59: 0x0556, 0x0e5a: 0x055c, 0x0e5b: 0x055c, 0x0e5c: 0x055c, 0x0e5d: 0x055c, + 0x0e5e: 0x0550, 0x0e5f: 0x0550, 0x0e60: 0x0550, 0x0e61: 0x0550, 0x0e62: 0x0559, 0x0e63: 0x0559, + 0x0e64: 0x0559, 0x0e65: 0x0559, 0x0e66: 0x054d, 0x0e67: 0x054d, 0x0e68: 0x054d, 0x0e69: 0x054d, + 0x0e6a: 0x057d, 0x0e6b: 0x057d, 0x0e6c: 0x057d, 0x0e6d: 0x057d, 0x0e6e: 0x0580, 0x0e6f: 0x0580, + 0x0e70: 0x0580, 0x0e71: 0x0580, 0x0e72: 0x0562, 0x0e73: 0x0562, 0x0e74: 0x0562, 0x0e75: 0x0562, + 0x0e76: 0x055f, 0x0e77: 0x055f, 0x0e78: 0x055f, 0x0e79: 0x055f, 0x0e7a: 0x0565, 0x0e7b: 0x0565, + 0x0e7c: 0x0565, 0x0e7d: 0x0565, 0x0e7e: 0x0568, 0x0e7f: 0x0568, // Block 0x3a, offset 0xe80 - 0x0e80: 0x3d23, 0x0e81: 0x3d27, 0x0e82: 0x3d2b, 0x0e83: 0x3d2f, 0x0e84: 0x3d34, 0x0e85: 0x2eb5, - 0x0e86: 0x3d38, 0x0e87: 0x3d3c, 0x0e88: 0x3d40, 0x0e89: 0x3d44, 0x0e8a: 0x2eb9, 0x0e8b: 0x3d48, - 0x0e8c: 0x3d4c, 0x0e8d: 0x3d50, 0x0e8e: 0x2ebd, 0x0e8f: 0x3d55, 0x0e90: 0x3d59, 0x0e91: 0x3d5d, - 0x0e92: 0x3d61, 0x0e93: 0x3d66, 0x0e94: 0x3d6a, 0x0e95: 0x3c71, 0x0e96: 0x3d6e, 0x0e97: 0x3d73, - 0x0e98: 0x3d77, 0x0e99: 0x3d7b, 0x0e9a: 0x3d7f, 0x0e9b: 0x2f9a, 0x0e9c: 0x3d83, 0x0e9d: 0x1866, - 0x0e9e: 0x3d88, 0x0e9f: 0x3d8c, 0x0ea0: 0x3d90, 0x0ea1: 0x3d94, 0x0ea2: 0x3cb9, 0x0ea3: 0x3d98, - 0x0ea4: 0x3d9c, 0x0ea5: 0x2fae, 0x0ea6: 0x2ec1, 0x0ea7: 0x2ec5, 0x0ea8: 0x2fb2, 0x0ea9: 0x3da0, - 0x0eaa: 0x3da4, 0x0eab: 0x2bf1, 0x0eac: 0x3da8, 0x0ead: 0x2ec9, 0x0eae: 0x3dac, 0x0eaf: 0x3db0, - 0x0eb0: 0x3db4, 0x0eb1: 0x3db8, 0x0eb2: 0x3db8, 0x0eb3: 0x3db8, 0x0eb4: 0x3dbc, 0x0eb5: 0x3dc1, - 0x0eb6: 0x3dc5, 0x0eb7: 0x3dc9, 0x0eb8: 0x3dcd, 0x0eb9: 0x3dd2, 0x0eba: 0x3dd6, 0x0ebb: 0x3dda, - 0x0ebc: 0x3dde, 0x0ebd: 0x3de2, 0x0ebe: 0x3de6, 0x0ebf: 0x3dea, + 0x0e80: 0x0568, 0x0e81: 0x0568, 0x0e82: 0x0571, 0x0e83: 0x0571, 0x0e84: 0x056e, 0x0e85: 0x056e, + 0x0e86: 0x0574, 0x0e87: 0x0574, 0x0e88: 0x056b, 0x0e89: 0x056b, 0x0e8a: 0x057a, 0x0e8b: 0x057a, + 0x0e8c: 0x0577, 0x0e8d: 0x0577, 0x0e8e: 0x0583, 0x0e8f: 0x0583, 0x0e90: 0x0583, 0x0e91: 0x0583, + 0x0e92: 0x0589, 0x0e93: 0x0589, 0x0e94: 0x0589, 0x0e95: 0x0589, 0x0e96: 0x058f, 0x0e97: 0x058f, + 0x0e98: 0x058f, 0x0e99: 0x058f, 0x0e9a: 0x058c, 0x0e9b: 0x058c, 0x0e9c: 0x058c, 0x0e9d: 0x058c, + 0x0e9e: 0x0592, 0x0e9f: 0x0592, 0x0ea0: 0x0595, 0x0ea1: 0x0595, 0x0ea2: 0x0595, 0x0ea3: 0x0595, + 0x0ea4: 0x436c, 0x0ea5: 0x436c, 0x0ea6: 0x059b, 0x0ea7: 0x059b, 0x0ea8: 0x059b, 0x0ea9: 0x059b, + 0x0eaa: 0x0598, 0x0eab: 0x0598, 0x0eac: 0x0598, 0x0ead: 0x0598, 0x0eae: 0x05b6, 0x0eaf: 0x05b6, + 0x0eb0: 0x4366, 0x0eb1: 0x4366, // Block 0x3b, offset 0xec0 - 0x0ec0: 0x3dee, 0x0ec1: 0x3df2, 0x0ec2: 0x3df6, 0x0ec3: 0x3dfa, 0x0ec4: 0x3dfe, 0x0ec5: 0x3e02, - 0x0ec6: 0x3e02, 0x0ec7: 0x2fba, 0x0ec8: 0x3e06, 0x0ec9: 0x3e0a, 0x0eca: 0x3e0e, 0x0ecb: 0x3e12, - 0x0ecc: 0x2ed1, 0x0ecd: 0x3e16, 0x0ece: 0x3e1a, 0x0ecf: 0x3e1e, 0x0ed0: 0x2e39, 0x0ed1: 0x3e22, - 0x0ed2: 0x3e26, 0x0ed3: 0x3e2a, 0x0ed4: 0x3e2e, 0x0ed5: 0x3e32, 0x0ed6: 0x3e36, 0x0ed7: 0x3e3a, - 0x0ed8: 0x3e3e, 0x0ed9: 0x3e42, 0x0eda: 0x3e47, 0x0edb: 0x3e4b, 0x0edc: 0x3e4f, 0x0edd: 0x3c55, - 0x0ede: 0x3e53, 0x0edf: 0x3e57, 0x0ee0: 0x3e5b, 0x0ee1: 0x3e60, 0x0ee2: 0x3e65, 0x0ee3: 0x3e69, - 0x0ee4: 0x3e6d, 0x0ee5: 0x3e71, 0x0ee6: 0x3e75, 0x0ee7: 0x3e79, 0x0ee8: 0x3e7d, 0x0ee9: 0x3e81, - 0x0eea: 0x3e85, 0x0eeb: 0x3e85, 0x0eec: 0x3e89, 0x0eed: 0x3e8e, 0x0eee: 0x3e92, 0x0eef: 0x2be1, - 0x0ef0: 0x3e96, 0x0ef1: 0x3e9a, 0x0ef2: 0x3e9f, 0x0ef3: 0x3ea3, 0x0ef4: 0x3ea7, 0x0ef5: 0x18ce, - 0x0ef6: 0x3eab, 0x0ef7: 0x3eaf, 0x0ef8: 0x18d6, 0x0ef9: 0x3eb3, 0x0efa: 0x3eb7, 0x0efb: 0x3ebb, - 0x0efc: 0x3ec0, 0x0efd: 0x3ec4, 0x0efe: 0x3ec9, 0x0eff: 0x3ecd, + 0x0ed3: 0x0586, 0x0ed4: 0x0586, 0x0ed5: 0x0586, 0x0ed6: 0x0586, 0x0ed7: 0x05a4, + 0x0ed8: 0x05a4, 0x0ed9: 0x05a1, 0x0eda: 0x05a1, 0x0edb: 0x05a7, 0x0edc: 0x05a7, 0x0edd: 0x1f3c, + 0x0ede: 0x05ad, 0x0edf: 0x05ad, 0x0ee0: 0x059e, 0x0ee1: 0x059e, 0x0ee2: 0x05aa, 0x0ee3: 0x05aa, + 0x0ee4: 0x05b3, 0x0ee5: 0x05b3, 0x0ee6: 0x05b3, 0x0ee7: 0x05b3, 0x0ee8: 0x0544, 0x0ee9: 0x0544, + 0x0eea: 0x26bd, 0x0eeb: 0x26bd, 0x0eec: 0x272d, 0x0eed: 0x272d, 0x0eee: 0x26fc, 0x0eef: 0x26fc, + 0x0ef0: 0x2718, 0x0ef1: 0x2718, 0x0ef2: 0x2711, 0x0ef3: 0x2711, 0x0ef4: 0x271f, 0x0ef5: 0x271f, + 0x0ef6: 0x2726, 0x0ef7: 0x2726, 0x0ef8: 0x2726, 0x0ef9: 0x2703, 0x0efa: 0x2703, 0x0efb: 0x2703, + 0x0efc: 0x05b0, 0x0efd: 0x05b0, 0x0efe: 0x05b0, 0x0eff: 0x05b0, // Block 0x3c, offset 0xf00 - 0x0f00: 0x3ed1, 0x0f01: 0x3ed5, 0x0f02: 0x3ed9, 0x0f03: 0x3edd, 0x0f04: 0x3ee1, 0x0f05: 0x3ee5, - 0x0f06: 0x3ee9, 0x0f07: 0x3eed, 0x0f08: 0x3ef1, 0x0f09: 0x3ef5, 0x0f0a: 0x3efa, 0x0f0b: 0x3efe, - 0x0f0c: 0x3f02, 0x0f0d: 0x3f06, 0x0f0e: 0x2b11, 0x0f0f: 0x3f0a, 0x0f10: 0x18fe, 0x0f11: 0x3f0f, - 0x0f12: 0x3f0f, 0x0f13: 0x3f14, 0x0f14: 0x3f18, 0x0f15: 0x3f18, 0x0f16: 0x3f1c, 0x0f17: 0x3f20, - 0x0f18: 0x3f25, 0x0f19: 0x3f2a, 0x0f1a: 0x3f2e, 0x0f1b: 0x3f32, 0x0f1c: 0x3f36, 0x0f1d: 0x3f3a, - 0x0f1e: 0x3f3e, 0x0f1f: 0x3f42, 0x0f20: 0x3f46, 0x0f21: 0x3f4a, 0x0f22: 0x3f4e, 0x0f23: 0x2ee5, - 0x0f24: 0x3f52, 0x0f25: 0x3f57, 0x0f26: 0x3f5b, 0x0f27: 0x3f5f, 0x0f28: 0x2fea, 0x0f29: 0x3f5f, - 0x0f2a: 0x3f63, 0x0f2b: 0x2eed, 0x0f2c: 0x3f67, 0x0f2d: 0x3f6b, 0x0f2e: 0x3f6f, 0x0f2f: 0x3f73, - 0x0f30: 0x2ef1, 0x0f31: 0x2aa5, 0x0f32: 0x3f77, 0x0f33: 0x3f7b, 0x0f34: 0x3f7f, 0x0f35: 0x3f83, - 0x0f36: 0x3f87, 0x0f37: 0x3f8b, 0x0f38: 0x3f8f, 0x0f39: 0x3f94, 0x0f3a: 0x3f98, 0x0f3b: 0x3f9c, - 0x0f3c: 0x3fa0, 0x0f3d: 0x3fa4, 0x0f3e: 0x3fa8, 0x0f3f: 0x3fad, + 0x0f00: 0x26c4, 0x0f01: 0x26cb, 0x0f02: 0x26e7, 0x0f03: 0x2703, 0x0f04: 0x270a, 0x0f05: 0x1c76, + 0x0f06: 0x1c7b, 0x0f07: 0x1c80, 0x0f08: 0x1c8f, 0x0f09: 0x1c9e, 0x0f0a: 0x1ca3, 0x0f0b: 0x1ca8, + 0x0f0c: 0x1cad, 0x0f0d: 0x1cb2, 0x0f0e: 0x1cc1, 0x0f0f: 0x1cd0, 0x0f10: 0x1cd5, 0x0f11: 0x1cda, + 0x0f12: 0x1ce9, 0x0f13: 0x1cf8, 0x0f14: 0x1cfd, 0x0f15: 0x1d02, 0x0f16: 0x1d07, 0x0f17: 0x1d16, + 0x0f18: 0x1d1b, 0x0f19: 0x1d2a, 0x0f1a: 0x1d2f, 0x0f1b: 0x1d34, 0x0f1c: 0x1d43, 0x0f1d: 0x1d48, + 0x0f1e: 0x1d4d, 0x0f1f: 0x1d57, 0x0f20: 0x1d93, 0x0f21: 0x1da2, 0x0f22: 0x1db1, 0x0f23: 0x1db6, + 0x0f24: 0x1dbb, 0x0f25: 0x1dc5, 0x0f26: 0x1dd4, 0x0f27: 0x1dd9, 0x0f28: 0x1de8, 0x0f29: 0x1ded, + 0x0f2a: 0x1df2, 0x0f2b: 0x1e01, 0x0f2c: 0x1e06, 0x0f2d: 0x1e15, 0x0f2e: 0x1e1a, 0x0f2f: 0x1e1f, + 0x0f30: 0x1e24, 0x0f31: 0x1e29, 0x0f32: 0x1e2e, 0x0f33: 0x1e33, 0x0f34: 0x1e38, 0x0f35: 0x1e3d, + 0x0f36: 0x1e42, 0x0f37: 0x1e47, 0x0f38: 0x1e4c, 0x0f39: 0x1e51, 0x0f3a: 0x1e56, 0x0f3b: 0x1e5b, + 0x0f3c: 0x1e60, 0x0f3d: 0x1e65, 0x0f3e: 0x1e6a, 0x0f3f: 0x1e74, // Block 0x3d, offset 0xf40 - 0x0f40: 0x3fb1, 0x0f41: 0x3fb5, 0x0f42: 0x3fb9, 0x0f43: 0x3fbd, 0x0f44: 0x3fc1, 0x0f45: 0x3fc5, - 0x0f46: 0x3fc9, 0x0f47: 0x3fcd, 0x0f48: 0x2ef5, 0x0f49: 0x3fd1, 0x0f4a: 0x3fd5, 0x0f4b: 0x3fda, - 0x0f4c: 0x3fde, 0x0f4d: 0x3fe2, 0x0f4e: 0x3fe6, 0x0f4f: 0x2efd, 0x0f50: 0x3fea, 0x0f51: 0x3fee, - 0x0f52: 0x3ff2, 0x0f53: 0x3ff6, 0x0f54: 0x3ffa, 0x0f55: 0x3ffe, 0x0f56: 0x4002, 0x0f57: 0x4006, - 0x0f58: 0x2b15, 0x0f59: 0x300a, 0x0f5a: 0x400a, 0x0f5b: 0x400e, 0x0f5c: 0x4012, 0x0f5d: 0x4016, - 0x0f5e: 0x401b, 0x0f5f: 0x401f, 0x0f60: 0x4023, 0x0f61: 0x4027, 0x0f62: 0x2f01, 0x0f63: 0x402b, - 0x0f64: 0x4030, 0x0f65: 0x4034, 0x0f66: 0x4038, 0x0f67: 0x30b5, 0x0f68: 0x403c, 0x0f69: 0x4040, - 0x0f6a: 0x4044, 0x0f6b: 0x4048, 0x0f6c: 0x404c, 0x0f6d: 0x4051, 0x0f6e: 0x4055, 0x0f6f: 0x4059, - 0x0f70: 0x405d, 0x0f71: 0x4062, 0x0f72: 0x4066, 0x0f73: 0x406a, 0x0f74: 0x406e, 0x0f75: 0x2c25, - 0x0f76: 0x4072, 0x0f77: 0x4076, 0x0f78: 0x407b, 0x0f79: 0x4080, 0x0f7a: 0x4085, 0x0f7b: 0x4089, - 0x0f7c: 0x408e, 0x0f7d: 0x4092, 0x0f7e: 0x4096, 0x0f7f: 0x409a, + 0x0f40: 0x1e79, 0x0f41: 0x1e7e, 0x0f42: 0x1e83, 0x0f43: 0x1e8d, 0x0f44: 0x1e92, 0x0f45: 0x1e9c, + 0x0f46: 0x1ea1, 0x0f47: 0x1ea6, 0x0f48: 0x1eab, 0x0f49: 0x1eb0, 0x0f4a: 0x1eb5, 0x0f4b: 0x1eba, + 0x0f4c: 0x1ebf, 0x0f4d: 0x1ec4, 0x0f4e: 0x1ed3, 0x0f4f: 0x1ee2, 0x0f50: 0x1ee7, 0x0f51: 0x1eec, + 0x0f52: 0x1ef1, 0x0f53: 0x1ef6, 0x0f54: 0x1efb, 0x0f55: 0x1f05, 0x0f56: 0x1f0a, 0x0f57: 0x1f0f, + 0x0f58: 0x1f1e, 0x0f59: 0x1f2d, 0x0f5a: 0x1f32, 0x0f5b: 0x431e, 0x0f5c: 0x4324, 0x0f5d: 0x435a, + 0x0f5e: 0x43b1, 0x0f5f: 0x43b8, 0x0f60: 0x43bf, 0x0f61: 0x43c6, 0x0f62: 0x43cd, 0x0f63: 0x43d4, + 0x0f64: 0x26d9, 0x0f65: 0x26e0, 0x0f66: 0x26e7, 0x0f67: 0x26ee, 0x0f68: 0x2703, 0x0f69: 0x270a, + 0x0f6a: 0x1c85, 0x0f6b: 0x1c8a, 0x0f6c: 0x1c8f, 0x0f6d: 0x1c94, 0x0f6e: 0x1c9e, 0x0f6f: 0x1ca3, + 0x0f70: 0x1cb7, 0x0f71: 0x1cbc, 0x0f72: 0x1cc1, 0x0f73: 0x1cc6, 0x0f74: 0x1cd0, 0x0f75: 0x1cd5, + 0x0f76: 0x1cdf, 0x0f77: 0x1ce4, 0x0f78: 0x1ce9, 0x0f79: 0x1cee, 0x0f7a: 0x1cf8, 0x0f7b: 0x1cfd, + 0x0f7c: 0x1e29, 0x0f7d: 0x1e2e, 0x0f7e: 0x1e3d, 0x0f7f: 0x1e42, // Block 0x3e, offset 0xf80 - 0x0f80: 0x409e, 0x0f81: 0x2f05, 0x0f82: 0x2d71, 0x0f83: 0x40a2, 0x0f84: 0x40a6, 0x0f85: 0x40aa, - 0x0f86: 0x40ae, 0x0f87: 0x40b3, 0x0f88: 0x40b7, 0x0f89: 0x40bb, 0x0f8a: 0x40bf, 0x0f8b: 0x3016, - 0x0f8c: 0x40c3, 0x0f8d: 0x40c7, 0x0f8e: 0x40cc, 0x0f8f: 0x40d0, 0x0f90: 0x40d4, 0x0f91: 0x40d9, - 0x0f92: 0x40de, 0x0f93: 0x40e2, 0x0f94: 0x301a, 0x0f95: 0x40e6, 0x0f96: 0x40ea, 0x0f97: 0x40ee, - 0x0f98: 0x40f2, 0x0f99: 0x40f6, 0x0f9a: 0x40fa, 0x0f9b: 0x40fe, 0x0f9c: 0x4103, 0x0f9d: 0x4107, - 0x0f9e: 0x410c, 0x0f9f: 0x4110, 0x0fa0: 0x4115, 0x0fa1: 0x3022, 0x0fa2: 0x4119, 0x0fa3: 0x411d, - 0x0fa4: 0x4122, 0x0fa5: 0x4126, 0x0fa6: 0x412a, 0x0fa7: 0x412f, 0x0fa8: 0x4134, 0x0fa9: 0x4138, - 0x0faa: 0x413c, 0x0fab: 0x4140, 0x0fac: 0x4144, 0x0fad: 0x4144, 0x0fae: 0x4148, 0x0faf: 0x414c, - 0x0fb0: 0x302a, 0x0fb1: 0x4150, 0x0fb2: 0x4154, 0x0fb3: 0x4158, 0x0fb4: 0x415c, 0x0fb5: 0x4160, - 0x0fb6: 0x4165, 0x0fb7: 0x4169, 0x0fb8: 0x2bed, 0x0fb9: 0x416e, 0x0fba: 0x4173, 0x0fbb: 0x4177, - 0x0fbc: 0x417c, 0x0fbd: 0x4181, 0x0fbe: 0x4186, 0x0fbf: 0x418a, + 0x0f80: 0x1e47, 0x0f81: 0x1e5b, 0x0f82: 0x1e60, 0x0f83: 0x1e65, 0x0f84: 0x1e6a, 0x0f85: 0x1e83, + 0x0f86: 0x1e8d, 0x0f87: 0x1e92, 0x0f88: 0x1e97, 0x0f89: 0x1eab, 0x0f8a: 0x1ec9, 0x0f8b: 0x1ece, + 0x0f8c: 0x1ed3, 0x0f8d: 0x1ed8, 0x0f8e: 0x1ee2, 0x0f8f: 0x1ee7, 0x0f90: 0x435a, 0x0f91: 0x1f14, + 0x0f92: 0x1f19, 0x0f93: 0x1f1e, 0x0f94: 0x1f23, 0x0f95: 0x1f2d, 0x0f96: 0x1f32, 0x0f97: 0x26c4, + 0x0f98: 0x26cb, 0x0f99: 0x26d2, 0x0f9a: 0x26e7, 0x0f9b: 0x26f5, 0x0f9c: 0x1c76, 0x0f9d: 0x1c7b, + 0x0f9e: 0x1c80, 0x0f9f: 0x1c8f, 0x0fa0: 0x1c99, 0x0fa1: 0x1ca8, 0x0fa2: 0x1cad, 0x0fa3: 0x1cb2, + 0x0fa4: 0x1cc1, 0x0fa5: 0x1ccb, 0x0fa6: 0x1ce9, 0x0fa7: 0x1d02, 0x0fa8: 0x1d07, 0x0fa9: 0x1d16, + 0x0faa: 0x1d1b, 0x0fab: 0x1d2a, 0x0fac: 0x1d34, 0x0fad: 0x1d43, 0x0fae: 0x1d48, 0x0faf: 0x1d4d, + 0x0fb0: 0x1d57, 0x0fb1: 0x1d93, 0x0fb2: 0x1d98, 0x0fb3: 0x1da2, 0x0fb4: 0x1db1, 0x0fb5: 0x1db6, + 0x0fb6: 0x1dbb, 0x0fb7: 0x1dc5, 0x0fb8: 0x1dd4, 0x0fb9: 0x1de8, 0x0fba: 0x1ded, 0x0fbb: 0x1df2, + 0x0fbc: 0x1e01, 0x0fbd: 0x1e06, 0x0fbe: 0x1e15, 0x0fbf: 0x1e1a, // Block 0x3f, offset 0xfc0 - 0x0fc0: 0x3042, 0x0fc1: 0x418e, 0x0fc2: 0x4193, 0x0fc3: 0x4198, 0x0fc4: 0x419d, 0x0fc5: 0x41a2, - 0x0fc6: 0x41a6, 0x0fc7: 0x41a6, 0x0fc8: 0x3046, 0x0fc9: 0x30bd, 0x0fca: 0x41aa, 0x0fcb: 0x41ae, - 0x0fcc: 0x41b2, 0x0fcd: 0x41b6, 0x0fce: 0x41bb, 0x0fcf: 0x2b59, 0x0fd0: 0x304e, 0x0fd1: 0x41bf, - 0x0fd2: 0x41c3, 0x0fd3: 0x2f2d, 0x0fd4: 0x41c8, 0x0fd5: 0x41cd, 0x0fd6: 0x2e89, 0x0fd7: 0x41d2, - 0x0fd8: 0x41d6, 0x0fd9: 0x2f39, 0x0fda: 0x41da, 0x0fdb: 0x41de, 0x0fdc: 0x41e2, 0x0fdd: 0x41e7, - 0x0fde: 0x41e7, 0x0fdf: 0x41ec, 0x0fe0: 0x41f0, 0x0fe1: 0x41f4, 0x0fe2: 0x41f9, 0x0fe3: 0x41fd, - 0x0fe4: 0x4201, 0x0fe5: 0x4205, 0x0fe6: 0x420a, 0x0fe7: 0x420e, 0x0fe8: 0x4212, 0x0fe9: 0x4216, - 0x0fea: 0x421a, 0x0feb: 0x421e, 0x0fec: 0x4223, 0x0fed: 0x4227, 0x0fee: 0x422b, 0x0fef: 0x422f, - 0x0ff0: 0x4233, 0x0ff1: 0x4237, 0x0ff2: 0x423b, 0x0ff3: 0x4240, 0x0ff4: 0x4245, 0x0ff5: 0x4249, - 0x0ff6: 0x424e, 0x0ff7: 0x4252, 0x0ff8: 0x4257, 0x0ff9: 0x425b, 0x0ffa: 0x2f51, 0x0ffb: 0x425f, - 0x0ffc: 0x4264, 0x0ffd: 0x4269, 0x0ffe: 0x426d, 0x0fff: 0x4272, + 0x0fc0: 0x1e1f, 0x0fc1: 0x1e24, 0x0fc2: 0x1e33, 0x0fc3: 0x1e38, 0x0fc4: 0x1e4c, 0x0fc5: 0x1e51, + 0x0fc6: 0x1e56, 0x0fc7: 0x1e5b, 0x0fc8: 0x1e60, 0x0fc9: 0x1e74, 0x0fca: 0x1e79, 0x0fcb: 0x1e7e, + 0x0fcc: 0x1e83, 0x0fcd: 0x1e88, 0x0fce: 0x1e9c, 0x0fcf: 0x1ea1, 0x0fd0: 0x1ea6, 0x0fd1: 0x1eab, + 0x0fd2: 0x1eba, 0x0fd3: 0x1ebf, 0x0fd4: 0x1ec4, 0x0fd5: 0x1ed3, 0x0fd6: 0x1edd, 0x0fd7: 0x1eec, + 0x0fd8: 0x1ef1, 0x0fd9: 0x434e, 0x0fda: 0x1f05, 0x0fdb: 0x1f0a, 0x0fdc: 0x1f0f, 0x0fdd: 0x1f1e, + 0x0fde: 0x1f28, 0x0fdf: 0x26e7, 0x0fe0: 0x26f5, 0x0fe1: 0x1c8f, 0x0fe2: 0x1c99, 0x0fe3: 0x1cc1, + 0x0fe4: 0x1ccb, 0x0fe5: 0x1ce9, 0x0fe6: 0x1cf3, 0x0fe7: 0x1d57, 0x0fe8: 0x1d5c, 0x0fe9: 0x1d7f, + 0x0fea: 0x1d84, 0x0feb: 0x1e5b, 0x0fec: 0x1e60, 0x0fed: 0x1e83, 0x0fee: 0x1ed3, 0x0fef: 0x1edd, + 0x0ff0: 0x1f1e, 0x0ff1: 0x1f28, 0x0ff2: 0x4402, 0x0ff3: 0x440a, 0x0ff4: 0x4412, 0x0ff5: 0x1dde, + 0x0ff6: 0x1de3, 0x0ff7: 0x1df7, 0x0ff8: 0x1dfc, 0x0ff9: 0x1e0b, 0x0ffa: 0x1e10, 0x0ffb: 0x1d61, + 0x0ffc: 0x1d66, 0x0ffd: 0x1d89, 0x0ffe: 0x1d8e, 0x0fff: 0x1d20, // Block 0x40, offset 0x1000 - 0x1000: 0x4276, 0x1001: 0x427b, 0x1002: 0x427f, 0x1003: 0x4283, 0x1004: 0x4287, 0x1005: 0x428b, - 0x1006: 0x428f, 0x1007: 0x4293, 0x1008: 0x4298, 0x1009: 0x429d, 0x100a: 0x42a2, 0x100b: 0x3f14, - 0x100c: 0x42a7, 0x100d: 0x42ab, 0x100e: 0x42af, 0x100f: 0x42b3, 0x1010: 0x42b7, 0x1011: 0x42bb, - 0x1012: 0x42bf, 0x1013: 0x42c3, 0x1014: 0x42c7, 0x1015: 0x42cb, 0x1016: 0x42cf, 0x1017: 0x42d3, - 0x1018: 0x2c31, 0x1019: 0x42d8, 0x101a: 0x42dc, 0x101b: 0x42e0, 0x101c: 0x42e4, 0x101d: 0x42e8, - 0x101e: 0x42ec, 0x101f: 0x2f5d, 0x1020: 0x42f0, 0x1021: 0x42f4, 0x1022: 0x42f8, 0x1023: 0x42fc, - 0x1024: 0x4300, 0x1025: 0x4305, 0x1026: 0x430a, 0x1027: 0x430f, 0x1028: 0x4313, 0x1029: 0x4317, - 0x102a: 0x431b, 0x102b: 0x431f, 0x102c: 0x4324, 0x102d: 0x4328, 0x102e: 0x432d, 0x102f: 0x4331, - 0x1030: 0x4335, 0x1031: 0x433a, 0x1032: 0x433f, 0x1033: 0x4343, 0x1034: 0x2b45, 0x1035: 0x4347, - 0x1036: 0x434b, 0x1037: 0x434f, 0x1038: 0x4353, 0x1039: 0x4357, 0x103a: 0x435b, 0x103b: 0x306a, - 0x103c: 0x435f, 0x103d: 0x4363, 0x103e: 0x4367, 0x103f: 0x436b, + 0x1000: 0x1d25, 0x1001: 0x1d0c, 0x1002: 0x1d11, 0x1003: 0x1d39, 0x1004: 0x1d3e, 0x1005: 0x1da7, + 0x1006: 0x1dac, 0x1007: 0x1dca, 0x1008: 0x1dcf, 0x1009: 0x1d6b, 0x100a: 0x1d70, 0x100b: 0x1d75, + 0x100c: 0x1d7f, 0x100d: 0x1d7a, 0x100e: 0x1d52, 0x100f: 0x1d9d, 0x1010: 0x1dc0, 0x1011: 0x1dde, + 0x1012: 0x1de3, 0x1013: 0x1df7, 0x1014: 0x1dfc, 0x1015: 0x1e0b, 0x1016: 0x1e10, 0x1017: 0x1d61, + 0x1018: 0x1d66, 0x1019: 0x1d89, 0x101a: 0x1d8e, 0x101b: 0x1d20, 0x101c: 0x1d25, 0x101d: 0x1d0c, + 0x101e: 0x1d11, 0x101f: 0x1d39, 0x1020: 0x1d3e, 0x1021: 0x1da7, 0x1022: 0x1dac, 0x1023: 0x1dca, + 0x1024: 0x1dcf, 0x1025: 0x1d6b, 0x1026: 0x1d70, 0x1027: 0x1d75, 0x1028: 0x1d7f, 0x1029: 0x1d7a, + 0x102a: 0x1d52, 0x102b: 0x1d9d, 0x102c: 0x1dc0, 0x102d: 0x1d6b, 0x102e: 0x1d70, 0x102f: 0x1d75, + 0x1030: 0x1d7f, 0x1031: 0x1d5c, 0x1032: 0x1d84, 0x1033: 0x1dd9, 0x1034: 0x1d43, 0x1035: 0x1d48, + 0x1036: 0x1d4d, 0x1037: 0x1d6b, 0x1038: 0x1d70, 0x1039: 0x1d75, 0x103a: 0x1dd9, 0x103b: 0x1de8, + 0x103c: 0x4306, 0x103d: 0x4306, // Block 0x41, offset 0x1040 - 0x1040: 0x436f, 0x1041: 0x4373, 0x1042: 0x4377, 0x1043: 0x437b, 0x1044: 0x1a66, 0x1045: 0x437f, - 0x1046: 0x4384, 0x1047: 0x4388, 0x1048: 0x438c, 0x1049: 0x4390, 0x104a: 0x4394, 0x104b: 0x4398, - 0x104c: 0x439d, 0x104d: 0x43a2, 0x104e: 0x43a6, 0x104f: 0x43aa, 0x1050: 0x307e, 0x1051: 0x3082, - 0x1052: 0x1a82, 0x1053: 0x43ae, 0x1054: 0x43b3, 0x1055: 0x43b7, 0x1056: 0x43bb, 0x1057: 0x43bf, - 0x1058: 0x43c3, 0x1059: 0x43c8, 0x105a: 0x43cd, 0x105b: 0x43d1, 0x105c: 0x43d5, 0x105d: 0x43d9, - 0x105e: 0x43de, 0x105f: 0x3086, 0x1060: 0x43e2, 0x1061: 0x43e7, 0x1062: 0x43ec, 0x1063: 0x43f0, - 0x1064: 0x43f4, 0x1065: 0x43f8, 0x1066: 0x43fd, 0x1067: 0x4401, 0x1068: 0x4405, 0x1069: 0x4409, - 0x106a: 0x440d, 0x106b: 0x4411, 0x106c: 0x4415, 0x106d: 0x4419, 0x106e: 0x441e, 0x106f: 0x4422, - 0x1070: 0x4426, 0x1071: 0x442a, 0x1072: 0x442f, 0x1073: 0x4433, 0x1074: 0x4437, 0x1075: 0x443b, - 0x1076: 0x443f, 0x1077: 0x4444, 0x1078: 0x4449, 0x1079: 0x444d, 0x107a: 0x4451, 0x107b: 0x4455, - 0x107c: 0x445a, 0x107d: 0x445e, 0x107e: 0x309e, 0x107f: 0x309e, + 0x1050: 0x2424, 0x1051: 0x2439, + 0x1052: 0x2439, 0x1053: 0x2440, 0x1054: 0x2447, 0x1055: 0x245c, 0x1056: 0x2463, 0x1057: 0x246a, + 0x1058: 0x248d, 0x1059: 0x248d, 0x105a: 0x24b0, 0x105b: 0x24a9, 0x105c: 0x24c5, 0x105d: 0x24b7, + 0x105e: 0x24be, 0x105f: 0x24e1, 0x1060: 0x24e1, 0x1061: 0x24da, 0x1062: 0x24e8, 0x1063: 0x24e8, + 0x1064: 0x2512, 0x1065: 0x2512, 0x1066: 0x252e, 0x1067: 0x24f6, 0x1068: 0x24f6, 0x1069: 0x24ef, + 0x106a: 0x2504, 0x106b: 0x2504, 0x106c: 0x250b, 0x106d: 0x250b, 0x106e: 0x2535, 0x106f: 0x2543, + 0x1070: 0x2543, 0x1071: 0x254a, 0x1072: 0x254a, 0x1073: 0x2551, 0x1074: 0x2558, 0x1075: 0x255f, + 0x1076: 0x2566, 0x1077: 0x2566, 0x1078: 0x256d, 0x1079: 0x257b, 0x107a: 0x2589, 0x107b: 0x2582, + 0x107c: 0x2590, 0x107d: 0x2590, 0x107e: 0x25a5, 0x107f: 0x25ac, + // Block 0x42, offset 0x1080 + 0x1080: 0x25dd, 0x1081: 0x25eb, 0x1082: 0x25e4, 0x1083: 0x25c8, 0x1084: 0x25c8, 0x1085: 0x25f2, + 0x1086: 0x25f2, 0x1087: 0x25f9, 0x1088: 0x25f9, 0x1089: 0x2623, 0x108a: 0x262a, 0x108b: 0x2631, + 0x108c: 0x2607, 0x108d: 0x2615, 0x108e: 0x2638, 0x108f: 0x263f, + 0x1092: 0x260e, 0x1093: 0x2693, 0x1094: 0x269a, 0x1095: 0x2670, 0x1096: 0x2677, 0x1097: 0x265b, + 0x1098: 0x265b, 0x1099: 0x2662, 0x109a: 0x268c, 0x109b: 0x2685, 0x109c: 0x26af, 0x109d: 0x26af, + 0x109e: 0x241d, 0x109f: 0x2432, 0x10a0: 0x242b, 0x10a1: 0x2455, 0x10a2: 0x244e, 0x10a3: 0x2478, + 0x10a4: 0x2471, 0x10a5: 0x249b, 0x10a6: 0x247f, 0x10a7: 0x2494, 0x10a8: 0x24cc, 0x10a9: 0x2519, + 0x10aa: 0x24fd, 0x10ab: 0x253c, 0x10ac: 0x25d6, 0x10ad: 0x2600, 0x10ae: 0x26a8, 0x10af: 0x26a1, + 0x10b0: 0x26b6, 0x10b1: 0x264d, 0x10b2: 0x25b3, 0x10b3: 0x267e, 0x10b4: 0x25a5, 0x10b5: 0x25dd, + 0x10b6: 0x2574, 0x10b7: 0x25c1, 0x10b8: 0x2654, 0x10b9: 0x2646, 0x10ba: 0x25cf, 0x10bb: 0x25ba, + 0x10bc: 0x25cf, 0x10bd: 0x2654, 0x10be: 0x2486, 0x10bf: 0x24a2, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x261c, 0x10c1: 0x2597, 0x10c2: 0x2416, 0x10c3: 0x25ba, 0x10c4: 0x255f, 0x10c5: 0x252e, + 0x10c6: 0x24d3, 0x10c7: 0x2669, + 0x10f0: 0x2527, 0x10f1: 0x259e, 0x10f2: 0x293b, 0x10f3: 0x2932, 0x10f4: 0x2968, 0x10f5: 0x2956, + 0x10f6: 0x2944, 0x10f7: 0x295f, 0x10f8: 0x2971, 0x10f9: 0x2520, 0x10fa: 0x2e15, 0x10fb: 0x2c85, + 0x10fc: 0x294d, + // Block 0x44, offset 0x1100 + 0x1110: 0x00e7, 0x1111: 0x09c1, + 0x1112: 0x09c5, 0x1113: 0x0103, 0x1114: 0x0105, 0x1115: 0x00d1, 0x1116: 0x010d, 0x1117: 0x09fd, + 0x1118: 0x0a01, 0x1119: 0x06ad, + 0x1120: 0x80e6, 0x1121: 0x80e6, 0x1122: 0x80e6, 0x1123: 0x80e6, + 0x1124: 0x80e6, 0x1125: 0x80e6, 0x1126: 0x80e6, + 0x1130: 0x0193, 0x1131: 0x0981, 0x1132: 0x097d, 0x1133: 0x014d, 0x1134: 0x014d, 0x1135: 0x00df, + 0x1136: 0x00e1, 0x1137: 0x0185, 0x1138: 0x0189, 0x1139: 0x09f5, 0x113a: 0x09f9, 0x113b: 0x09e9, + 0x113c: 0x09ed, 0x113d: 0x09d1, 0x113e: 0x09d5, 0x113f: 0x09c9, + // Block 0x45, offset 0x1140 + 0x1140: 0x09cd, 0x1141: 0x09d9, 0x1142: 0x09dd, 0x1143: 0x09e1, 0x1144: 0x09e5, + 0x1147: 0x0145, 0x1148: 0x0149, 0x1149: 0x4155, 0x114a: 0x4155, 0x114b: 0x4155, + 0x114c: 0x4155, 0x114d: 0x014d, 0x114e: 0x014d, 0x114f: 0x014d, 0x1150: 0x00e7, 0x1151: 0x09c1, + 0x1152: 0x00eb, 0x1154: 0x0105, 0x1155: 0x0103, 0x1156: 0x010d, 0x1157: 0x00d1, + 0x1158: 0x0981, 0x1159: 0x00df, 0x115a: 0x00e1, 0x115b: 0x0185, 0x115c: 0x0189, 0x115d: 0x09f5, + 0x115e: 0x09f9, 0x115f: 0x00d5, 0x1160: 0x00db, 0x1161: 0x00e3, 0x1162: 0x00e5, 0x1163: 0x00e9, + 0x1164: 0x0107, 0x1165: 0x010b, 0x1166: 0x0109, 0x1168: 0x0147, 0x1169: 0x00d7, + 0x116a: 0x00d9, 0x116b: 0x010f, + 0x1170: 0x4196, 0x1171: 0x432a, 0x1172: 0x419b, 0x1174: 0x41a0, + 0x1176: 0x41a5, 0x1177: 0x4330, 0x1178: 0x41aa, 0x1179: 0x4336, 0x117a: 0x41af, 0x117b: 0x433c, + 0x117c: 0x41b4, 0x117d: 0x4342, 0x117e: 0x41b9, 0x117f: 0x4348, + // Block 0x46, offset 0x1180 + 0x1180: 0x04ed, 0x1181: 0x430c, 0x1182: 0x430c, 0x1183: 0x4312, 0x1184: 0x4312, 0x1185: 0x4354, + 0x1186: 0x4354, 0x1187: 0x4318, 0x1188: 0x4318, 0x1189: 0x4360, 0x118a: 0x4360, 0x118b: 0x4360, + 0x118c: 0x4360, 0x118d: 0x04f0, 0x118e: 0x04f0, 0x118f: 0x04f3, 0x1190: 0x04f3, 0x1191: 0x04f3, + 0x1192: 0x04f3, 0x1193: 0x04f6, 0x1194: 0x04f6, 0x1195: 0x04f9, 0x1196: 0x04f9, 0x1197: 0x04f9, + 0x1198: 0x04f9, 0x1199: 0x04fc, 0x119a: 0x04fc, 0x119b: 0x04fc, 0x119c: 0x04fc, 0x119d: 0x04ff, + 0x119e: 0x04ff, 0x119f: 0x04ff, 0x11a0: 0x04ff, 0x11a1: 0x0502, 0x11a2: 0x0502, 0x11a3: 0x0502, + 0x11a4: 0x0502, 0x11a5: 0x0505, 0x11a6: 0x0505, 0x11a7: 0x0505, 0x11a8: 0x0505, 0x11a9: 0x0508, + 0x11aa: 0x0508, 0x11ab: 0x050b, 0x11ac: 0x050b, 0x11ad: 0x050e, 0x11ae: 0x050e, 0x11af: 0x0511, + 0x11b0: 0x0511, 0x11b1: 0x0514, 0x11b2: 0x0514, 0x11b3: 0x0514, 0x11b4: 0x0514, 0x11b5: 0x0517, + 0x11b6: 0x0517, 0x11b7: 0x0517, 0x11b8: 0x0517, 0x11b9: 0x051a, 0x11ba: 0x051a, 0x11bb: 0x051a, + 0x11bc: 0x051a, 0x11bd: 0x051d, 0x11be: 0x051d, 0x11bf: 0x051d, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x051d, 0x11c1: 0x0520, 0x11c2: 0x0520, 0x11c3: 0x0520, 0x11c4: 0x0520, 0x11c5: 0x0523, + 0x11c6: 0x0523, 0x11c7: 0x0523, 0x11c8: 0x0523, 0x11c9: 0x0526, 0x11ca: 0x0526, 0x11cb: 0x0526, + 0x11cc: 0x0526, 0x11cd: 0x0529, 0x11ce: 0x0529, 0x11cf: 0x0529, 0x11d0: 0x0529, 0x11d1: 0x052c, + 0x11d2: 0x052c, 0x11d3: 0x052c, 0x11d4: 0x052c, 0x11d5: 0x052f, 0x11d6: 0x052f, 0x11d7: 0x052f, + 0x11d8: 0x052f, 0x11d9: 0x0532, 0x11da: 0x0532, 0x11db: 0x0532, 0x11dc: 0x0532, 0x11dd: 0x0535, + 0x11de: 0x0535, 0x11df: 0x0535, 0x11e0: 0x0535, 0x11e1: 0x0538, 0x11e2: 0x0538, 0x11e3: 0x0538, + 0x11e4: 0x0538, 0x11e5: 0x053b, 0x11e6: 0x053b, 0x11e7: 0x053b, 0x11e8: 0x053b, 0x11e9: 0x053e, + 0x11ea: 0x053e, 0x11eb: 0x053e, 0x11ec: 0x053e, 0x11ed: 0x0541, 0x11ee: 0x0541, 0x11ef: 0x0544, + 0x11f0: 0x0544, 0x11f1: 0x0547, 0x11f2: 0x0547, 0x11f3: 0x0547, 0x11f4: 0x0547, 0x11f5: 0x441a, + 0x11f6: 0x441a, 0x11f7: 0x4422, 0x11f8: 0x4422, 0x11f9: 0x442a, 0x11fa: 0x442a, 0x11fb: 0x1e6f, + 0x11fc: 0x1e6f, + // Block 0x48, offset 0x1200 + 0x1200: 0x014f, 0x1201: 0x0151, 0x1202: 0x0153, 0x1203: 0x0155, 0x1204: 0x0157, 0x1205: 0x0159, + 0x1206: 0x015b, 0x1207: 0x015d, 0x1208: 0x015f, 0x1209: 0x0161, 0x120a: 0x0163, 0x120b: 0x0165, + 0x120c: 0x0167, 0x120d: 0x0169, 0x120e: 0x016b, 0x120f: 0x016d, 0x1210: 0x016f, 0x1211: 0x0171, + 0x1212: 0x0173, 0x1213: 0x0175, 0x1214: 0x0177, 0x1215: 0x0179, 0x1216: 0x017b, 0x1217: 0x017d, + 0x1218: 0x017f, 0x1219: 0x0181, 0x121a: 0x0183, 0x121b: 0x0185, 0x121c: 0x0187, 0x121d: 0x0189, + 0x121e: 0x018b, 0x121f: 0x09b5, 0x1220: 0x09b9, 0x1221: 0x09c5, 0x1222: 0x09d9, 0x1223: 0x09dd, + 0x1224: 0x09c1, 0x1225: 0x0ae9, 0x1226: 0x0ae1, 0x1227: 0x0a05, 0x1228: 0x0a0d, 0x1229: 0x0a15, + 0x122a: 0x0a1d, 0x122b: 0x0a25, 0x122c: 0x0aa9, 0x122d: 0x0ab1, 0x122e: 0x0ab9, 0x122f: 0x0a5d, + 0x1230: 0x0aed, 0x1231: 0x0a09, 0x1232: 0x0a11, 0x1233: 0x0a19, 0x1234: 0x0a21, 0x1235: 0x0a29, + 0x1236: 0x0a2d, 0x1237: 0x0a31, 0x1238: 0x0a35, 0x1239: 0x0a39, 0x123a: 0x0a3d, 0x123b: 0x0a41, + 0x123c: 0x0a45, 0x123d: 0x0a49, 0x123e: 0x0a4d, 0x123f: 0x0a51, + // Block 0x49, offset 0x1240 + 0x1240: 0x0a55, 0x1241: 0x0a59, 0x1242: 0x0a61, 0x1243: 0x0a65, 0x1244: 0x0a69, 0x1245: 0x0a6d, + 0x1246: 0x0a71, 0x1247: 0x0a75, 0x1248: 0x0a79, 0x1249: 0x0a7d, 0x124a: 0x0a81, 0x124b: 0x0a85, + 0x124c: 0x0a89, 0x124d: 0x0a8d, 0x124e: 0x0a91, 0x124f: 0x0a95, 0x1250: 0x0a99, 0x1251: 0x0a9d, + 0x1252: 0x0aa1, 0x1253: 0x0aa5, 0x1254: 0x0aad, 0x1255: 0x0ab5, 0x1256: 0x0abd, 0x1257: 0x0ac1, + 0x1258: 0x0ac5, 0x1259: 0x0ac9, 0x125a: 0x0acd, 0x125b: 0x0ad1, 0x125c: 0x0ad5, 0x125d: 0x0ae5, + 0x125e: 0x4974, 0x125f: 0x497a, 0x1260: 0x0889, 0x1261: 0x07d9, 0x1262: 0x07dd, 0x1263: 0x0901, + 0x1264: 0x07e1, 0x1265: 0x0905, 0x1266: 0x0909, 0x1267: 0x07e5, 0x1268: 0x07e9, 0x1269: 0x07ed, + 0x126a: 0x090d, 0x126b: 0x0911, 0x126c: 0x0915, 0x126d: 0x0919, 0x126e: 0x091d, 0x126f: 0x0921, + 0x1270: 0x082d, 0x1271: 0x07f1, 0x1272: 0x07f5, 0x1273: 0x07f9, 0x1274: 0x0841, 0x1275: 0x07fd, + 0x1276: 0x0801, 0x1277: 0x0805, 0x1278: 0x0809, 0x1279: 0x080d, 0x127a: 0x0811, 0x127b: 0x0815, + 0x127c: 0x0819, 0x127d: 0x081d, 0x127e: 0x0821, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0131, 0x1281: 0x0133, 0x1282: 0x0135, 0x1283: 0x0137, 0x1284: 0x0139, 0x1285: 0x013b, + 0x1286: 0x013d, 0x1287: 0x013f, 0x1288: 0x0141, 0x1289: 0x0143, 0x128a: 0x0151, 0x128b: 0x0153, + 0x128c: 0x0155, 0x128d: 0x0157, 0x128e: 0x0159, 0x128f: 0x015b, 0x1290: 0x015d, 0x1291: 0x015f, + 0x1292: 0x0161, 0x1293: 0x0163, 0x1294: 0x0165, 0x1295: 0x0167, 0x1296: 0x0169, 0x1297: 0x016b, + 0x1298: 0x016d, 0x1299: 0x016f, 0x129a: 0x0171, 0x129b: 0x0173, 0x129c: 0x0175, 0x129d: 0x0177, + 0x129e: 0x0179, 0x129f: 0x017b, 0x12a0: 0x017d, 0x12a1: 0x017f, 0x12a2: 0x0181, 0x12a3: 0x0183, + 0x12a4: 0x03a0, 0x12a5: 0x03b2, 0x12a8: 0x0430, 0x12a9: 0x0433, + 0x12aa: 0x0436, 0x12ab: 0x0439, 0x12ac: 0x043c, 0x12ad: 0x043f, 0x12ae: 0x0442, 0x12af: 0x0445, + 0x12b0: 0x0448, 0x12b1: 0x044b, 0x12b2: 0x044e, 0x12b3: 0x0451, 0x12b4: 0x0454, 0x12b5: 0x0457, + 0x12b6: 0x045a, 0x12b7: 0x045d, 0x12b8: 0x0460, 0x12b9: 0x0445, 0x12ba: 0x0463, 0x12bb: 0x0466, + 0x12bc: 0x0469, 0x12bd: 0x046c, 0x12be: 0x046f, 0x12bf: 0x0472, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x04ba, 0x12c1: 0x04bd, 0x12c2: 0x04c0, 0x12c3: 0x0999, 0x12c4: 0x0484, 0x12c5: 0x048d, + 0x12c6: 0x0493, 0x12c7: 0x04b7, 0x12c8: 0x04a8, 0x12c9: 0x04a5, 0x12ca: 0x04c3, 0x12cb: 0x04c6, + 0x12ce: 0x00ef, 0x12cf: 0x00f1, 0x12d0: 0x00f3, 0x12d1: 0x00f5, + 0x12d2: 0x00f7, 0x12d3: 0x00f9, 0x12d4: 0x00fb, 0x12d5: 0x00fd, 0x12d6: 0x00ff, 0x12d7: 0x0101, + 0x12d8: 0x00ef, 0x12d9: 0x00f1, 0x12da: 0x00f3, 0x12db: 0x00f5, 0x12dc: 0x00f7, 0x12dd: 0x00f9, + 0x12de: 0x00fb, 0x12df: 0x00fd, 0x12e0: 0x00ff, 0x12e1: 0x0101, 0x12e2: 0x00ef, 0x12e3: 0x00f1, + 0x12e4: 0x00f3, 0x12e5: 0x00f5, 0x12e6: 0x00f7, 0x12e7: 0x00f9, 0x12e8: 0x00fb, 0x12e9: 0x00fd, + 0x12ea: 0x00ff, 0x12eb: 0x0101, 0x12ec: 0x00ef, 0x12ed: 0x00f1, 0x12ee: 0x00f3, 0x12ef: 0x00f5, + 0x12f0: 0x00f7, 0x12f1: 0x00f9, 0x12f2: 0x00fb, 0x12f3: 0x00fd, 0x12f4: 0x00ff, 0x12f5: 0x0101, + 0x12f6: 0x00ef, 0x12f7: 0x00f1, 0x12f8: 0x00f3, 0x12f9: 0x00f5, 0x12fa: 0x00f7, 0x12fb: 0x00f9, + 0x12fc: 0x00fb, 0x12fd: 0x00fd, 0x12fe: 0x00ff, 0x12ff: 0x0101, + // Block 0x4c, offset 0x1300 + 0x1300: 0x0199, 0x1301: 0x0196, 0x1302: 0x019c, 0x1303: 0x01c0, 0x1304: 0x01e4, 0x1305: 0x0208, + 0x1306: 0x022c, 0x1307: 0x0235, 0x1308: 0x023b, 0x1309: 0x0241, 0x130a: 0x0247, + 0x1310: 0x05dd, 0x1311: 0x05e1, + 0x1312: 0x05e5, 0x1313: 0x05e9, 0x1314: 0x05ed, 0x1315: 0x05f1, 0x1316: 0x05f5, 0x1317: 0x05f9, + 0x1318: 0x05fd, 0x1319: 0x0601, 0x131a: 0x0605, 0x131b: 0x0609, 0x131c: 0x060d, 0x131d: 0x0611, + 0x131e: 0x0615, 0x131f: 0x0619, 0x1320: 0x061d, 0x1321: 0x0621, 0x1322: 0x0625, 0x1323: 0x0629, + 0x1324: 0x062d, 0x1325: 0x0631, 0x1326: 0x0635, 0x1327: 0x0639, 0x1328: 0x063d, 0x1329: 0x0641, + 0x132a: 0x289a, 0x132b: 0x0115, 0x132c: 0x0133, 0x132d: 0x025c, 0x132e: 0x02cb, + 0x1330: 0x0111, 0x1331: 0x0113, 0x1332: 0x0115, 0x1333: 0x0117, 0x1334: 0x0119, 0x1335: 0x011b, + 0x1336: 0x011d, 0x1337: 0x011f, 0x1338: 0x0121, 0x1339: 0x0123, 0x133a: 0x0125, 0x133b: 0x0127, + 0x133c: 0x0129, 0x133d: 0x012b, 0x133e: 0x012d, 0x133f: 0x012f, + // Block 0x4d, offset 0x1340 + 0x1340: 0x2829, 0x1341: 0x283e, 0x1342: 0x0a41, + 0x1350: 0x114d, 0x1351: 0x0f85, + 0x1352: 0x0e11, 0x1353: 0x44da, 0x1354: 0x0c59, 0x1355: 0x0f2d, 0x1356: 0x186d, 0x1357: 0x0f3d, + 0x1358: 0x0c65, 0x1359: 0x1215, 0x135a: 0x13ed, 0x135b: 0x11ed, 0x135c: 0x0d65, 0x135d: 0x10a9, + 0x135e: 0x0cfd, 0x135f: 0x11f5, 0x1360: 0x0d51, 0x1361: 0x1655, 0x1362: 0x14c1, 0x1363: 0x18c9, + 0x1364: 0x0f11, 0x1365: 0x0e49, 0x1366: 0x13a1, 0x1367: 0x1159, 0x1368: 0x1185, 0x1369: 0x0bfd, + 0x136a: 0x0c09, 0x136b: 0x1949, 0x136c: 0x1019, 0x136d: 0x0c25, 0x136e: 0x0e2d, 0x136f: 0x1179, + 0x1370: 0x18f1, 0x1371: 0x1151, 0x1372: 0x15ad, 0x1373: 0x15e9, 0x1374: 0x0e35, 0x1375: 0x1381, + 0x1376: 0x1249, 0x1377: 0x1245, 0x1378: 0x14d5, 0x1379: 0x0d69, 0x137a: 0x0e95, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0c39, 0x1381: 0x0c31, 0x1382: 0x0c41, 0x1383: 0x1f41, 0x1384: 0x0c85, 0x1385: 0x0c95, + 0x1386: 0x0c99, 0x1387: 0x0ca1, 0x1388: 0x0ca9, 0x1389: 0x0cad, 0x138a: 0x0cb9, 0x138b: 0x0cb1, + 0x138c: 0x0af1, 0x138d: 0x1f55, 0x138e: 0x0ccd, 0x138f: 0x0cd1, 0x1390: 0x0cd5, 0x1391: 0x0cf1, + 0x1392: 0x1f46, 0x1393: 0x0af5, 0x1394: 0x0cdd, 0x1395: 0x0cfd, 0x1396: 0x1f50, 0x1397: 0x0d0d, + 0x1398: 0x0d15, 0x1399: 0x0c75, 0x139a: 0x0d1d, 0x139b: 0x0d21, 0x139c: 0x212b, 0x139d: 0x0d3d, + 0x139e: 0x0d45, 0x139f: 0x0afd, 0x13a0: 0x0d5d, 0x13a1: 0x0d61, 0x13a2: 0x0d69, 0x13a3: 0x0d6d, + 0x13a4: 0x0b01, 0x13a5: 0x0d85, 0x13a6: 0x0d89, 0x13a7: 0x0d95, 0x13a8: 0x0da1, 0x13a9: 0x0da5, + 0x13aa: 0x0da9, 0x13ab: 0x0db1, 0x13ac: 0x0dd1, 0x13ad: 0x0dd5, 0x13ae: 0x0ddd, 0x13af: 0x0ded, + 0x13b0: 0x0df5, 0x13b1: 0x0df9, 0x13b2: 0x0df9, 0x13b3: 0x0df9, 0x13b4: 0x1f64, 0x13b5: 0x13d1, + 0x13b6: 0x0e0d, 0x13b7: 0x0e15, 0x13b8: 0x1f69, 0x13b9: 0x0e21, 0x13ba: 0x0e29, 0x13bb: 0x0e31, + 0x13bc: 0x0e59, 0x13bd: 0x0e45, 0x13be: 0x0e51, 0x13bf: 0x0e55, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0e5d, 0x13c1: 0x0e65, 0x13c2: 0x0e69, 0x13c3: 0x0e71, 0x13c4: 0x0e79, 0x13c5: 0x0e7d, + 0x13c6: 0x0e7d, 0x13c7: 0x0e85, 0x13c8: 0x0e8d, 0x13c9: 0x0e91, 0x13ca: 0x0e9d, 0x13cb: 0x0ec1, + 0x13cc: 0x0ea5, 0x13cd: 0x0ec5, 0x13ce: 0x0ea9, 0x13cf: 0x0eb1, 0x13d0: 0x0d49, 0x13d1: 0x0f0d, + 0x13d2: 0x0ed5, 0x13d3: 0x0ed9, 0x13d4: 0x0edd, 0x13d5: 0x0ed1, 0x13d6: 0x0ee5, 0x13d7: 0x0ee1, + 0x13d8: 0x0ef9, 0x13d9: 0x1f6e, 0x13da: 0x0f15, 0x13db: 0x0f19, 0x13dc: 0x0f21, 0x13dd: 0x0f2d, + 0x13de: 0x0f35, 0x13df: 0x0f51, 0x13e0: 0x1f73, 0x13e1: 0x1f78, 0x13e2: 0x0f5d, 0x13e3: 0x0f61, + 0x13e4: 0x0f65, 0x13e5: 0x0f59, 0x13e6: 0x0f6d, 0x13e7: 0x0b05, 0x13e8: 0x0b09, 0x13e9: 0x0f75, + 0x13ea: 0x0f7d, 0x13eb: 0x0f7d, 0x13ec: 0x1f7d, 0x13ed: 0x0f99, 0x13ee: 0x0f9d, 0x13ef: 0x0fa1, + 0x13f0: 0x0fa9, 0x13f1: 0x1f82, 0x13f2: 0x0fb1, 0x13f3: 0x0fb5, 0x13f4: 0x108d, 0x13f5: 0x0fbd, + 0x13f6: 0x0b0d, 0x13f7: 0x0fc9, 0x13f8: 0x0fd9, 0x13f9: 0x0fe5, 0x13fa: 0x0fe1, 0x13fb: 0x1f8c, + 0x13fc: 0x0fed, 0x13fd: 0x1f91, 0x13fe: 0x0ff9, 0x13ff: 0x0ff5, + // Block 0x50, offset 0x1400 + 0x1400: 0x0ffd, 0x1401: 0x100d, 0x1402: 0x1011, 0x1403: 0x0b11, 0x1404: 0x1021, 0x1405: 0x1029, + 0x1406: 0x102d, 0x1407: 0x1031, 0x1408: 0x0b15, 0x1409: 0x1f96, 0x140a: 0x0b19, 0x140b: 0x104d, + 0x140c: 0x1051, 0x140d: 0x1055, 0x140e: 0x105d, 0x140f: 0x215d, 0x1410: 0x1075, 0x1411: 0x1fa0, + 0x1412: 0x1fa0, 0x1413: 0x1715, 0x1414: 0x1085, 0x1415: 0x1085, 0x1416: 0x0b1d, 0x1417: 0x1fc3, + 0x1418: 0x2095, 0x1419: 0x1095, 0x141a: 0x109d, 0x141b: 0x0b21, 0x141c: 0x10b1, 0x141d: 0x10c1, + 0x141e: 0x10c5, 0x141f: 0x10cd, 0x1420: 0x10dd, 0x1421: 0x0b29, 0x1422: 0x0b25, 0x1423: 0x10e1, + 0x1424: 0x1fa5, 0x1425: 0x10e5, 0x1426: 0x10f9, 0x1427: 0x10fd, 0x1428: 0x1101, 0x1429: 0x10fd, + 0x142a: 0x110d, 0x142b: 0x1111, 0x142c: 0x1121, 0x142d: 0x1119, 0x142e: 0x111d, 0x142f: 0x1125, + 0x1430: 0x1129, 0x1431: 0x112d, 0x1432: 0x1139, 0x1433: 0x113d, 0x1434: 0x1155, 0x1435: 0x115d, + 0x1436: 0x116d, 0x1437: 0x1181, 0x1438: 0x1fb4, 0x1439: 0x117d, 0x143a: 0x1171, 0x143b: 0x1189, + 0x143c: 0x1191, 0x143d: 0x11a5, 0x143e: 0x1fb9, 0x143f: 0x11ad, + // Block 0x51, offset 0x1440 + 0x1440: 0x11a1, 0x1441: 0x1199, 0x1442: 0x0b2d, 0x1443: 0x11b5, 0x1444: 0x11bd, 0x1445: 0x11c5, + 0x1446: 0x11b9, 0x1447: 0x0b31, 0x1448: 0x11d5, 0x1449: 0x11dd, 0x144a: 0x1fbe, 0x144b: 0x1209, + 0x144c: 0x123d, 0x144d: 0x1219, 0x144e: 0x0b3d, 0x144f: 0x1225, 0x1450: 0x0b39, 0x1451: 0x0b35, + 0x1452: 0x0d01, 0x1453: 0x0d05, 0x1454: 0x1241, 0x1455: 0x1229, 0x1456: 0x16e9, 0x1457: 0x0ba1, + 0x1458: 0x124d, 0x1459: 0x1251, 0x145a: 0x1255, 0x145b: 0x1269, 0x145c: 0x1261, 0x145d: 0x1fd7, + 0x145e: 0x0b41, 0x145f: 0x127d, 0x1460: 0x1271, 0x1461: 0x128d, 0x1462: 0x1295, 0x1463: 0x1fe1, + 0x1464: 0x1299, 0x1465: 0x1285, 0x1466: 0x12a1, 0x1467: 0x0b45, 0x1468: 0x12a5, 0x1469: 0x12a9, + 0x146a: 0x12ad, 0x146b: 0x12b9, 0x146c: 0x1fe6, 0x146d: 0x12c1, 0x146e: 0x0b49, 0x146f: 0x12cd, + 0x1470: 0x1feb, 0x1471: 0x12d1, 0x1472: 0x0b4d, 0x1473: 0x12dd, 0x1474: 0x12e9, 0x1475: 0x12f5, + 0x1476: 0x12f9, 0x1477: 0x1ff0, 0x1478: 0x1f87, 0x1479: 0x1ff5, 0x147a: 0x1319, 0x147b: 0x1ffa, + 0x147c: 0x1325, 0x147d: 0x132d, 0x147e: 0x131d, 0x147f: 0x1339, + // Block 0x52, offset 0x1480 + 0x1480: 0x1349, 0x1481: 0x1359, 0x1482: 0x134d, 0x1483: 0x1351, 0x1484: 0x135d, 0x1485: 0x1361, + 0x1486: 0x1fff, 0x1487: 0x1345, 0x1488: 0x1379, 0x1489: 0x137d, 0x148a: 0x0b51, 0x148b: 0x1391, + 0x148c: 0x138d, 0x148d: 0x2004, 0x148e: 0x1371, 0x148f: 0x13ad, 0x1490: 0x2009, 0x1491: 0x200e, + 0x1492: 0x13b1, 0x1493: 0x13c5, 0x1494: 0x13c1, 0x1495: 0x13bd, 0x1496: 0x0b55, 0x1497: 0x13c9, + 0x1498: 0x13d9, 0x1499: 0x13d5, 0x149a: 0x13e1, 0x149b: 0x1f4b, 0x149c: 0x13f1, 0x149d: 0x2013, + 0x149e: 0x13fd, 0x149f: 0x201d, 0x14a0: 0x1411, 0x14a1: 0x141d, 0x14a2: 0x1431, 0x14a3: 0x2022, + 0x14a4: 0x1445, 0x14a5: 0x1449, 0x14a6: 0x2027, 0x14a7: 0x202c, 0x14a8: 0x1465, 0x14a9: 0x1475, + 0x14aa: 0x0b59, 0x14ab: 0x1479, 0x14ac: 0x0b5d, 0x14ad: 0x0b5d, 0x14ae: 0x1491, 0x14af: 0x1495, + 0x14b0: 0x149d, 0x14b1: 0x14a1, 0x14b2: 0x14ad, 0x14b3: 0x0b61, 0x14b4: 0x14c5, 0x14b5: 0x2031, + 0x14b6: 0x14e1, 0x14b7: 0x2036, 0x14b8: 0x14ed, 0x14b9: 0x1f9b, 0x14ba: 0x14fd, 0x14bb: 0x203b, + 0x14bc: 0x2040, 0x14bd: 0x2045, 0x14be: 0x0b65, 0x14bf: 0x0b69, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x1535, 0x14c1: 0x204f, 0x14c2: 0x204a, 0x14c3: 0x2054, 0x14c4: 0x2059, 0x14c5: 0x153d, + 0x14c6: 0x1541, 0x14c7: 0x1541, 0x14c8: 0x1549, 0x14c9: 0x0b71, 0x14ca: 0x154d, 0x14cb: 0x0b75, + 0x14cc: 0x0b79, 0x14cd: 0x2063, 0x14ce: 0x1561, 0x14cf: 0x1569, 0x14d0: 0x1575, 0x14d1: 0x0b7d, + 0x14d2: 0x2068, 0x14d3: 0x1599, 0x14d4: 0x206d, 0x14d5: 0x2072, 0x14d6: 0x15b9, 0x14d7: 0x15d1, + 0x14d8: 0x0b81, 0x14d9: 0x15d9, 0x14da: 0x15dd, 0x14db: 0x15e1, 0x14dc: 0x2077, 0x14dd: 0x207c, + 0x14de: 0x207c, 0x14df: 0x15f9, 0x14e0: 0x0b85, 0x14e1: 0x2081, 0x14e2: 0x160d, 0x14e3: 0x1611, + 0x14e4: 0x0b89, 0x14e5: 0x2086, 0x14e6: 0x162d, 0x14e7: 0x0b8d, 0x14e8: 0x163d, 0x14e9: 0x1635, + 0x14ea: 0x1645, 0x14eb: 0x2090, 0x14ec: 0x165d, 0x14ed: 0x0b91, 0x14ee: 0x1669, 0x14ef: 0x1671, + 0x14f0: 0x1681, 0x14f1: 0x0b95, 0x14f2: 0x209a, 0x14f3: 0x209f, 0x14f4: 0x0b99, 0x14f5: 0x20a4, + 0x14f6: 0x1699, 0x14f7: 0x20a9, 0x14f8: 0x16a5, 0x14f9: 0x16b1, 0x14fa: 0x16b9, 0x14fb: 0x20ae, + 0x14fc: 0x20b3, 0x14fd: 0x16cd, 0x14fe: 0x20b8, 0x14ff: 0x16d5, + // Block 0x54, offset 0x1500 + 0x1500: 0x1fc8, 0x1501: 0x0b9d, 0x1502: 0x16ed, 0x1503: 0x16f1, 0x1504: 0x0ba5, 0x1505: 0x16f5, + 0x1506: 0x0f71, 0x1507: 0x20bd, 0x1508: 0x20c2, 0x1509: 0x1fcd, 0x150a: 0x1fd2, 0x150b: 0x1715, + 0x150c: 0x1719, 0x150d: 0x1931, 0x150e: 0x0ba9, 0x150f: 0x1745, 0x1510: 0x1741, 0x1511: 0x1749, + 0x1512: 0x0d7d, 0x1513: 0x174d, 0x1514: 0x1751, 0x1515: 0x1755, 0x1516: 0x175d, 0x1517: 0x20c7, + 0x1518: 0x1759, 0x1519: 0x1761, 0x151a: 0x1775, 0x151b: 0x1779, 0x151c: 0x1765, 0x151d: 0x177d, + 0x151e: 0x1791, 0x151f: 0x17a5, 0x1520: 0x1771, 0x1521: 0x1785, 0x1522: 0x1789, 0x1523: 0x178d, + 0x1524: 0x20cc, 0x1525: 0x20d6, 0x1526: 0x20d1, 0x1527: 0x0bad, 0x1528: 0x17ad, 0x1529: 0x17b1, + 0x152a: 0x17b9, 0x152b: 0x20ea, 0x152c: 0x17bd, 0x152d: 0x20db, 0x152e: 0x0bb1, 0x152f: 0x0bb5, + 0x1530: 0x20e0, 0x1531: 0x20e5, 0x1532: 0x0bb9, 0x1533: 0x17dd, 0x1534: 0x17e1, 0x1535: 0x17e5, + 0x1536: 0x17e9, 0x1537: 0x17f5, 0x1538: 0x17f1, 0x1539: 0x17fd, 0x153a: 0x17f9, 0x153b: 0x1809, + 0x153c: 0x1801, 0x153d: 0x1805, 0x153e: 0x180d, 0x153f: 0x0bbd, + // Block 0x55, offset 0x1540 + 0x1540: 0x1815, 0x1541: 0x1819, 0x1542: 0x0bc1, 0x1543: 0x1829, 0x1544: 0x182d, 0x1545: 0x20ef, + 0x1546: 0x1839, 0x1547: 0x183d, 0x1548: 0x0bc5, 0x1549: 0x1849, 0x154a: 0x0af9, 0x154b: 0x20f4, + 0x154c: 0x20f9, 0x154d: 0x0bc9, 0x154e: 0x0bcd, 0x154f: 0x1875, 0x1550: 0x188d, 0x1551: 0x18a9, + 0x1552: 0x18b9, 0x1553: 0x20fe, 0x1554: 0x18cd, 0x1555: 0x18d1, 0x1556: 0x18e9, 0x1557: 0x18f5, + 0x1558: 0x2108, 0x1559: 0x1f5a, 0x155a: 0x1901, 0x155b: 0x18fd, 0x155c: 0x1909, 0x155d: 0x1f5f, + 0x155e: 0x1915, 0x155f: 0x1921, 0x1560: 0x210d, 0x1561: 0x2112, 0x1562: 0x1961, 0x1563: 0x1969, + 0x1564: 0x1971, 0x1565: 0x2117, 0x1566: 0x1975, 0x1567: 0x199d, 0x1568: 0x19a9, 0x1569: 0x19ad, + 0x156a: 0x19a5, 0x156b: 0x19b9, 0x156c: 0x19bd, 0x156d: 0x211c, 0x156e: 0x19c9, 0x156f: 0x0bd1, + 0x1570: 0x19d1, 0x1571: 0x2121, 0x1572: 0x0bd5, 0x1573: 0x1a05, 0x1574: 0x1001, 0x1575: 0x1a1d, + 0x1576: 0x2126, 0x1577: 0x2130, 0x1578: 0x0bd9, 0x1579: 0x0bdd, 0x157a: 0x1a45, 0x157b: 0x2135, + 0x157c: 0x0be1, 0x157d: 0x213a, 0x157e: 0x1a5d, 0x157f: 0x1a5d, + // Block 0x56, offset 0x1580 + 0x1580: 0x1a65, 0x1581: 0x213f, 0x1582: 0x1a7d, 0x1583: 0x0be5, 0x1584: 0x1a8d, 0x1585: 0x1a99, + 0x1586: 0x1aa1, 0x1587: 0x1aa9, 0x1588: 0x0be9, 0x1589: 0x2144, 0x158a: 0x1abd, 0x158b: 0x1ad9, + 0x158c: 0x1ae5, 0x158d: 0x0bed, 0x158e: 0x0bf1, 0x158f: 0x1ae9, 0x1590: 0x2149, 0x1591: 0x0bf5, + 0x1592: 0x214e, 0x1593: 0x2153, 0x1594: 0x2158, 0x1595: 0x1b0d, 0x1596: 0x0bf9, 0x1597: 0x1b21, + 0x1598: 0x1b29, 0x1599: 0x1b2d, 0x159a: 0x1b35, 0x159b: 0x1b3d, 0x159c: 0x1b45, 0x159d: 0x2162, } -// nfkcDecompSparseOffset: 93 entries, 186 bytes -var nfkcDecompSparseOffset = []uint16{0x0, 0xc, 0x16, 0x1e, 0x24, 0x27, 0x31, 0x37, 0x3e, 0x44, 0x4c, 0x59, 0x60, 0x66, 0x6e, 0x70, 0x72, 0x74, 0x78, 0x7c, 0x7e, 0x82, 0x85, 0x88, 0x8c, 0x8e, 0x90, 0x92, 0x96, 0x98, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xae, 0xb6, 0xb8, 0xba, 0xc3, 0xc6, 0xcd, 0xd8, 0xe6, 0xf4, 0xfe, 0x102, 0x104, 0x10c, 0x118, 0x11d, 0x120, 0x122, 0x124, 0x127, 0x129, 0x12b, 0x12d, 0x12f, 0x131, 0x133, 0x135, 0x137, 0x139, 0x13e, 0x14d, 0x15b, 0x15d, 0x15f, 0x167, 0x177, 0x179, 0x184, 0x18b, 0x196, 0x1a2, 0x1b3, 0x1c4, 0x1cb, 0x1dc, 0x1ea, 0x1f8, 0x207, 0x218, 0x21d, 0x22a, 0x22e, 0x232, 0x236, 0x238, 0x247, 0x249, 0x24d} +// nfkcSparseOffset: 123 entries, 246 bytes +var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x6f, 0x74, 0x76, 0x7e, 0x85, 0x88, 0x90, 0x94, 0x98, 0x9a, 0x9c, 0xa5, 0xa9, 0xb0, 0xb5, 0xb8, 0xc2, 0xc4, 0xcb, 0xd3, 0xd7, 0xd9, 0xdc, 0xe0, 0xe6, 0xf7, 0x103, 0x105, 0x10b, 0x10d, 0x10f, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11c, 0x11f, 0x121, 0x124, 0x127, 0x12b, 0x134, 0x136, 0x139, 0x13b, 0x144, 0x14f, 0x15e, 0x16c, 0x17a, 0x18a, 0x198, 0x19f, 0x1a5, 0x1b4, 0x1b8, 0x1ba, 0x1be, 0x1c0, 0x1c3, 0x1c5, 0x1c8, 0x1ca, 0x1cd, 0x1cf, 0x1d1, 0x1d3, 0x1df, 0x1e8, 0x1ef, 0x1fc, 0x1ff, 0x201, 0x203, 0x205, 0x208, 0x20a, 0x20c, 0x20e, 0x210, 0x216, 0x218, 0x21a, 0x21c, 0x21e, 0x220, 0x22f, 0x231, 0x237, 0x23f, 0x24c, 0x256, 0x258, 0x25a, 0x25e, 0x263, 0x26f, 0x274, 0x27d, 0x283, 0x288, 0x28c, 0x291, 0x295, 0x2a5, 0x2b3, 0x2c1, 0x2cf, 0x2d7, 0x2d9} -// nfkcDecompSparseValues: 603 entries, 2412 bytes -var nfkcDecompSparseValues = [603]valueRange{ +// nfkcSparseValues: 739 entries, 2956 bytes +var nfkcSparseValues = [739]valueRange{ // Block 0x0, offset 0x1 - {value: 0x0002, lo: 0x0b}, - {value: 0x0001, lo: 0xa0, hi: 0xa0}, - {value: 0x0003, lo: 0xa8, hi: 0xa8}, - {value: 0x0007, lo: 0xaa, hi: 0xaa}, - {value: 0x0009, lo: 0xaf, hi: 0xaf}, - {value: 0x000d, lo: 0xb2, hi: 0xb4}, - {value: 0x0015, lo: 0xb5, hi: 0xb5}, - {value: 0x0018, lo: 0xb8, hi: 0xb8}, - {value: 0x001c, lo: 0xb9, hi: 0xba}, - {value: 0x0020, lo: 0xbc, hi: 0xbc}, - {value: 0x0026, lo: 0xbd, hi: 0xbd}, - {value: 0x002c, lo: 0xbe, hi: 0xbe}, + {value: 0x0002, lo: 0x0d}, + {value: 0x00cf, lo: 0xa0, hi: 0xa0}, + {value: 0x4164, lo: 0xa8, hi: 0xa8}, + {value: 0x0151, lo: 0xaa, hi: 0xaa}, + {value: 0x4150, lo: 0xaf, hi: 0xaf}, + {value: 0x00f3, lo: 0xb2, hi: 0xb3}, + {value: 0x4146, lo: 0xb4, hi: 0xb4}, + {value: 0x0499, lo: 0xb5, hi: 0xb5}, + {value: 0x417d, lo: 0xb8, hi: 0xb8}, + {value: 0x00f1, lo: 0xb9, hi: 0xb9}, + {value: 0x016d, lo: 0xba, hi: 0xba}, + {value: 0x232f, lo: 0xbc, hi: 0xbc}, + {value: 0x2323, lo: 0xbd, hi: 0xbd}, + {value: 0x23c5, lo: 0xbe, hi: 0xbe}, // Block 0x1, offset 0x2 - {value: 0x0004, lo: 0x09}, - {value: 0x0032, lo: 0x80, hi: 0x85}, - {value: 0x004a, lo: 0x87, hi: 0x8f}, - {value: 0x006e, lo: 0x91, hi: 0x96}, - {value: 0x0086, lo: 0x99, hi: 0x9d}, - {value: 0x009a, lo: 0xa0, hi: 0xa5}, - {value: 0x00b2, lo: 0xa7, hi: 0xaf}, - {value: 0x00d6, lo: 0xb1, hi: 0xb6}, - {value: 0x00ee, lo: 0xb9, hi: 0xbd}, - {value: 0x0102, lo: 0xbf, hi: 0xbf}, + {value: 0x0091, lo: 0x03}, + {value: 0x4699, lo: 0xa0, hi: 0xa1}, + {value: 0x46cb, lo: 0xaf, hi: 0xb0}, + {value: 0x8800, lo: 0xb7, hi: 0xb7}, // Block 0x2, offset 0x3 - {value: 0x0004, lo: 0x07}, - {value: 0x0106, lo: 0x80, hi: 0x8f}, - {value: 0x0146, lo: 0x92, hi: 0xa5}, - {value: 0x0196, lo: 0xa8, hi: 0xb0}, - {value: 0x01ba, lo: 0xb2, hi: 0xb2}, - {value: 0x01bd, lo: 0xb3, hi: 0xb3}, - {value: 0x01c0, lo: 0xb4, hi: 0xb7}, - {value: 0x01d0, lo: 0xb9, hi: 0xbf}, + {value: 0x0003, lo: 0x08}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x015f, lo: 0xb0, hi: 0xb0}, + {value: 0x03d9, lo: 0xb1, hi: 0xb1}, + {value: 0x0163, lo: 0xb2, hi: 0xb2}, + {value: 0x0173, lo: 0xb3, hi: 0xb3}, + {value: 0x0400, lo: 0xb4, hi: 0xb6}, + {value: 0x017d, lo: 0xb7, hi: 0xb7}, + {value: 0x0181, lo: 0xb8, hi: 0xb8}, // Block 0x3, offset 0x4 - {value: 0x0004, lo: 0x05}, - {value: 0x01ec, lo: 0x80, hi: 0x80}, - {value: 0x01f0, lo: 0x83, hi: 0x89}, - {value: 0x020c, lo: 0x8c, hi: 0x91}, - {value: 0x0224, lo: 0x94, hi: 0xa5}, - {value: 0x026c, lo: 0xa8, hi: 0xbf}, + {value: 0x000a, lo: 0x09}, + {value: 0x415a, lo: 0x98, hi: 0x98}, + {value: 0x415f, lo: 0x99, hi: 0x9a}, + {value: 0x4182, lo: 0x9b, hi: 0x9b}, + {value: 0x414b, lo: 0x9c, hi: 0x9c}, + {value: 0x416e, lo: 0x9d, hi: 0x9d}, + {value: 0x03d3, lo: 0xa0, hi: 0xa0}, + {value: 0x0167, lo: 0xa1, hi: 0xa1}, + {value: 0x0175, lo: 0xa2, hi: 0xa3}, + {value: 0x0424, lo: 0xa4, hi: 0xa4}, // Block 0x4, offset 0x5 - {value: 0x0004, lo: 0x02}, - {value: 0x02ca, lo: 0xa0, hi: 0xa1}, - {value: 0x02d2, lo: 0xaf, hi: 0xb0}, + {value: 0x0000, lo: 0x0f}, + {value: 0x8800, lo: 0x83, hi: 0x83}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x8800, lo: 0x8b, hi: 0x8b}, + {value: 0x8800, lo: 0x8d, hi: 0x8d}, + {value: 0x368a, lo: 0x90, hi: 0x90}, + {value: 0x3696, lo: 0x91, hi: 0x91}, + {value: 0x3684, lo: 0x93, hi: 0x93}, + {value: 0x8800, lo: 0x96, hi: 0x96}, + {value: 0x36fc, lo: 0x97, hi: 0x97}, + {value: 0x36c6, lo: 0x9c, hi: 0x9c}, + {value: 0x36ae, lo: 0x9d, hi: 0x9d}, + {value: 0x36d8, lo: 0x9e, hi: 0x9e}, + {value: 0x8800, lo: 0xb4, hi: 0xb5}, + {value: 0x3702, lo: 0xb6, hi: 0xb6}, + {value: 0x3708, lo: 0xb7, hi: 0xb7}, // Block 0x5, offset 0x6 - {value: 0x0004, lo: 0x09}, - {value: 0x03d8, lo: 0x80, hi: 0x9b}, - {value: 0x0448, lo: 0x9e, hi: 0x9f}, - {value: 0x0450, lo: 0xa6, hi: 0xaa}, - {value: 0x0466, lo: 0xab, hi: 0xab}, - {value: 0x046c, lo: 0xac, hi: 0xac}, - {value: 0x0472, lo: 0xad, hi: 0xad}, - {value: 0x0478, lo: 0xae, hi: 0xb0}, - {value: 0x0486, lo: 0xb1, hi: 0xb1}, - {value: 0x048c, lo: 0xb2, hi: 0xb3}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x83, hi: 0x87}, // Block 0x6, offset 0x7 - {value: 0x0002, lo: 0x05}, - {value: 0x0494, lo: 0xb0, hi: 0xb1}, - {value: 0x0499, lo: 0xb2, hi: 0xb4}, - {value: 0x04a0, lo: 0xb5, hi: 0xb5}, - {value: 0x04a3, lo: 0xb6, hi: 0xb6}, - {value: 0x04a6, lo: 0xb7, hi: 0xb8}, + {value: 0x0001, lo: 0x04}, + {value: 0x8018, lo: 0x81, hi: 0x82}, + {value: 0x80e6, lo: 0x84, hi: 0x84}, + {value: 0x80dc, lo: 0x85, hi: 0x85}, + {value: 0x8012, lo: 0x87, hi: 0x87}, // Block 0x7, offset 0x8 - {value: 0x0004, lo: 0x06}, - {value: 0x04aa, lo: 0x98, hi: 0x9d}, - {value: 0x04c2, lo: 0xa0, hi: 0xa0}, - {value: 0x04c5, lo: 0xa1, hi: 0xa1}, - {value: 0x02c8, lo: 0xa2, hi: 0xa2}, - {value: 0x04c7, lo: 0xa3, hi: 0xa3}, - {value: 0x04c9, lo: 0xa4, hi: 0xa4}, + {value: 0x0000, lo: 0x0a}, + {value: 0x80e6, lo: 0x90, hi: 0x97}, + {value: 0x801e, lo: 0x98, hi: 0x98}, + {value: 0x801f, lo: 0x99, hi: 0x99}, + {value: 0x8020, lo: 0x9a, hi: 0x9a}, + {value: 0x3726, lo: 0xa2, hi: 0xa2}, + {value: 0x372c, lo: 0xa3, hi: 0xa3}, + {value: 0x3738, lo: 0xa4, hi: 0xa4}, + {value: 0x3732, lo: 0xa5, hi: 0xa5}, + {value: 0x373e, lo: 0xa6, hi: 0xa6}, + {value: 0x8800, lo: 0xa7, hi: 0xa7}, // Block 0x8, offset 0x9 - {value: 0x0003, lo: 0x05}, - {value: 0x04cc, lo: 0x80, hi: 0x81}, - {value: 0x04d2, lo: 0x83, hi: 0x84}, - {value: 0x04da, lo: 0xb4, hi: 0xb4}, - {value: 0x04dd, lo: 0xba, hi: 0xba}, - {value: 0x04e1, lo: 0xbe, hi: 0xbe}, + {value: 0x0000, lo: 0x0e}, + {value: 0x3750, lo: 0x80, hi: 0x80}, + {value: 0x8800, lo: 0x81, hi: 0x81}, + {value: 0x3744, lo: 0x82, hi: 0x82}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x374a, lo: 0x93, hi: 0x93}, + {value: 0x8800, lo: 0x95, hi: 0x95}, + {value: 0x80e6, lo: 0x96, hi: 0x9c}, + {value: 0x80e6, lo: 0x9f, hi: 0xa2}, + {value: 0x80dc, lo: 0xa3, hi: 0xa3}, + {value: 0x80e6, lo: 0xa4, hi: 0xa4}, + {value: 0x80e6, lo: 0xa7, hi: 0xa8}, + {value: 0x80dc, lo: 0xaa, hi: 0xaa}, + {value: 0x80e6, lo: 0xab, hi: 0xac}, + {value: 0x80dc, lo: 0xad, hi: 0xad}, // Block 0x9, offset 0xa - {value: 0x0005, lo: 0x07}, - {value: 0x0011, lo: 0x84, hi: 0x84}, - {value: 0x04e8, lo: 0x85, hi: 0x85}, - {value: 0x04ee, lo: 0x86, hi: 0x87}, - {value: 0x04f6, lo: 0x88, hi: 0x8a}, - {value: 0x0505, lo: 0x8c, hi: 0x8c}, - {value: 0x050a, lo: 0x8e, hi: 0x90}, - {value: 0x051b, lo: 0xaa, hi: 0xb0}, + {value: 0x0000, lo: 0x0c}, + {value: 0x8024, lo: 0x91, hi: 0x91}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, + {value: 0x80dc, lo: 0xb1, hi: 0xb1}, + {value: 0x80e6, lo: 0xb2, hi: 0xb3}, + {value: 0x80dc, lo: 0xb4, hi: 0xb4}, + {value: 0x80e6, lo: 0xb5, hi: 0xb6}, + {value: 0x80dc, lo: 0xb7, hi: 0xb9}, + {value: 0x80e6, lo: 0xba, hi: 0xba}, + {value: 0x80dc, lo: 0xbb, hi: 0xbc}, + {value: 0x80e6, lo: 0xbd, hi: 0xbd}, + {value: 0x80dc, lo: 0xbe, hi: 0xbe}, + {value: 0x80e6, lo: 0xbf, hi: 0xbf}, // Block 0xa, offset 0xb - {value: 0x0003, lo: 0x0c}, - {value: 0x0540, lo: 0x8a, hi: 0x8a}, - {value: 0x0545, lo: 0x8b, hi: 0x8b}, - {value: 0x054a, lo: 0x8c, hi: 0x8c}, - {value: 0x054f, lo: 0x8d, hi: 0x8d}, - {value: 0x0554, lo: 0x8e, hi: 0x8e}, - {value: 0x0559, lo: 0x90, hi: 0x92}, - {value: 0x050a, lo: 0x93, hi: 0x93}, - {value: 0x0520, lo: 0x94, hi: 0x94}, - {value: 0x056c, lo: 0x95, hi: 0x96}, - {value: 0x0572, lo: 0xb0, hi: 0xb2}, - {value: 0x057b, lo: 0xb4, hi: 0xb5}, - {value: 0x0581, lo: 0xb9, hi: 0xb9}, + {value: 0x000a, lo: 0x07}, + {value: 0x80e6, lo: 0x80, hi: 0x80}, + {value: 0x80e6, lo: 0x81, hi: 0x81}, + {value: 0x80dc, lo: 0x82, hi: 0x83}, + {value: 0x80dc, lo: 0x84, hi: 0x85}, + {value: 0x80dc, lo: 0x86, hi: 0x87}, + {value: 0x80dc, lo: 0x88, hi: 0x89}, + {value: 0x80e6, lo: 0x8a, hi: 0x8a}, // Block 0xb, offset 0xc - {value: 0x0005, lo: 0x06}, - {value: 0x0584, lo: 0x80, hi: 0x81}, - {value: 0x058e, lo: 0x83, hi: 0x83}, - {value: 0x0593, lo: 0x87, hi: 0x87}, - {value: 0x0598, lo: 0x8c, hi: 0x8e}, - {value: 0x05a7, lo: 0x99, hi: 0x99}, - {value: 0x05ac, lo: 0xb9, hi: 0xb9}, + {value: 0x0000, lo: 0x03}, + {value: 0x80e6, lo: 0xab, hi: 0xb1}, + {value: 0x80dc, lo: 0xb2, hi: 0xb2}, + {value: 0x80e6, lo: 0xb3, hi: 0xb3}, // Block 0xc, offset 0xd - {value: 0x0005, lo: 0x05}, - {value: 0x05b1, lo: 0x90, hi: 0x91}, - {value: 0x05bb, lo: 0x93, hi: 0x93}, - {value: 0x05c0, lo: 0x97, hi: 0x97}, - {value: 0x05c5, lo: 0x9c, hi: 0x9e}, - {value: 0x05d4, lo: 0xb6, hi: 0xb7}, + {value: 0x0000, lo: 0x04}, + {value: 0x80e6, lo: 0x96, hi: 0x99}, + {value: 0x80e6, lo: 0x9b, hi: 0xa3}, + {value: 0x80e6, lo: 0xa5, hi: 0xa7}, + {value: 0x80e6, lo: 0xa9, hi: 0xad}, // Block 0xd, offset 0xe - {value: 0x0005, lo: 0x07}, - {value: 0x05de, lo: 0x81, hi: 0x82}, - {value: 0x05e8, lo: 0x90, hi: 0x93}, - {value: 0x05fc, lo: 0x96, hi: 0x97}, - {value: 0x0606, lo: 0x9a, hi: 0x9f}, - {value: 0x0624, lo: 0xa2, hi: 0xa7}, - {value: 0x0642, lo: 0xaa, hi: 0xb5}, - {value: 0x067e, lo: 0xb8, hi: 0xb9}, - // Block 0xe, offset 0xf {value: 0x0000, lo: 0x01}, - {value: 0x0688, lo: 0x87, hi: 0x87}, + {value: 0x80dc, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0xf + {value: 0x0000, lo: 0x07}, + {value: 0x8800, lo: 0xa8, hi: 0xa8}, + {value: 0x3dbd, lo: 0xa9, hi: 0xa9}, + {value: 0x8800, lo: 0xb0, hi: 0xb0}, + {value: 0x3dc5, lo: 0xb1, hi: 0xb1}, + {value: 0x8800, lo: 0xb3, hi: 0xb3}, + {value: 0x3dcd, lo: 0xb4, hi: 0xb4}, + {value: 0x8607, lo: 0xbc, hi: 0xbc}, // Block 0xf, offset 0x10 - {value: 0x0005, lo: 0x01}, - {value: 0x068d, lo: 0xa2, hi: 0xa6}, + {value: 0x0008, lo: 0x06}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x80e6, lo: 0x91, hi: 0x91}, + {value: 0x80dc, lo: 0x92, hi: 0x92}, + {value: 0x80e6, lo: 0x93, hi: 0x93}, + {value: 0x80e6, lo: 0x94, hi: 0x94}, + {value: 0x4432, lo: 0x98, hi: 0x9f}, // Block 0x10, offset 0x11 - {value: 0x0005, lo: 0x01}, - {value: 0x06a6, lo: 0xb5, hi: 0xb8}, + {value: 0x0000, lo: 0x02}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x11, offset 0x12 - {value: 0x0000, lo: 0x03}, - {value: 0x06ba, lo: 0x80, hi: 0x80}, - {value: 0x06bf, lo: 0x82, hi: 0x82}, - {value: 0x06c4, lo: 0x93, hi: 0x93}, + {value: 0x0007, lo: 0x07}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x0001, lo: 0x8b, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, + {value: 0x4472, lo: 0x9c, hi: 0x9c}, + {value: 0x447a, lo: 0x9d, hi: 0x9d}, + {value: 0x4482, lo: 0x9f, hi: 0x9f}, // Block 0x12, offset 0x13 {value: 0x0000, lo: 0x03}, - {value: 0x06c9, lo: 0xa9, hi: 0xa9}, - {value: 0x06d0, lo: 0xb1, hi: 0xb1}, - {value: 0x06d7, lo: 0xb4, hi: 0xb4}, + {value: 0x44aa, lo: 0xb3, hi: 0xb3}, + {value: 0x44b2, lo: 0xb6, hi: 0xb6}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, // Block 0x13, offset 0x14 - {value: 0x0007, lo: 0x01}, - {value: 0x06de, lo: 0x98, hi: 0x9f}, + {value: 0x0008, lo: 0x03}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x448a, lo: 0x99, hi: 0x9b}, + {value: 0x44a2, lo: 0x9e, hi: 0x9e}, // Block 0x14, offset 0x15 - {value: 0x0007, lo: 0x03}, - {value: 0x0716, lo: 0x8b, hi: 0x8c}, - {value: 0x0724, lo: 0x9c, hi: 0x9d}, - {value: 0x0732, lo: 0x9f, hi: 0x9f}, + {value: 0x0000, lo: 0x01}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, // Block 0x15, offset 0x16 - {value: 0x0000, lo: 0x02}, - {value: 0x0739, lo: 0xb3, hi: 0xb3}, - {value: 0x0740, lo: 0xb6, hi: 0xb6}, + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, // Block 0x16, offset 0x17 - {value: 0x0007, lo: 0x02}, - {value: 0x0747, lo: 0x99, hi: 0x9b}, - {value: 0x075c, lo: 0x9e, hi: 0x9e}, + {value: 0x0000, lo: 0x08}, + {value: 0x8800, lo: 0x87, hi: 0x87}, + {value: 0x0016, lo: 0x88, hi: 0x88}, + {value: 0x000f, lo: 0x8b, hi: 0x8b}, + {value: 0x001d, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x96, hi: 0x97}, + {value: 0x44ba, lo: 0x9c, hi: 0x9c}, + {value: 0x44c2, lo: 0x9d, hi: 0x9d}, // Block 0x17, offset 0x18 - {value: 0x0007, lo: 0x03}, - {value: 0x0763, lo: 0x88, hi: 0x88}, - {value: 0x076a, lo: 0x8b, hi: 0x8c}, - {value: 0x0778, lo: 0x9c, hi: 0x9d}, + {value: 0x0000, lo: 0x03}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x0024, lo: 0x94, hi: 0x94}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x18, offset 0x19 - {value: 0x0000, lo: 0x01}, - {value: 0x0786, lo: 0x94, hi: 0x94}, + {value: 0x0000, lo: 0x06}, + {value: 0x8800, lo: 0x86, hi: 0x87}, + {value: 0x002b, lo: 0x8a, hi: 0x8a}, + {value: 0x0039, lo: 0x8b, hi: 0x8b}, + {value: 0x0032, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, // Block 0x19, offset 0x1a - {value: 0x0007, lo: 0x01}, - {value: 0x078d, lo: 0x8a, hi: 0x8c}, + {value: 0x0607, lo: 0x04}, + {value: 0x8800, lo: 0x86, hi: 0x86}, + {value: 0x3dd5, lo: 0x88, hi: 0x88}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8054, lo: 0x95, hi: 0x96}, // Block 0x1a, offset 0x1b - {value: 0x0000, lo: 0x01}, - {value: 0x07a2, lo: 0x88, hi: 0x88}, + {value: 0x0000, lo: 0x02}, + {value: 0x8007, lo: 0xbc, hi: 0xbc}, + {value: 0x8800, lo: 0xbf, hi: 0xbf}, // Block 0x1b, offset 0x1c - {value: 0x0007, lo: 0x03}, - {value: 0x07a9, lo: 0x80, hi: 0x80}, - {value: 0x07b0, lo: 0x87, hi: 0x88}, - {value: 0x07be, lo: 0x8a, hi: 0x8b}, + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x8600, lo: 0x82, hi: 0x82}, + {value: 0x8800, lo: 0x86, hi: 0x86}, + {value: 0x0047, lo: 0x87, hi: 0x87}, + {value: 0x004e, lo: 0x88, hi: 0x88}, + {value: 0x2e37, lo: 0x8a, hi: 0x8a}, + {value: 0x00c5, lo: 0x8b, hi: 0x8b}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x95, hi: 0x96}, // Block 0x1c, offset 0x1d - {value: 0x0007, lo: 0x01}, - {value: 0x07cf, lo: 0x8a, hi: 0x8c}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0xbe, hi: 0xbe}, // Block 0x1d, offset 0x1e - {value: 0x0007, lo: 0x03}, - {value: 0x07e4, lo: 0x9a, hi: 0x9a}, - {value: 0x07eb, lo: 0x9c, hi: 0x9d}, - {value: 0x07fc, lo: 0x9e, hi: 0x9e}, + {value: 0x0000, lo: 0x06}, + {value: 0x8800, lo: 0x86, hi: 0x87}, + {value: 0x0055, lo: 0x8a, hi: 0x8a}, + {value: 0x0063, lo: 0x8b, hi: 0x8b}, + {value: 0x005c, lo: 0x8c, hi: 0x8c}, + {value: 0x8009, lo: 0x8d, hi: 0x8d}, + {value: 0x8600, lo: 0x97, hi: 0x97}, // Block 0x1e, offset 0x1f - {value: 0x0000, lo: 0x01}, - {value: 0x0803, lo: 0xb3, hi: 0xb3}, + {value: 0x12fd, lo: 0x07}, + {value: 0x8609, lo: 0x8a, hi: 0x8a}, + {value: 0x8600, lo: 0x8f, hi: 0x8f}, + {value: 0x8800, lo: 0x99, hi: 0x99}, + {value: 0x3ddd, lo: 0x9a, hi: 0x9a}, + {value: 0x2e3e, lo: 0x9c, hi: 0x9d}, + {value: 0x006a, lo: 0x9e, hi: 0x9e}, + {value: 0x8600, lo: 0x9f, hi: 0x9f}, // Block 0x1f, offset 0x20 - {value: 0x0000, lo: 0x01}, - {value: 0x080a, lo: 0xb3, hi: 0xb3}, + {value: 0x0000, lo: 0x03}, + {value: 0x2734, lo: 0xb3, hi: 0xb3}, + {value: 0x8067, lo: 0xb8, hi: 0xb9}, + {value: 0x8009, lo: 0xba, hi: 0xba}, // Block 0x20, offset 0x21 - {value: 0x0007, lo: 0x01}, - {value: 0x0811, lo: 0x9c, hi: 0x9d}, - // Block 0x21, offset 0x22 {value: 0x0000, lo: 0x01}, - {value: 0x081f, lo: 0x8c, hi: 0x8c}, + {value: 0x806b, lo: 0x88, hi: 0x8b}, + // Block 0x21, offset 0x22 + {value: 0x0000, lo: 0x02}, + {value: 0x2749, lo: 0xb3, hi: 0xb3}, + {value: 0x8076, lo: 0xb8, hi: 0xb9}, // Block 0x22, offset 0x23 - {value: 0x0007, lo: 0x09}, - {value: 0x0823, lo: 0x83, hi: 0x83}, - {value: 0x082a, lo: 0x8d, hi: 0x8d}, - {value: 0x0831, lo: 0x92, hi: 0x92}, - {value: 0x0838, lo: 0x97, hi: 0x97}, - {value: 0x083f, lo: 0x9c, hi: 0x9c}, - {value: 0x0846, lo: 0xa9, hi: 0xa9}, - {value: 0x084d, lo: 0xb3, hi: 0xb3}, - {value: 0x0854, lo: 0xb5, hi: 0xb7}, - {value: 0x086c, lo: 0xb8, hi: 0xb9}, + {value: 0x0000, lo: 0x03}, + {value: 0x807a, lo: 0x88, hi: 0x8b}, + {value: 0x273b, lo: 0x9c, hi: 0x9c}, + {value: 0x2742, lo: 0x9d, hi: 0x9d}, // Block 0x23, offset 0x24 - {value: 0x0000, lo: 0x07}, - {value: 0x087d, lo: 0x81, hi: 0x81}, - {value: 0x0884, lo: 0x93, hi: 0x93}, - {value: 0x088b, lo: 0x9d, hi: 0x9d}, - {value: 0x0892, lo: 0xa2, hi: 0xa2}, - {value: 0x0899, lo: 0xa7, hi: 0xa7}, - {value: 0x08a0, lo: 0xac, hi: 0xac}, - {value: 0x08a7, lo: 0xb9, hi: 0xb9}, + {value: 0x0000, lo: 0x05}, + {value: 0x07d1, lo: 0x8c, hi: 0x8c}, + {value: 0x80dc, lo: 0x98, hi: 0x99}, + {value: 0x80dc, lo: 0xb5, hi: 0xb5}, + {value: 0x80dc, lo: 0xb7, hi: 0xb7}, + {value: 0x80d8, lo: 0xb9, hi: 0xb9}, // Block 0x24, offset 0x25 - {value: 0x0000, lo: 0x01}, - {value: 0x08ae, lo: 0xa6, hi: 0xa6}, + {value: 0x0000, lo: 0x10}, + {value: 0x2757, lo: 0x83, hi: 0x83}, + {value: 0x275e, lo: 0x8d, hi: 0x8d}, + {value: 0x2765, lo: 0x92, hi: 0x92}, + {value: 0x276c, lo: 0x97, hi: 0x97}, + {value: 0x2773, lo: 0x9c, hi: 0x9c}, + {value: 0x2750, lo: 0xa9, hi: 0xa9}, + {value: 0x8081, lo: 0xb1, hi: 0xb1}, + {value: 0x8082, lo: 0xb2, hi: 0xb2}, + {value: 0x4987, lo: 0xb3, hi: 0xb3}, + {value: 0x8084, lo: 0xb4, hi: 0xb4}, + {value: 0x4990, lo: 0xb5, hi: 0xb5}, + {value: 0x44ca, lo: 0xb6, hi: 0xb6}, + {value: 0x450a, lo: 0xb7, hi: 0xb7}, + {value: 0x44d2, lo: 0xb8, hi: 0xb8}, + {value: 0x4515, lo: 0xb9, hi: 0xb9}, + {value: 0x8082, lo: 0xba, hi: 0xbd}, // Block 0x25, offset 0x26 - {value: 0x0000, lo: 0x01}, - {value: 0x08b5, lo: 0xbc, hi: 0xbc}, + {value: 0x0000, lo: 0x0b}, + {value: 0x8082, lo: 0x80, hi: 0x80}, + {value: 0x4999, lo: 0x81, hi: 0x81}, + {value: 0x80e6, lo: 0x82, hi: 0x83}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0x86, hi: 0x87}, + {value: 0x2781, lo: 0x93, hi: 0x93}, + {value: 0x2788, lo: 0x9d, hi: 0x9d}, + {value: 0x278f, lo: 0xa2, hi: 0xa2}, + {value: 0x2796, lo: 0xa7, hi: 0xa7}, + {value: 0x279d, lo: 0xac, hi: 0xac}, + {value: 0x277a, lo: 0xb9, hi: 0xb9}, // Block 0x26, offset 0x27 - {value: 0x0000, lo: 0x08}, - {value: 0x08b9, lo: 0x86, hi: 0x86}, - {value: 0x08c0, lo: 0x88, hi: 0x88}, - {value: 0x08c7, lo: 0x8a, hi: 0x8a}, - {value: 0x08ce, lo: 0x8c, hi: 0x8c}, - {value: 0x08d5, lo: 0x8e, hi: 0x8e}, - {value: 0x08dc, lo: 0x92, hi: 0x92}, - {value: 0x08e3, lo: 0xbb, hi: 0xbb}, - {value: 0x08ea, lo: 0xbd, hi: 0xbd}, + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0x86, hi: 0x86}, // Block 0x27, offset 0x28 - {value: 0x0007, lo: 0x02}, - {value: 0x08f1, lo: 0x80, hi: 0x81}, - {value: 0x08ff, lo: 0x83, hi: 0x83}, + {value: 0x0000, lo: 0x05}, + {value: 0x8800, lo: 0xa5, hi: 0xa5}, + {value: 0x0071, lo: 0xa6, hi: 0xa6}, + {value: 0x8600, lo: 0xae, hi: 0xae}, + {value: 0x8007, lo: 0xb7, hi: 0xb7}, + {value: 0x8009, lo: 0xb9, hi: 0xba}, // Block 0x28, offset 0x29 - {value: 0x0002, lo: 0x06}, - {value: 0x0906, lo: 0xac, hi: 0xad}, - {value: 0x090b, lo: 0xae, hi: 0xae}, - {value: 0x090d, lo: 0xb0, hi: 0xb2}, - {value: 0x0914, lo: 0xb3, hi: 0xba}, - {value: 0x0924, lo: 0xbc, hi: 0xbd}, - {value: 0x0929, lo: 0xbe, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0x8d, hi: 0x8d}, // Block 0x29, offset 0x2a - {value: 0x0003, lo: 0x0a}, - {value: 0x0981, lo: 0x9b, hi: 0x9c}, - {value: 0x0986, lo: 0x9d, hi: 0x9e}, - {value: 0x0949, lo: 0x9f, hi: 0x9f}, - {value: 0x098c, lo: 0xa0, hi: 0xa0}, - {value: 0x098e, lo: 0xa1, hi: 0xa7}, - {value: 0x09a4, lo: 0xa8, hi: 0xaa}, - {value: 0x09ae, lo: 0xab, hi: 0xb8}, - {value: 0x09d9, lo: 0xb9, hi: 0xbb}, - {value: 0x09e1, lo: 0xbc, hi: 0xbe}, - {value: 0x055c, lo: 0xbf, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x07d5, lo: 0xbc, hi: 0xbc}, // Block 0x2a, offset 0x2b - {value: 0x0004, lo: 0x0d}, - {value: 0x09ea, lo: 0x80, hi: 0x88}, - {value: 0x0a10, lo: 0x89, hi: 0x89}, - {value: 0x0a16, lo: 0x8a, hi: 0x94}, - {value: 0x0a44, lo: 0x95, hi: 0x95}, - {value: 0x0a4a, lo: 0x96, hi: 0x96}, - {value: 0x0a50, lo: 0x97, hi: 0x97}, - {value: 0x0a56, lo: 0x98, hi: 0x9c}, - {value: 0x0a6c, lo: 0x9d, hi: 0x9d}, - {value: 0x0a72, lo: 0x9e, hi: 0xae}, - {value: 0x0ab8, lo: 0xaf, hi: 0xaf}, - {value: 0x0abe, lo: 0xb0, hi: 0xb8}, - {value: 0x0ae4, lo: 0xb9, hi: 0xb9}, - {value: 0x0aea, lo: 0xba, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x8800, lo: 0x80, hi: 0x92}, // Block 0x2b, offset 0x2c - {value: 0x0000, lo: 0x0d}, - {value: 0x0001, lo: 0x80, hi: 0x8a}, - {value: 0x1436, lo: 0x91, hi: 0x91}, - {value: 0x143a, lo: 0x97, hi: 0x97}, - {value: 0x143e, lo: 0xa4, hi: 0xa4}, - {value: 0x1440, lo: 0xa5, hi: 0xa5}, - {value: 0x1443, lo: 0xa6, hi: 0xa6}, - {value: 0x0001, lo: 0xaf, hi: 0xaf}, - {value: 0x1447, lo: 0xb3, hi: 0xb3}, - {value: 0x144e, lo: 0xb4, hi: 0xb4}, - {value: 0x1458, lo: 0xb6, hi: 0xb6}, - {value: 0x145f, lo: 0xb7, hi: 0xb7}, - {value: 0x1469, lo: 0xbc, hi: 0xbc}, - {value: 0x146c, lo: 0xbe, hi: 0xbe}, + {value: 0x0000, lo: 0x01}, + {value: 0x8e00, lo: 0xa1, hi: 0xb5}, // Block 0x2c, offset 0x2d - {value: 0x0002, lo: 0x09}, - {value: 0x1470, lo: 0x87, hi: 0x87}, - {value: 0x1473, lo: 0x88, hi: 0x88}, - {value: 0x1476, lo: 0x89, hi: 0x89}, - {value: 0x1479, lo: 0x97, hi: 0x97}, - {value: 0x0001, lo: 0x9f, hi: 0x9f}, - {value: 0x1486, lo: 0xb0, hi: 0xb0}, - {value: 0x097c, lo: 0xb1, hi: 0xb1}, - {value: 0x1488, lo: 0xb4, hi: 0xbb}, - {value: 0x149a, lo: 0xbc, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0xa8, hi: 0xbf}, // Block 0x2d, offset 0x2e - {value: 0x0006, lo: 0x03}, - {value: 0x1599, lo: 0x89, hi: 0x89}, - {value: 0x159f, lo: 0x9a, hi: 0x9b}, - {value: 0x15ab, lo: 0xae, hi: 0xae}, + {value: 0x0000, lo: 0x01}, + {value: 0x8600, lo: 0x80, hi: 0x82}, // Block 0x2e, offset 0x2f - {value: 0x0006, lo: 0x01}, - {value: 0x15b1, lo: 0x8d, hi: 0x8f}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x9d, hi: 0x9f}, // Block 0x2f, offset 0x30 - {value: 0x0007, lo: 0x07}, - {value: 0x15c3, lo: 0x84, hi: 0x84}, - {value: 0x15c9, lo: 0x89, hi: 0x89}, - {value: 0x15cf, lo: 0x8c, hi: 0x8c}, - {value: 0x15d5, lo: 0xa4, hi: 0xa4}, - {value: 0x15db, lo: 0xa6, hi: 0xa6}, - {value: 0x15e1, lo: 0xac, hi: 0xad}, - {value: 0x15f2, lo: 0xaf, hi: 0xb0}, + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x94, hi: 0x94}, + {value: 0x8009, lo: 0xb4, hi: 0xb4}, // Block 0x30, offset 0x31 - {value: 0x0006, lo: 0x0b}, - {value: 0x1603, lo: 0x81, hi: 0x81}, - {value: 0x1609, lo: 0x84, hi: 0x84}, - {value: 0x160f, lo: 0x87, hi: 0x87}, - {value: 0x1615, lo: 0x89, hi: 0x89}, - {value: 0x161b, lo: 0xa0, hi: 0xa0}, - {value: 0x161f, lo: 0xa2, hi: 0xa2}, - {value: 0x1625, lo: 0xad, hi: 0xae}, - {value: 0x162f, lo: 0xaf, hi: 0xaf}, - {value: 0x1633, lo: 0xb0, hi: 0xb1}, - {value: 0x163f, lo: 0xb4, hi: 0xb5}, - {value: 0x164b, lo: 0xb8, hi: 0xb9}, + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x92, hi: 0x92}, + {value: 0x80e6, lo: 0x9d, hi: 0x9d}, // Block 0x31, offset 0x32 - {value: 0x0006, lo: 0x04}, - {value: 0x1657, lo: 0x80, hi: 0x81}, - {value: 0x1663, lo: 0x84, hi: 0x85}, - {value: 0x166f, lo: 0x88, hi: 0x89}, - {value: 0x167b, lo: 0xac, hi: 0xaf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e4, lo: 0xa9, hi: 0xa9}, // Block 0x32, offset 0x33 - {value: 0x0006, lo: 0x02}, - {value: 0x1693, lo: 0xa0, hi: 0xa3}, - {value: 0x16ab, lo: 0xaa, hi: 0xad}, + {value: 0x0008, lo: 0x02}, + {value: 0x80de, lo: 0xb9, hi: 0xba}, + {value: 0x80dc, lo: 0xbb, hi: 0xbb}, // Block 0x33, offset 0x34 - {value: 0x0004, lo: 0x01}, - {value: 0x16c3, lo: 0xa9, hi: 0xaa}, + {value: 0x0000, lo: 0x02}, + {value: 0x80e6, lo: 0x97, hi: 0x97}, + {value: 0x80dc, lo: 0x98, hi: 0x98}, // Block 0x34, offset 0x35 - {value: 0x0000, lo: 0x01}, - {value: 0x17fc, lo: 0x8c, hi: 0x8c}, + {value: 0x0000, lo: 0x03}, + {value: 0x8009, lo: 0xa0, hi: 0xa0}, + {value: 0x80e6, lo: 0xb5, hi: 0xbc}, + {value: 0x80dc, lo: 0xbf, hi: 0xbf}, // Block 0x35, offset 0x36 - {value: 0x0003, lo: 0x02}, - {value: 0x1809, lo: 0xb4, hi: 0xb4}, - {value: 0x180d, lo: 0xb5, hi: 0xb6}, + {value: 0x0000, lo: 0x08}, + {value: 0x00b0, lo: 0x80, hi: 0x80}, + {value: 0x00b7, lo: 0x81, hi: 0x81}, + {value: 0x8800, lo: 0x82, hi: 0x82}, + {value: 0x00be, lo: 0x83, hi: 0x83}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0xab, hi: 0xab}, + {value: 0x80dc, lo: 0xac, hi: 0xac}, + {value: 0x80e6, lo: 0xad, hi: 0xb3}, // Block 0x36, offset 0x37 {value: 0x0000, lo: 0x01}, - {value: 0x1814, lo: 0x9c, hi: 0x9c}, + {value: 0x8009, lo: 0xaa, hi: 0xaa}, // Block 0x37, offset 0x38 - {value: 0x10c6, lo: 0x01}, - {value: 0x0499, lo: 0xbc, hi: 0xbd}, + {value: 0x0000, lo: 0x02}, + {value: 0x8007, lo: 0xa6, hi: 0xa6}, + {value: 0x8009, lo: 0xb2, hi: 0xb3}, // Block 0x38, offset 0x39 {value: 0x0000, lo: 0x01}, - {value: 0x181a, lo: 0xaf, hi: 0xaf}, + {value: 0x8007, lo: 0xb7, hi: 0xb7}, // Block 0x39, offset 0x3a - {value: 0x0000, lo: 0x01}, - {value: 0x181e, lo: 0x9f, hi: 0x9f}, + {value: 0x0000, lo: 0x08}, + {value: 0x80e6, lo: 0x90, hi: 0x92}, + {value: 0x8001, lo: 0x94, hi: 0x94}, + {value: 0x80dc, lo: 0x95, hi: 0x99}, + {value: 0x80e6, lo: 0x9a, hi: 0x9b}, + {value: 0x80dc, lo: 0x9c, hi: 0x9f}, + {value: 0x80e6, lo: 0xa0, hi: 0xa0}, + {value: 0x8001, lo: 0xa2, hi: 0xa8}, + {value: 0x80dc, lo: 0xad, hi: 0xad}, // Block 0x3a, offset 0x3b - {value: 0x0000, lo: 0x01}, - {value: 0x1822, lo: 0xb3, hi: 0xb3}, + {value: 0x0002, lo: 0x0a}, + {value: 0x0111, lo: 0xac, hi: 0xac}, + {value: 0x0397, lo: 0xad, hi: 0xad}, + {value: 0x0113, lo: 0xae, hi: 0xae}, + {value: 0x0117, lo: 0xb0, hi: 0xb1}, + {value: 0x03a6, lo: 0xb2, hi: 0xb2}, + {value: 0x011d, lo: 0xb3, hi: 0xba}, + {value: 0x012d, lo: 0xbc, hi: 0xbc}, + {value: 0x03af, lo: 0xbd, hi: 0xbd}, + {value: 0x012f, lo: 0xbe, hi: 0xbe}, + {value: 0x0133, lo: 0xbf, hi: 0xbf}, // Block 0x3b, offset 0x3c - {value: 0x0004, lo: 0x01}, - {value: 0x1826, lo: 0x80, hi: 0xbf}, + {value: 0x0000, lo: 0x0e}, + {value: 0x80e6, lo: 0x80, hi: 0x81}, + {value: 0x80dc, lo: 0x82, hi: 0x82}, + {value: 0x80e6, lo: 0x83, hi: 0x89}, + {value: 0x80dc, lo: 0x8a, hi: 0x8a}, + {value: 0x80e6, lo: 0x8b, hi: 0x8c}, + {value: 0x80ea, lo: 0x8d, hi: 0x8d}, + {value: 0x80d6, lo: 0x8e, hi: 0x8e}, + {value: 0x80dc, lo: 0x8f, hi: 0x8f}, + {value: 0x80ca, lo: 0x90, hi: 0x90}, + {value: 0x80e6, lo: 0x91, hi: 0xa6}, + {value: 0x80e9, lo: 0xbc, hi: 0xbc}, + {value: 0x80dc, lo: 0xbd, hi: 0xbd}, + {value: 0x80e6, lo: 0xbe, hi: 0xbe}, + {value: 0x80dc, lo: 0xbf, hi: 0xbf}, // Block 0x3c, offset 0x3d - {value: 0x0004, lo: 0x01}, - {value: 0x1926, lo: 0x80, hi: 0xbf}, + {value: 0x0000, lo: 0x0d}, + {value: 0x00cf, lo: 0x80, hi: 0x8a}, + {value: 0x0979, lo: 0x91, hi: 0x91}, + {value: 0x4187, lo: 0x97, hi: 0x97}, + {value: 0x00eb, lo: 0xa4, hi: 0xa4}, + {value: 0x0193, lo: 0xa5, hi: 0xa5}, + {value: 0x06ad, lo: 0xa6, hi: 0xa6}, + {value: 0x00cf, lo: 0xaf, hi: 0xaf}, + {value: 0x280d, lo: 0xb3, hi: 0xb3}, + {value: 0x297a, lo: 0xb4, hi: 0xb4}, + {value: 0x2814, lo: 0xb6, hi: 0xb6}, + {value: 0x2984, lo: 0xb7, hi: 0xb7}, + {value: 0x018d, lo: 0xbc, hi: 0xbc}, + {value: 0x4155, lo: 0xbe, hi: 0xbe}, // Block 0x3d, offset 0x3e - {value: 0x0004, lo: 0x01}, - {value: 0x1a26, lo: 0x80, hi: 0xbf}, + {value: 0x0002, lo: 0x0d}, + {value: 0x0253, lo: 0x87, hi: 0x87}, + {value: 0x0250, lo: 0x88, hi: 0x88}, + {value: 0x0190, lo: 0x89, hi: 0x89}, + {value: 0x2b17, lo: 0x97, hi: 0x97}, + {value: 0x00cf, lo: 0x9f, hi: 0x9f}, + {value: 0x00ef, lo: 0xb0, hi: 0xb0}, + {value: 0x0161, lo: 0xb1, hi: 0xb1}, + {value: 0x00f7, lo: 0xb4, hi: 0xb9}, + {value: 0x00e5, lo: 0xba, hi: 0xba}, + {value: 0x09a5, lo: 0xbb, hi: 0xbb}, + {value: 0x0109, lo: 0xbc, hi: 0xbc}, + {value: 0x00df, lo: 0xbd, hi: 0xbe}, + {value: 0x016b, lo: 0xbf, hi: 0xbf}, // Block 0x3e, offset 0x3f - {value: 0x0004, lo: 0x01}, - {value: 0x1b26, lo: 0x80, hi: 0x95}, + {value: 0x0002, lo: 0x0f}, + {value: 0x00ef, lo: 0x80, hi: 0x89}, + {value: 0x00e5, lo: 0x8a, hi: 0x8a}, + {value: 0x09a5, lo: 0x8b, hi: 0x8b}, + {value: 0x0109, lo: 0x8c, hi: 0x8c}, + {value: 0x00df, lo: 0x8d, hi: 0x8e}, + {value: 0x0151, lo: 0x90, hi: 0x90}, + {value: 0x0159, lo: 0x91, hi: 0x91}, + {value: 0x016d, lo: 0x92, hi: 0x92}, + {value: 0x017f, lo: 0x93, hi: 0x93}, + {value: 0x03c4, lo: 0x94, hi: 0x94}, + {value: 0x015f, lo: 0x95, hi: 0x95}, + {value: 0x0165, lo: 0x96, hi: 0x99}, + {value: 0x016f, lo: 0x9a, hi: 0x9a}, + {value: 0x0175, lo: 0x9b, hi: 0x9c}, + {value: 0x02b3, lo: 0xa8, hi: 0xa8}, // Block 0x3f, offset 0x40 - {value: 0x0004, lo: 0x04}, - {value: 0x0001, lo: 0x80, hi: 0x80}, - {value: 0x1b7e, lo: 0xb6, hi: 0xb6}, - {value: 0x1882, lo: 0xb8, hi: 0xb8}, - {value: 0x1b82, lo: 0xb9, hi: 0xba}, + {value: 0x0000, lo: 0x0d}, + {value: 0x80e6, lo: 0x90, hi: 0x91}, + {value: 0x8001, lo: 0x92, hi: 0x93}, + {value: 0x80e6, lo: 0x94, hi: 0x97}, + {value: 0x8001, lo: 0x98, hi: 0x9a}, + {value: 0x80e6, lo: 0x9b, hi: 0x9c}, + {value: 0x80e6, lo: 0xa1, hi: 0xa1}, + {value: 0x8001, lo: 0xa5, hi: 0xa6}, + {value: 0x80e6, lo: 0xa7, hi: 0xa7}, + {value: 0x80dc, lo: 0xa8, hi: 0xa8}, + {value: 0x80e6, lo: 0xa9, hi: 0xa9}, + {value: 0x8001, lo: 0xaa, hi: 0xab}, + {value: 0x80dc, lo: 0xac, hi: 0xaf}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, // Block 0x40, offset 0x41 - {value: 0x0005, lo: 0x0e}, - {value: 0x1c39, lo: 0x94, hi: 0x94}, - {value: 0x1c40, lo: 0x9b, hi: 0x9c}, - {value: 0x1c4a, lo: 0x9e, hi: 0x9e}, - {value: 0x1c51, lo: 0x9f, hi: 0x9f}, - {value: 0x1c58, lo: 0xac, hi: 0xac}, - {value: 0x1c5f, lo: 0xae, hi: 0xae}, - {value: 0x1c66, lo: 0xb0, hi: 0xb0}, - {value: 0x1c6d, lo: 0xb2, hi: 0xb2}, - {value: 0x1c74, lo: 0xb4, hi: 0xb4}, - {value: 0x1c7b, lo: 0xb6, hi: 0xb6}, - {value: 0x1c82, lo: 0xb8, hi: 0xb8}, - {value: 0x1c89, lo: 0xba, hi: 0xba}, - {value: 0x1c90, lo: 0xbc, hi: 0xbc}, - {value: 0x1c97, lo: 0xbe, hi: 0xbe}, + {value: 0x0007, lo: 0x06}, + {value: 0x2293, lo: 0x89, hi: 0x89}, + {value: 0x8800, lo: 0x90, hi: 0x90}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x8800, lo: 0x94, hi: 0x94}, + {value: 0x3a9e, lo: 0x9a, hi: 0x9b}, + {value: 0x3aac, lo: 0xae, hi: 0xae}, // Block 0x41, offset 0x42 - {value: 0x0007, lo: 0x0d}, - {value: 0x1c9e, lo: 0x80, hi: 0x80}, - {value: 0x1ca5, lo: 0x82, hi: 0x82}, - {value: 0x1cac, lo: 0x85, hi: 0x85}, - {value: 0x1cb3, lo: 0x87, hi: 0x87}, - {value: 0x1cba, lo: 0x89, hi: 0x89}, - {value: 0x1cc1, lo: 0x90, hi: 0x91}, - {value: 0x1ccf, lo: 0x93, hi: 0x94}, - {value: 0x1cdd, lo: 0x96, hi: 0x97}, - {value: 0x1ceb, lo: 0x99, hi: 0x9a}, - {value: 0x1cf9, lo: 0x9c, hi: 0x9d}, - {value: 0x1d07, lo: 0xb4, hi: 0xb4}, - {value: 0x1d0e, lo: 0xb7, hi: 0xba}, - {value: 0x1d2a, lo: 0xbe, hi: 0xbf}, + {value: 0x000e, lo: 0x05}, + {value: 0x3ab3, lo: 0x8d, hi: 0x8e}, + {value: 0x3aba, lo: 0x8f, hi: 0x8f}, + {value: 0x8800, lo: 0x90, hi: 0x90}, + {value: 0x8800, lo: 0x92, hi: 0x92}, + {value: 0x8800, lo: 0x94, hi: 0x94}, // Block 0x42, offset 0x43 - {value: 0x0004, lo: 0x01}, - {value: 0x1d38, lo: 0xb1, hi: 0xbf}, + {value: 0x0173, lo: 0x0e}, + {value: 0x8800, lo: 0x83, hi: 0x83}, + {value: 0x3ac8, lo: 0x84, hi: 0x84}, + {value: 0x8800, lo: 0x88, hi: 0x88}, + {value: 0x3acf, lo: 0x89, hi: 0x89}, + {value: 0x8800, lo: 0x8b, hi: 0x8b}, + {value: 0x3ad6, lo: 0x8c, hi: 0x8c}, + {value: 0x8800, lo: 0xa3, hi: 0xa3}, + {value: 0x3add, lo: 0xa4, hi: 0xa4}, + {value: 0x8800, lo: 0xa5, hi: 0xa5}, + {value: 0x3ae4, lo: 0xa6, hi: 0xa6}, + {value: 0x281b, lo: 0xac, hi: 0xad}, + {value: 0x2822, lo: 0xaf, hi: 0xaf}, + {value: 0x2998, lo: 0xb0, hi: 0xb0}, + {value: 0x8800, lo: 0xbc, hi: 0xbc}, // Block 0x43, offset 0x44 - {value: 0x0004, lo: 0x01}, - {value: 0x1d74, lo: 0x80, hi: 0xbf}, + {value: 0x0007, lo: 0x03}, + {value: 0x3b4d, lo: 0xa0, hi: 0xa1}, + {value: 0x3b77, lo: 0xa2, hi: 0xa3}, + {value: 0x3ba1, lo: 0xaa, hi: 0xad}, // Block 0x44, offset 0x45 - {value: 0x0004, lo: 0x07}, - {value: 0x1e74, lo: 0x80, hi: 0x8e}, - {value: 0x1826, lo: 0x92, hi: 0x92}, - {value: 0x183e, lo: 0x93, hi: 0x93}, - {value: 0x1eb0, lo: 0x94, hi: 0x99}, - {value: 0x1836, lo: 0x9a, hi: 0x9a}, - {value: 0x1ec8, lo: 0x9b, hi: 0x9e}, - {value: 0x1846, lo: 0x9f, hi: 0x9f}, + {value: 0x0004, lo: 0x01}, + {value: 0x09c9, lo: 0xa9, hi: 0xaa}, // Block 0x45, offset 0x46 - {value: 0x0004, lo: 0x0f}, - {value: 0x221c, lo: 0x80, hi: 0x80}, - {value: 0x2221, lo: 0x81, hi: 0x81}, - {value: 0x2226, lo: 0x82, hi: 0x82}, - {value: 0x222b, lo: 0x83, hi: 0x83}, - {value: 0x2230, lo: 0x84, hi: 0x84}, - {value: 0x2235, lo: 0x85, hi: 0x85}, - {value: 0x223a, lo: 0x86, hi: 0x86}, - {value: 0x223f, lo: 0x87, hi: 0x87}, - {value: 0x2244, lo: 0x88, hi: 0x88}, - {value: 0x2249, lo: 0x89, hi: 0x89}, - {value: 0x224f, lo: 0x8a, hi: 0x8a}, - {value: 0x2255, lo: 0x8b, hi: 0x8b}, - {value: 0x225b, lo: 0x8c, hi: 0x8c}, - {value: 0x225e, lo: 0x8d, hi: 0x8e}, - {value: 0x2265, lo: 0x8f, hi: 0xbe}, + {value: 0x0002, lo: 0x03}, + {value: 0x0125, lo: 0x80, hi: 0x8f}, + {value: 0x0151, lo: 0x90, hi: 0xa9}, + {value: 0x00ef, lo: 0xaa, hi: 0xaa}, // Block 0x46, offset 0x47 {value: 0x0000, lo: 0x01}, - {value: 0x2a7d, lo: 0xb0, hi: 0xb0}, + {value: 0x2b24, lo: 0x8c, hi: 0x8c}, // Block 0x47, offset 0x48 - {value: 0x0004, lo: 0x0a}, - {value: 0x2a81, lo: 0x80, hi: 0x81}, - {value: 0x1a9e, lo: 0x82, hi: 0x82}, - {value: 0x2a89, lo: 0x83, hi: 0x86}, - {value: 0x1b76, lo: 0x87, hi: 0x87}, - {value: 0x1b76, lo: 0x88, hi: 0x88}, - {value: 0x2a99, lo: 0x89, hi: 0x89}, - {value: 0x1abe, lo: 0x8a, hi: 0x8a}, - {value: 0x2a9d, lo: 0x8b, hi: 0xb3}, - {value: 0x1a16, lo: 0xb4, hi: 0xb4}, - {value: 0x2b41, lo: 0xb5, hi: 0xbf}, + {value: 0x0494, lo: 0x02}, + {value: 0x06dd, lo: 0xb4, hi: 0xb4}, + {value: 0x024d, lo: 0xb5, hi: 0xb6}, // Block 0x48, offset 0x49 - {value: 0x0004, lo: 0x06}, - {value: 0x1b3a, lo: 0x80, hi: 0x80}, - {value: 0x2b6d, lo: 0x81, hi: 0x9b}, - {value: 0x2ac1, lo: 0x9c, hi: 0x9c}, - {value: 0x2bd9, lo: 0x9d, hi: 0xb0}, - {value: 0x1aa6, lo: 0xb1, hi: 0xb1}, - {value: 0x2c29, lo: 0xb2, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x43db, lo: 0x9c, hi: 0x9c}, // Block 0x49, offset 0x4a - {value: 0x0004, lo: 0x0a}, - {value: 0x2c61, lo: 0x80, hi: 0x80}, - {value: 0x18ba, lo: 0x81, hi: 0x81}, - {value: 0x2c65, lo: 0x82, hi: 0x89}, - {value: 0x186e, lo: 0x8a, hi: 0x8a}, - {value: 0x2c85, lo: 0x8b, hi: 0xa0}, - {value: 0x2c21, lo: 0xa1, hi: 0xa1}, - {value: 0x2cdd, lo: 0xa2, hi: 0xa9}, - {value: 0x2be1, lo: 0xaa, hi: 0xaa}, - {value: 0x2cfd, lo: 0xab, hi: 0xbe}, - {value: 0x2ac1, lo: 0xbf, hi: 0xbf}, + {value: 0x0000, lo: 0x02}, + {value: 0x0163, lo: 0xbc, hi: 0xbc}, + {value: 0x013b, lo: 0xbd, hi: 0xbd}, // Block 0x4a, offset 0x4b - {value: 0x0004, lo: 0x0b}, - {value: 0x2d4d, lo: 0x80, hi: 0x83}, - {value: 0x1b72, lo: 0x84, hi: 0x84}, - {value: 0x2d5d, lo: 0x85, hi: 0x90}, - {value: 0x2173, lo: 0x91, hi: 0x91}, - {value: 0x2d8d, lo: 0x92, hi: 0x9a}, - {value: 0x2be9, lo: 0x9b, hi: 0x9b}, - {value: 0x2db1, lo: 0x9c, hi: 0xa8}, - {value: 0x1aba, lo: 0xa9, hi: 0xa9}, - {value: 0x2de5, lo: 0xaa, hi: 0xb6}, - {value: 0x19f6, lo: 0xb7, hi: 0xb7}, - {value: 0x2e19, lo: 0xb8, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xaf, hi: 0xb1}, // Block 0x4b, offset 0x4c - {value: 0x0004, lo: 0x10}, - {value: 0x2e39, lo: 0x80, hi: 0x87}, - {value: 0x1a62, lo: 0x88, hi: 0x88}, - {value: 0x2e59, lo: 0x89, hi: 0x89}, - {value: 0x1a6e, lo: 0x8a, hi: 0x8a}, - {value: 0x2e5d, lo: 0x8b, hi: 0x8d}, - {value: 0x2e69, lo: 0x90, hi: 0x90}, - {value: 0x2e6d, lo: 0x92, hi: 0x92}, - {value: 0x2e71, lo: 0x95, hi: 0x9d}, - {value: 0x1a12, lo: 0x9e, hi: 0x9e}, - {value: 0x2e95, lo: 0xa0, hi: 0xa0}, - {value: 0x2e99, lo: 0xa2, hi: 0xa2}, - {value: 0x2e9d, lo: 0xa5, hi: 0xa6}, - {value: 0x2ea5, lo: 0xaa, hi: 0xad}, - {value: 0x2eb5, lo: 0xb0, hi: 0xbb}, - {value: 0x18d6, lo: 0xbc, hi: 0xbc}, - {value: 0x2ee5, lo: 0xbd, hi: 0xbf}, + {value: 0x0000, lo: 0x02}, + {value: 0x09bd, lo: 0xaf, hi: 0xaf}, + {value: 0x8009, lo: 0xbf, hi: 0xbf}, // Block 0x4c, offset 0x4d - {value: 0x0004, lo: 0x10}, - {value: 0x2ef1, lo: 0x80, hi: 0x8b}, - {value: 0x2187, lo: 0x8c, hi: 0x8c}, - {value: 0x2f21, lo: 0x8d, hi: 0x90}, - {value: 0x2197, lo: 0x91, hi: 0x91}, - {value: 0x2f31, lo: 0x92, hi: 0x96}, - {value: 0x2cb1, lo: 0x97, hi: 0x97}, - {value: 0x2f45, lo: 0x98, hi: 0x9d}, - {value: 0x2f59, lo: 0x9e, hi: 0xa6}, - {value: 0x2e9d, lo: 0xa7, hi: 0xa7}, - {value: 0x2f7d, lo: 0xa8, hi: 0xac}, - {value: 0x2f92, lo: 0xad, hi: 0xad}, - {value: 0x2f96, lo: 0xb0, hi: 0xb7}, - {value: 0x2ecd, lo: 0xb8, hi: 0xb8}, - {value: 0x2fb6, lo: 0xb9, hi: 0xbb}, - {value: 0x2e69, lo: 0xbc, hi: 0xbc}, - {value: 0x2fc2, lo: 0xbd, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xa0, hi: 0xbf}, // Block 0x4d, offset 0x4e - {value: 0x0005, lo: 0x06}, - {value: 0x3277, lo: 0x80, hi: 0x80}, - {value: 0x327e, lo: 0x81, hi: 0x81}, - {value: 0x3285, lo: 0x82, hi: 0x82}, - {value: 0x326d, lo: 0x83, hi: 0x83}, - {value: 0x328c, lo: 0x84, hi: 0x84}, - {value: 0x3293, lo: 0x85, hi: 0xbf}, + {value: 0x0000, lo: 0x01}, + {value: 0x1301, lo: 0x9f, hi: 0x9f}, // Block 0x4e, offset 0x4f - {value: 0x0005, lo: 0x10}, - {value: 0x356a, lo: 0x80, hi: 0x8b}, - {value: 0x3514, lo: 0x8c, hi: 0x8c}, - {value: 0x35a6, lo: 0x8d, hi: 0x90}, - {value: 0x3533, lo: 0x91, hi: 0xa7}, - {value: 0x3514, lo: 0xa8, hi: 0xa8}, - {value: 0x35a6, lo: 0xa9, hi: 0xac}, - {value: 0x3597, lo: 0xad, hi: 0xaf}, - {value: 0x3514, lo: 0xb0, hi: 0xb0}, - {value: 0x350f, lo: 0xb1, hi: 0xb1}, - {value: 0x3519, lo: 0xb2, hi: 0xb2}, - {value: 0x333d, lo: 0xb3, hi: 0xb3}, - {value: 0x3306, lo: 0xb4, hi: 0xb6}, - {value: 0x3597, lo: 0xb7, hi: 0xb9}, - {value: 0x333d, lo: 0xba, hi: 0xbb}, - {value: 0x35ba, lo: 0xbc, hi: 0xbc}, - {value: 0x35ba, lo: 0xbd, hi: 0xbd}, + {value: 0x0000, lo: 0x01}, + {value: 0x1b61, lo: 0xb3, hi: 0xb3}, // Block 0x4f, offset 0x50 - {value: 0x0007, lo: 0x0d}, - {value: 0x35bf, lo: 0x90, hi: 0x91}, - {value: 0x35c6, lo: 0x92, hi: 0x98}, - {value: 0x35f0, lo: 0x99, hi: 0x9f}, - {value: 0x361a, lo: 0xa0, hi: 0xa2}, - {value: 0x3628, lo: 0xa3, hi: 0xa4}, - {value: 0x362f, lo: 0xa5, hi: 0xa7}, - {value: 0x363d, lo: 0xa8, hi: 0xaa}, - {value: 0x364b, lo: 0xab, hi: 0xac}, - {value: 0x3652, lo: 0xad, hi: 0xaf}, - {value: 0x3660, lo: 0xb0, hi: 0xb1}, - {value: 0x3667, lo: 0xb2, hi: 0xb6}, - {value: 0x3683, lo: 0xb7, hi: 0xbc}, - {value: 0x36a6, lo: 0xbd, hi: 0xbf}, + {value: 0x0004, lo: 0x0b}, + {value: 0x1ac9, lo: 0x80, hi: 0x82}, + {value: 0x1ae1, lo: 0x83, hi: 0x83}, + {value: 0x1af9, lo: 0x84, hi: 0x85}, + {value: 0x1b09, lo: 0x86, hi: 0x89}, + {value: 0x1b1d, lo: 0x8a, hi: 0x8c}, + {value: 0x1b31, lo: 0x8d, hi: 0x8d}, + {value: 0x1b39, lo: 0x8e, hi: 0x8e}, + {value: 0x1b41, lo: 0x8f, hi: 0x90}, + {value: 0x1b4d, lo: 0x91, hi: 0x93}, + {value: 0x1b5d, lo: 0x94, hi: 0x94}, + {value: 0x1b65, lo: 0x95, hi: 0x95}, // Block 0x50, offset 0x51 - {value: 0x0007, lo: 0x0d}, - {value: 0x36bb, lo: 0x80, hi: 0x83}, - {value: 0x36d0, lo: 0x84, hi: 0x85}, - {value: 0x36d7, lo: 0x86, hi: 0x87}, - {value: 0x36de, lo: 0x88, hi: 0x8f}, - {value: 0x3716, lo: 0x92, hi: 0x97}, - {value: 0x3739, lo: 0x98, hi: 0x9c}, - {value: 0x3755, lo: 0x9d, hi: 0xb3}, - {value: 0x36ad, lo: 0xb4, hi: 0xb4}, - {value: 0x36bb, lo: 0xb5, hi: 0xb5}, - {value: 0x37f6, lo: 0xb6, hi: 0xbb}, - {value: 0x3812, lo: 0xbc, hi: 0xbc}, - {value: 0x3804, lo: 0xbd, hi: 0xbd}, - {value: 0x3820, lo: 0xbe, hi: 0xbf}, + {value: 0x0004, lo: 0x08}, + {value: 0x00cf, lo: 0x80, hi: 0x80}, + {value: 0x80da, lo: 0xaa, hi: 0xaa}, + {value: 0x80e4, lo: 0xab, hi: 0xac}, + {value: 0x80de, lo: 0xad, hi: 0xad}, + {value: 0x80e0, lo: 0xae, hi: 0xae}, + {value: 0x80e0, lo: 0xaf, hi: 0xaf}, + {value: 0x09f1, lo: 0xb6, hi: 0xb6}, + {value: 0x0dc5, lo: 0xb8, hi: 0xba}, // Block 0x51, offset 0x52 - {value: 0x0009, lo: 0x0e}, - {value: 0x382e, lo: 0x80, hi: 0x80}, - {value: 0x3835, lo: 0x81, hi: 0x81}, - {value: 0x383c, lo: 0x82, hi: 0x82}, - {value: 0x3819, lo: 0x83, hi: 0x83}, - {value: 0x367c, lo: 0x84, hi: 0x84}, - {value: 0x3636, lo: 0x85, hi: 0x85}, - {value: 0x3843, lo: 0x86, hi: 0x86}, - {value: 0x384a, lo: 0x87, hi: 0x87}, - {value: 0x3851, lo: 0xb0, hi: 0xb0}, - {value: 0x3858, lo: 0xb1, hi: 0xb1}, - {value: 0x385f, lo: 0xb2, hi: 0xb9}, - {value: 0x38a5, lo: 0xba, hi: 0xba}, - {value: 0x38c7, lo: 0xbb, hi: 0xbb}, - {value: 0x38d7, lo: 0xbc, hi: 0xbc}, + {value: 0x0004, lo: 0x06}, + {value: 0x07d9, lo: 0xb1, hi: 0xb2}, + {value: 0x0901, lo: 0xb3, hi: 0xb3}, + {value: 0x07e1, lo: 0xb4, hi: 0xb4}, + {value: 0x0905, lo: 0xb5, hi: 0xb6}, + {value: 0x07e5, lo: 0xb7, hi: 0xb9}, + {value: 0x090d, lo: 0xba, hi: 0xbf}, // Block 0x52, offset 0x53 - {value: 0x0004, lo: 0x10}, - {value: 0x38e0, lo: 0x90, hi: 0x90}, - {value: 0x38e2, lo: 0x91, hi: 0x93}, - {value: 0x04e1, lo: 0x94, hi: 0x94}, - {value: 0x38ec, lo: 0x95, hi: 0x95}, - {value: 0x38ee, lo: 0x96, hi: 0x96}, - {value: 0x38f0, lo: 0x97, hi: 0x98}, - {value: 0x1443, lo: 0x99, hi: 0x99}, - {value: 0x1440, lo: 0xb0, hi: 0xb0}, - {value: 0x38f8, lo: 0xb1, hi: 0xb3}, - {value: 0x3900, lo: 0xb4, hi: 0xb4}, - {value: 0x149c, lo: 0xb5, hi: 0xb5}, - {value: 0x149e, lo: 0xb6, hi: 0xb6}, - {value: 0x3902, lo: 0xb7, hi: 0xb7}, - {value: 0x3904, lo: 0xb8, hi: 0xb8}, - {value: 0x3906, lo: 0xb9, hi: 0xbe}, - {value: 0x16c3, lo: 0xbf, hi: 0xbf}, + {value: 0x0004, lo: 0x0c}, + {value: 0x082d, lo: 0x80, hi: 0x80}, + {value: 0x07f1, lo: 0x81, hi: 0x83}, + {value: 0x0841, lo: 0x84, hi: 0x84}, + {value: 0x07fd, lo: 0x85, hi: 0x8e}, + {value: 0x088d, lo: 0x8f, hi: 0xa3}, + {value: 0x0889, lo: 0xa4, hi: 0xa4}, + {value: 0x0825, lo: 0xa5, hi: 0xa6}, + {value: 0x0925, lo: 0xa7, hi: 0xad}, + {value: 0x0831, lo: 0xae, hi: 0xae}, + {value: 0x0941, lo: 0xaf, hi: 0xb0}, + {value: 0x0835, lo: 0xb1, hi: 0xb3}, + {value: 0x0845, lo: 0xb4, hi: 0xbf}, // Block 0x53, offset 0x54 - {value: 0x0004, lo: 0x04}, - {value: 0x22a5, lo: 0x80, hi: 0x9c}, - {value: 0x3a38, lo: 0x9d, hi: 0x9f}, - {value: 0x1e04, lo: 0xa0, hi: 0xa0}, - {value: 0x1d38, lo: 0xa1, hi: 0xbe}, + {value: 0x0000, lo: 0x02}, + {value: 0x80e6, lo: 0xaf, hi: 0xaf}, + {value: 0x80e6, lo: 0xbc, hi: 0xbd}, // Block 0x54, offset 0x55 - {value: 0x0004, lo: 0x0c}, - {value: 0x1db0, lo: 0x82, hi: 0x87}, - {value: 0x1dc8, lo: 0x8a, hi: 0x8f}, - {value: 0x1de0, lo: 0x92, hi: 0x97}, - {value: 0x1df8, lo: 0x9a, hi: 0x9c}, - {value: 0x3a44, lo: 0xa0, hi: 0xa0}, - {value: 0x3a47, lo: 0xa1, hi: 0xa1}, - {value: 0x3a4a, lo: 0xa2, hi: 0xa2}, - {value: 0x0009, lo: 0xa3, hi: 0xa3}, - {value: 0x3a4d, lo: 0xa4, hi: 0xa4}, - {value: 0x3a50, lo: 0xa5, hi: 0xa5}, - {value: 0x3a53, lo: 0xa6, hi: 0xa6}, - {value: 0x3a57, lo: 0xa8, hi: 0xae}, + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0xb0, hi: 0xb1}, // Block 0x55, offset 0x56 - {value: 0x0000, lo: 0x03}, - {value: 0x3a73, lo: 0x9a, hi: 0x9a}, - {value: 0x3a7c, lo: 0x9c, hi: 0x9c}, - {value: 0x3a85, lo: 0xab, hi: 0xab}, + {value: 0x0000, lo: 0x01}, + {value: 0x1b69, lo: 0xb0, hi: 0xb0}, // Block 0x56, offset 0x57 - {value: 0x000d, lo: 0x03}, - {value: 0x3a8e, lo: 0x9e, hi: 0x9e}, - {value: 0x3a97, lo: 0x9f, hi: 0x9f}, - {value: 0x3aa0, lo: 0xa0, hi: 0xa4}, + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x86, hi: 0x86}, // Block 0x57, offset 0x58 - {value: 0x0009, lo: 0x03}, - {value: 0x3ae1, lo: 0xbb, hi: 0xbd}, - {value: 0x3b00, lo: 0xbe, hi: 0xbe}, - {value: 0x3b0d, lo: 0xbf, hi: 0xbf}, + {value: 0x0000, lo: 0x02}, + {value: 0x8009, lo: 0x84, hi: 0x84}, + {value: 0x80e6, lo: 0xa0, hi: 0xb1}, // Block 0x58, offset 0x59 {value: 0x0000, lo: 0x01}, - {value: 0x3b1a, lo: 0x80, hi: 0x80}, + {value: 0x80dc, lo: 0xab, hi: 0xad}, // Block 0x59, offset 0x5a - {value: 0x0003, lo: 0x0e}, - {value: 0x14c8, lo: 0x80, hi: 0x80}, - {value: 0x092b, lo: 0x81, hi: 0x81}, - {value: 0x17f6, lo: 0x82, hi: 0x82}, - {value: 0x092d, lo: 0x83, hi: 0x83}, - {value: 0x092f, lo: 0x84, hi: 0x84}, - {value: 0x155f, lo: 0x85, hi: 0x85}, - {value: 0x0931, lo: 0x86, hi: 0x86}, - {value: 0x1570, lo: 0x87, hi: 0x87}, - {value: 0x17f8, lo: 0x88, hi: 0x88}, - {value: 0x14d4, lo: 0x89, hi: 0x89}, - {value: 0x3c2c, lo: 0x8a, hi: 0x8a}, - {value: 0x293d, lo: 0x8b, hi: 0x8b}, - {value: 0x3c2f, lo: 0x8c, hi: 0x8e}, - {value: 0x3c39, lo: 0x8f, hi: 0x8f}, + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x93, hi: 0x93}, // Block 0x5a, offset 0x5b {value: 0x0000, lo: 0x01}, - {value: 0x3c3c, lo: 0x90, hi: 0x90}, + {value: 0x8007, lo: 0xb3, hi: 0xb3}, // Block 0x5b, offset 0x5c - {value: 0x000a, lo: 0x03}, - {value: 0x3cc1, lo: 0x80, hi: 0x88}, - {value: 0x3d1b, lo: 0x90, hi: 0x90}, - {value: 0x3d1f, lo: 0x91, hi: 0x91}, + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0x80, hi: 0x80}, // Block 0x5c, offset 0x5d - {value: 0x0004, lo: 0x0d}, - {value: 0x4463, lo: 0x80, hi: 0x81}, - {value: 0x446c, lo: 0x82, hi: 0x89}, - {value: 0x30a2, lo: 0x8a, hi: 0x8a}, - {value: 0x448d, lo: 0x8b, hi: 0x90}, - {value: 0x44a6, lo: 0x91, hi: 0x92}, - {value: 0x44af, lo: 0x93, hi: 0x93}, - {value: 0x44b4, lo: 0x94, hi: 0x94}, - {value: 0x1b42, lo: 0x95, hi: 0x95}, - {value: 0x44b9, lo: 0x96, hi: 0x96}, - {value: 0x1b52, lo: 0x97, hi: 0x97}, - {value: 0x44bd, lo: 0x98, hi: 0x9b}, - {value: 0x1b66, lo: 0x9c, hi: 0x9c}, - {value: 0x44cd, lo: 0x9d, hi: 0x9d}, + {value: 0x0000, lo: 0x05}, + {value: 0x80e6, lo: 0xb0, hi: 0xb0}, + {value: 0x80e6, lo: 0xb2, hi: 0xb3}, + {value: 0x80dc, lo: 0xb4, hi: 0xb4}, + {value: 0x80e6, lo: 0xb7, hi: 0xb8}, + {value: 0x80e6, lo: 0xbe, hi: 0xbf}, + // Block 0x5d, offset 0x5e + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x81, hi: 0x81}, + // Block 0x5e, offset 0x5f + {value: 0x0000, lo: 0x01}, + {value: 0x8009, lo: 0xad, hi: 0xad}, + // Block 0x5f, offset 0x60 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x61 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x80, hi: 0xa3}, + // Block 0x61, offset 0x62 + {value: 0x0002, lo: 0x01}, + {value: 0x00d1, lo: 0x81, hi: 0xbf}, + // Block 0x62, offset 0x63 + {value: 0x0004, lo: 0x0e}, + {value: 0x088d, lo: 0x82, hi: 0x87}, + {value: 0x08a5, lo: 0x8a, hi: 0x8f}, + {value: 0x08bd, lo: 0x92, hi: 0x97}, + {value: 0x08d5, lo: 0x9a, hi: 0x9c}, + {value: 0x0382, lo: 0xa0, hi: 0xa0}, + {value: 0x0385, lo: 0xa1, hi: 0xa1}, + {value: 0x038e, lo: 0xa2, hi: 0xa2}, + {value: 0x4150, lo: 0xa3, hi: 0xa3}, + {value: 0x038b, lo: 0xa4, hi: 0xa4}, + {value: 0x0388, lo: 0xa5, hi: 0xa5}, + {value: 0x0985, lo: 0xa6, hi: 0xa6}, + {value: 0x09a9, lo: 0xa8, hi: 0xa8}, + {value: 0x0989, lo: 0xa9, hi: 0xac}, + {value: 0x09ad, lo: 0xad, hi: 0xae}, + // Block 0x63, offset 0x64 + {value: 0x0000, lo: 0x01}, + {value: 0x80dc, lo: 0xbd, hi: 0xbd}, + // Block 0x64, offset 0x65 + {value: 0x00db, lo: 0x05}, + {value: 0x80dc, lo: 0x8d, hi: 0x8d}, + {value: 0x80e6, lo: 0x8f, hi: 0x8f}, + {value: 0x80e6, lo: 0xb8, hi: 0xb8}, + {value: 0x8001, lo: 0xb9, hi: 0xba}, + {value: 0x8009, lo: 0xbf, hi: 0xbf}, + // Block 0x65, offset 0x66 + {value: 0x05fe, lo: 0x07}, + {value: 0x8800, lo: 0x99, hi: 0x99}, + {value: 0x411d, lo: 0x9a, hi: 0x9a}, + {value: 0x8800, lo: 0x9b, hi: 0x9b}, + {value: 0x4127, lo: 0x9c, hi: 0x9c}, + {value: 0x8800, lo: 0xa5, hi: 0xa5}, + {value: 0x4131, lo: 0xab, hi: 0xab}, + {value: 0x8009, lo: 0xb9, hi: 0xba}, + // Block 0x66, offset 0x67 + {value: 0x0000, lo: 0x0c}, + {value: 0x44e2, lo: 0x9e, hi: 0x9e}, + {value: 0x44ec, lo: 0x9f, hi: 0x9f}, + {value: 0x4555, lo: 0xa0, hi: 0xa0}, + {value: 0x4563, lo: 0xa1, hi: 0xa1}, + {value: 0x4571, lo: 0xa2, hi: 0xa2}, + {value: 0x457f, lo: 0xa3, hi: 0xa3}, + {value: 0x458d, lo: 0xa4, hi: 0xa4}, + {value: 0x80d8, lo: 0xa5, hi: 0xa6}, + {value: 0x8001, lo: 0xa7, hi: 0xa9}, + {value: 0x80e2, lo: 0xad, hi: 0xad}, + {value: 0x80d8, lo: 0xae, hi: 0xb2}, + {value: 0x80dc, lo: 0xbb, hi: 0xbf}, + // Block 0x67, offset 0x68 + {value: 0x0000, lo: 0x09}, + {value: 0x80dc, lo: 0x80, hi: 0x82}, + {value: 0x80e6, lo: 0x85, hi: 0x89}, + {value: 0x80dc, lo: 0x8a, hi: 0x8b}, + {value: 0x80e6, lo: 0xaa, hi: 0xad}, + {value: 0x44f6, lo: 0xbb, hi: 0xbb}, + {value: 0x4500, lo: 0xbc, hi: 0xbc}, + {value: 0x459b, lo: 0xbd, hi: 0xbd}, + {value: 0x45b7, lo: 0xbe, hi: 0xbe}, + {value: 0x45a9, lo: 0xbf, hi: 0xbf}, + // Block 0x68, offset 0x69 + {value: 0x0000, lo: 0x01}, + {value: 0x45c5, lo: 0x80, hi: 0x80}, + // Block 0x69, offset 0x6a + {value: 0x0000, lo: 0x01}, + {value: 0x80e6, lo: 0x82, hi: 0x84}, + // Block 0x6a, offset 0x6b + {value: 0x0002, lo: 0x03}, + {value: 0x0111, lo: 0x80, hi: 0x99}, + {value: 0x0151, lo: 0x9a, hi: 0xb3}, + {value: 0x0111, lo: 0xb4, hi: 0xbf}, + // Block 0x6b, offset 0x6c + {value: 0x0002, lo: 0x04}, + {value: 0x0129, lo: 0x80, hi: 0x8d}, + {value: 0x0151, lo: 0x8e, hi: 0x94}, + {value: 0x0161, lo: 0x96, hi: 0xa7}, + {value: 0x0111, lo: 0xa8, hi: 0xbf}, + // Block 0x6c, offset 0x6d + {value: 0x0002, lo: 0x0b}, + {value: 0x0141, lo: 0x80, hi: 0x81}, + {value: 0x0151, lo: 0x82, hi: 0x9b}, + {value: 0x0111, lo: 0x9c, hi: 0x9c}, + {value: 0x0115, lo: 0x9e, hi: 0x9f}, + {value: 0x011d, lo: 0xa2, hi: 0xa2}, + {value: 0x0123, lo: 0xa5, hi: 0xa6}, + {value: 0x012b, lo: 0xa9, hi: 0xac}, + {value: 0x0135, lo: 0xae, hi: 0xb5}, + {value: 0x0151, lo: 0xb6, hi: 0xb9}, + {value: 0x015b, lo: 0xbb, hi: 0xbb}, + {value: 0x015f, lo: 0xbd, hi: 0xbf}, + // Block 0x6d, offset 0x6e + {value: 0x0002, lo: 0x04}, + {value: 0x0165, lo: 0x80, hi: 0x83}, + {value: 0x016f, lo: 0x85, hi: 0x8f}, + {value: 0x0111, lo: 0x90, hi: 0xa9}, + {value: 0x0151, lo: 0xaa, hi: 0xbf}, + // Block 0x6e, offset 0x6f + {value: 0x0002, lo: 0x08}, + {value: 0x017d, lo: 0x80, hi: 0x83}, + {value: 0x0111, lo: 0x84, hi: 0x85}, + {value: 0x0117, lo: 0x87, hi: 0x8a}, + {value: 0x0123, lo: 0x8d, hi: 0x94}, + {value: 0x0135, lo: 0x96, hi: 0x9c}, + {value: 0x0151, lo: 0x9e, hi: 0xb7}, + {value: 0x0111, lo: 0xb8, hi: 0xb9}, + {value: 0x0117, lo: 0xbb, hi: 0xbe}, + // Block 0x6f, offset 0x70 + {value: 0x0002, lo: 0x05}, + {value: 0x0121, lo: 0x80, hi: 0x84}, + {value: 0x012d, lo: 0x86, hi: 0x86}, + {value: 0x0135, lo: 0x8a, hi: 0x90}, + {value: 0x0151, lo: 0x92, hi: 0xab}, + {value: 0x0111, lo: 0xac, hi: 0xbf}, + // Block 0x70, offset 0x71 + {value: 0x0002, lo: 0x04}, + {value: 0x0139, lo: 0x80, hi: 0x85}, + {value: 0x0151, lo: 0x86, hi: 0x9f}, + {value: 0x0111, lo: 0xa0, hi: 0xb9}, + {value: 0x0151, lo: 0xba, hi: 0xbf}, + // Block 0x71, offset 0x72 + {value: 0x0002, lo: 0x03}, + {value: 0x015d, lo: 0x80, hi: 0x93}, + {value: 0x0111, lo: 0x94, hi: 0xad}, + {value: 0x0151, lo: 0xae, hi: 0xbf}, + // Block 0x72, offset 0x73 + {value: 0x0002, lo: 0x04}, + {value: 0x0175, lo: 0x80, hi: 0x87}, + {value: 0x0111, lo: 0x88, hi: 0xa1}, + {value: 0x0151, lo: 0xa2, hi: 0xbb}, + {value: 0x0111, lo: 0xbc, hi: 0xbf}, + // Block 0x73, offset 0x74 + {value: 0x0002, lo: 0x03}, + {value: 0x0119, lo: 0x80, hi: 0x95}, + {value: 0x0151, lo: 0x96, hi: 0xaf}, + {value: 0x0111, lo: 0xb0, hi: 0xbf}, + // Block 0x74, offset 0x75 + {value: 0x0003, lo: 0x0f}, + {value: 0x0475, lo: 0x80, hi: 0x80}, + {value: 0x099d, lo: 0x81, hi: 0x81}, + {value: 0x0478, lo: 0x82, hi: 0x9a}, + {value: 0x0999, lo: 0x9b, hi: 0x9b}, + {value: 0x0484, lo: 0x9c, hi: 0x9c}, + {value: 0x048d, lo: 0x9d, hi: 0x9d}, + {value: 0x0493, lo: 0x9e, hi: 0x9e}, + {value: 0x04b7, lo: 0x9f, hi: 0x9f}, + {value: 0x04a8, lo: 0xa0, hi: 0xa0}, + {value: 0x04a5, lo: 0xa1, hi: 0xa1}, + {value: 0x0430, lo: 0xa2, hi: 0xb2}, + {value: 0x0445, lo: 0xb3, hi: 0xb3}, + {value: 0x0463, lo: 0xb4, hi: 0xba}, + {value: 0x099d, lo: 0xbb, hi: 0xbb}, + {value: 0x0478, lo: 0xbc, hi: 0xbf}, + // Block 0x75, offset 0x76 + {value: 0x0003, lo: 0x0d}, + {value: 0x0484, lo: 0x80, hi: 0x94}, + {value: 0x0999, lo: 0x95, hi: 0x95}, + {value: 0x0484, lo: 0x96, hi: 0x96}, + {value: 0x048d, lo: 0x97, hi: 0x97}, + {value: 0x0493, lo: 0x98, hi: 0x98}, + {value: 0x04b7, lo: 0x99, hi: 0x99}, + {value: 0x04a8, lo: 0x9a, hi: 0x9a}, + {value: 0x04a5, lo: 0x9b, hi: 0x9b}, + {value: 0x0430, lo: 0x9c, hi: 0xac}, + {value: 0x0445, lo: 0xad, hi: 0xad}, + {value: 0x0463, lo: 0xae, hi: 0xb4}, + {value: 0x099d, lo: 0xb5, hi: 0xb5}, + {value: 0x0478, lo: 0xb6, hi: 0xbf}, + // Block 0x76, offset 0x77 + {value: 0x0003, lo: 0x0d}, + {value: 0x0496, lo: 0x80, hi: 0x8e}, + {value: 0x0999, lo: 0x8f, hi: 0x8f}, + {value: 0x0484, lo: 0x90, hi: 0x90}, + {value: 0x048d, lo: 0x91, hi: 0x91}, + {value: 0x0493, lo: 0x92, hi: 0x92}, + {value: 0x04b7, lo: 0x93, hi: 0x93}, + {value: 0x04a8, lo: 0x94, hi: 0x94}, + {value: 0x04a5, lo: 0x95, hi: 0x95}, + {value: 0x0430, lo: 0x96, hi: 0xa6}, + {value: 0x0445, lo: 0xa7, hi: 0xa7}, + {value: 0x0463, lo: 0xa8, hi: 0xae}, + {value: 0x099d, lo: 0xaf, hi: 0xaf}, + {value: 0x0478, lo: 0xb0, hi: 0xbf}, + // Block 0x77, offset 0x78 + {value: 0x0003, lo: 0x0d}, + {value: 0x04a8, lo: 0x80, hi: 0x88}, + {value: 0x0999, lo: 0x89, hi: 0x89}, + {value: 0x0484, lo: 0x8a, hi: 0x8a}, + {value: 0x048d, lo: 0x8b, hi: 0x8b}, + {value: 0x0493, lo: 0x8c, hi: 0x8c}, + {value: 0x04b7, lo: 0x8d, hi: 0x8d}, + {value: 0x04a8, lo: 0x8e, hi: 0x8e}, + {value: 0x04a5, lo: 0x8f, hi: 0x8f}, + {value: 0x0430, lo: 0x90, hi: 0xa0}, + {value: 0x0445, lo: 0xa1, hi: 0xa1}, + {value: 0x0463, lo: 0xa2, hi: 0xa8}, + {value: 0x099d, lo: 0xa9, hi: 0xa9}, + {value: 0x0478, lo: 0xaa, hi: 0xbf}, + // Block 0x78, offset 0x79 + {value: 0x0002, lo: 0x07}, + {value: 0x0131, lo: 0x80, hi: 0x89}, + {value: 0x0271, lo: 0x8a, hi: 0x8a}, + {value: 0x029b, lo: 0x8b, hi: 0x8b}, + {value: 0x02b6, lo: 0x8c, hi: 0x8c}, + {value: 0x02bc, lo: 0x8d, hi: 0x8d}, + {value: 0x0711, lo: 0x8e, hi: 0x8e}, + {value: 0x02c8, lo: 0x8f, hi: 0x8f}, + // Block 0x79, offset 0x7a + {value: 0x0000, lo: 0x01}, + {value: 0x025f, lo: 0x90, hi: 0x90}, + // Block 0x7a, offset 0x7b + {value: 0x0028, lo: 0x09}, + {value: 0x29de, lo: 0x80, hi: 0x80}, + {value: 0x29a2, lo: 0x81, hi: 0x81}, + {value: 0x29ac, lo: 0x82, hi: 0x82}, + {value: 0x29c0, lo: 0x83, hi: 0x84}, + {value: 0x29ca, lo: 0x85, hi: 0x86}, + {value: 0x29b6, lo: 0x87, hi: 0x87}, + {value: 0x29d4, lo: 0x88, hi: 0x88}, + {value: 0x10ad, lo: 0x90, hi: 0x90}, + {value: 0x0e25, lo: 0x91, hi: 0x91}, } -// nfkcDecompLookup: 960 bytes +// nfkcLookup: 1152 bytes // Block 0 is the null block. -var nfkcDecompLookup = [960]uint8{ +var nfkcLookup = [1152]uint8{ // Block 0x0, offset 0x0 // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x0c2: 0x42, 0x0c3: 0x43, 0x0c4: 0x44, 0x0c5: 0x45, 0x0c6: 0x46, 0x0c7: 0x03, - 0x0c8: 0x47, 0x0ca: 0x48, 0x0cb: 0x49, 0x0cd: 0x4a, 0x0ce: 0x4b, 0x0cf: 0x4c, - 0x0d0: 0x4d, 0x0d1: 0x4e, 0x0d3: 0x4f, 0x0d6: 0x50, - 0x0d8: 0x51, 0x0d9: 0x52, 0x0db: 0x53, + 0x0c2: 0x57, 0x0c3: 0x03, 0x0c4: 0x04, 0x0c5: 0x05, 0x0c6: 0x58, 0x0c7: 0x06, + 0x0c8: 0x07, 0x0ca: 0x59, 0x0cb: 0x5a, 0x0cc: 0x08, 0x0cd: 0x09, 0x0ce: 0x0a, 0x0cf: 0x0b, + 0x0d0: 0x0c, 0x0d1: 0x5b, 0x0d2: 0x5c, 0x0d3: 0x0d, 0x0d6: 0x0e, 0x0d7: 0x5d, + 0x0d8: 0x5e, 0x0d9: 0x0f, 0x0db: 0x5f, 0x0dc: 0x60, 0x0dd: 0x61, 0x0df: 0x62, 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, - 0x0ea: 0x08, 0x0ef: 0x09, - 0x0f0: 0x0e, + 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, + 0x0f0: 0x11, // Block 0x4, offset 0x100 - 0x124: 0x54, 0x125: 0x55, 0x127: 0x56, - 0x128: 0x57, 0x129: 0x58, 0x12d: 0x59, 0x12e: 0x5a, 0x12f: 0x5b, - 0x131: 0x5c, 0x133: 0x5d, 0x135: 0x5e, 0x137: 0x5f, - 0x138: 0x60, 0x13a: 0x61, 0x13b: 0x62, 0x13c: 0x63, 0x13d: 0x64, 0x13e: 0x65, + 0x120: 0x63, 0x121: 0x64, 0x124: 0x65, 0x125: 0x66, 0x126: 0x67, 0x127: 0x68, + 0x128: 0x69, 0x129: 0x6a, 0x12a: 0x6b, 0x12b: 0x6c, 0x12c: 0x67, 0x12d: 0x6d, 0x12e: 0x6e, 0x12f: 0x6f, + 0x131: 0x70, 0x132: 0x71, 0x133: 0x72, 0x134: 0x73, 0x135: 0x74, 0x137: 0x75, + 0x138: 0x76, 0x139: 0x77, 0x13a: 0x78, 0x13b: 0x79, 0x13c: 0x7a, 0x13d: 0x7b, 0x13e: 0x7c, 0x13f: 0x7d, // Block 0x5, offset 0x140 - 0x140: 0x66, 0x143: 0x67, - 0x16c: 0x68, 0x16d: 0x69, - 0x174: 0x6a, 0x175: 0x04, 0x176: 0x6b, - 0x178: 0x6c, 0x179: 0x05, 0x17a: 0x06, 0x17b: 0x07, 0x17c: 0x08, 0x17d: 0x09, 0x17e: 0x0a, 0x17f: 0x0b, + 0x140: 0x7e, 0x142: 0x7f, 0x143: 0x80, 0x144: 0x81, 0x145: 0x82, 0x146: 0x83, 0x147: 0x84, + 0x14d: 0x85, + 0x15c: 0x86, 0x15f: 0x87, + 0x162: 0x88, 0x164: 0x89, + 0x168: 0x8a, 0x169: 0x8b, 0x16c: 0x10, 0x16d: 0x8c, 0x16e: 0x8d, 0x16f: 0x8e, + 0x170: 0x8f, 0x173: 0x90, 0x174: 0x91, 0x175: 0x11, 0x176: 0x12, 0x177: 0x92, + 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a, // Block 0x6, offset 0x180 - 0x180: 0x6d, 0x181: 0x6e, 0x182: 0x0c, 0x184: 0x0d, 0x185: 0x0e, 0x186: 0x6f, 0x187: 0x70, - 0x188: 0x71, 0x189: 0x72, 0x18a: 0x73, 0x18b: 0x74, 0x18c: 0x75, - 0x191: 0x0f, 0x192: 0x10, 0x193: 0x11, - 0x1a8: 0x76, 0x1a9: 0x77, 0x1ab: 0x78, - 0x1b1: 0x79, 0x1b5: 0x7a, - 0x1ba: 0x7b, 0x1bb: 0x7c, 0x1bc: 0x7d, 0x1bd: 0x7e, 0x1be: 0x7f, 0x1bf: 0x80, + 0x180: 0x93, 0x181: 0x94, 0x182: 0x95, 0x183: 0x96, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x97, 0x187: 0x98, + 0x188: 0x99, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0x9a, 0x18c: 0x9b, + 0x191: 0x1f, 0x192: 0x20, 0x193: 0x9c, + 0x1a8: 0x9d, 0x1a9: 0x9e, 0x1ab: 0x9f, + 0x1b1: 0xa0, 0x1b3: 0xa1, 0x1b5: 0xa2, 0x1b7: 0xa3, + 0x1ba: 0xa4, 0x1bb: 0xa5, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xa6, // Block 0x7, offset 0x1c0 - 0x1c0: 0x81, 0x1c1: 0x12, 0x1c2: 0x82, 0x1c3: 0x83, 0x1c4: 0x84, 0x1c5: 0x85, 0x1c6: 0x86, - 0x1c8: 0x13, 0x1c9: 0x14, 0x1ca: 0x15, 0x1cb: 0x87, 0x1cc: 0x16, 0x1cd: 0x17, 0x1ce: 0x18, 0x1cf: 0x19, + 0x1c0: 0xa7, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xa8, 0x1c5: 0xa9, 0x1c6: 0x27, + 0x1c8: 0x28, 0x1c9: 0x29, 0x1ca: 0x2a, 0x1cb: 0x2b, 0x1cc: 0x2c, 0x1cd: 0x2d, 0x1ce: 0x2e, 0x1cf: 0x2f, // Block 0x8, offset 0x200 - 0x21d: 0x88, + 0x219: 0xaa, 0x21b: 0xab, 0x21d: 0xac, + 0x220: 0xad, 0x223: 0xae, 0x224: 0xaf, 0x225: 0xb0, 0x226: 0xb1, 0x227: 0xb2, + 0x22a: 0xb3, 0x22b: 0xb4, 0x22f: 0xb5, + 0x230: 0xb6, 0x231: 0xb6, 0x232: 0xb6, 0x233: 0xb6, 0x234: 0xb6, 0x235: 0xb6, 0x236: 0xb6, 0x237: 0xb6, + 0x238: 0xb6, 0x239: 0xb6, 0x23a: 0xb6, 0x23b: 0xb6, 0x23c: 0xb6, 0x23d: 0xb6, 0x23e: 0xb6, 0x23f: 0xb6, // Block 0x9, offset 0x240 - 0x264: 0x89, 0x265: 0x8a, 0x266: 0x8b, 0x267: 0x8c, - 0x268: 0x8d, 0x269: 0x8e, 0x26a: 0x1a, 0x26b: 0x1b, 0x26c: 0x1c, 0x26d: 0x1d, 0x26e: 0x1e, 0x26f: 0x1f, - 0x270: 0x8f, 0x271: 0x20, 0x272: 0x21, 0x273: 0x22, 0x274: 0x90, 0x275: 0x91, 0x276: 0x92, 0x277: 0x93, - 0x278: 0x94, 0x279: 0x23, 0x27a: 0x24, 0x27b: 0x25, 0x27c: 0x26, 0x27d: 0x27, 0x27e: 0x95, 0x27f: 0x96, + 0x240: 0xb6, 0x241: 0xb6, 0x242: 0xb6, 0x243: 0xb6, 0x244: 0xb6, 0x245: 0xb6, 0x246: 0xb6, 0x247: 0xb6, + 0x248: 0xb6, 0x249: 0xb6, 0x24a: 0xb6, 0x24b: 0xb6, 0x24c: 0xb6, 0x24d: 0xb6, 0x24e: 0xb6, 0x24f: 0xb6, + 0x250: 0xb6, 0x251: 0xb6, 0x252: 0xb6, 0x253: 0xb6, 0x254: 0xb6, 0x255: 0xb6, 0x256: 0xb6, 0x257: 0xb6, + 0x258: 0xb6, 0x259: 0xb6, 0x25a: 0xb6, 0x25b: 0xb6, 0x25c: 0xb6, 0x25d: 0xb6, 0x25e: 0xb6, 0x25f: 0xb6, + 0x260: 0xb6, 0x261: 0xb6, 0x262: 0xb6, 0x263: 0xb6, 0x264: 0xb6, 0x265: 0xb6, 0x266: 0xb6, 0x267: 0xb6, + 0x268: 0xb6, 0x269: 0xb6, 0x26a: 0xb6, 0x26b: 0xb6, 0x26c: 0xb6, 0x26d: 0xb6, 0x26e: 0xb6, 0x26f: 0xb6, + 0x270: 0xb6, 0x271: 0xb6, 0x272: 0xb6, 0x273: 0xb6, 0x274: 0xb6, 0x275: 0xb6, 0x276: 0xb6, 0x277: 0xb6, + 0x278: 0xb6, 0x279: 0xb6, 0x27a: 0xb6, 0x27b: 0xb6, 0x27c: 0xb6, 0x27d: 0xb6, 0x27e: 0xb6, 0x27f: 0xb6, // Block 0xa, offset 0x280 - 0x282: 0x97, + 0x280: 0xb6, 0x281: 0xb6, 0x282: 0xb6, 0x283: 0xb6, 0x284: 0xb6, 0x285: 0xb6, 0x286: 0xb6, 0x287: 0xb6, + 0x288: 0xb6, 0x289: 0xb6, 0x28a: 0xb6, 0x28b: 0xb6, 0x28c: 0xb6, 0x28d: 0xb6, 0x28e: 0xb6, 0x28f: 0xb6, + 0x290: 0xb6, 0x291: 0xb6, 0x292: 0xb6, 0x293: 0xb6, 0x294: 0xb6, 0x295: 0xb6, 0x296: 0xb6, 0x297: 0xb6, + 0x298: 0xb6, 0x299: 0xb6, 0x29a: 0xb6, 0x29b: 0xb6, 0x29c: 0xb6, 0x29d: 0xb6, 0x29e: 0xb7, // Block 0xb, offset 0x2c0 - 0x2c5: 0x98, 0x2c6: 0x99, 0x2c7: 0x9a, - 0x2d0: 0x28, 0x2d1: 0x29, 0x2d2: 0x2a, 0x2d3: 0x2b, 0x2d4: 0x2c, 0x2d5: 0x2d, 0x2d6: 0x2e, 0x2d7: 0x2f, - 0x2d8: 0x30, 0x2d9: 0x31, 0x2da: 0x32, 0x2db: 0x33, 0x2dc: 0x34, 0x2dd: 0x35, 0x2de: 0x36, 0x2df: 0x37, + 0x2e4: 0x30, 0x2e5: 0x31, 0x2e6: 0x32, 0x2e7: 0x33, + 0x2e8: 0x34, 0x2e9: 0x35, 0x2ea: 0x36, 0x2eb: 0x37, 0x2ec: 0x38, 0x2ed: 0x39, 0x2ee: 0x3a, 0x2ef: 0x3b, + 0x2f0: 0x3c, 0x2f1: 0x3d, 0x2f2: 0x3e, 0x2f3: 0x3f, 0x2f4: 0x40, 0x2f5: 0x41, 0x2f6: 0x42, 0x2f7: 0x43, + 0x2f8: 0x44, 0x2f9: 0x45, 0x2fa: 0x46, 0x2fb: 0x47, 0x2fc: 0xb8, 0x2fd: 0x48, 0x2fe: 0x49, 0x2ff: 0xb9, // Block 0xc, offset 0x300 - 0x304: 0x38, 0x305: 0x9b, 0x306: 0x9c, - 0x308: 0x39, 0x309: 0x9d, + 0x307: 0xba, + 0x328: 0xbb, // Block 0xd, offset 0x340 - 0x360: 0x3a, 0x361: 0x3b, 0x362: 0x3c, 0x363: 0x3d, 0x364: 0x3e, 0x365: 0x3f, 0x366: 0x40, 0x367: 0x41, - 0x368: 0x9e, + 0x341: 0xad, 0x342: 0xbc, // Block 0xe, offset 0x380 - 0x391: 0x0a, - 0x39d: 0x0b, 0x39f: 0x0c, - 0x3af: 0x0d, + 0x385: 0xbd, 0x386: 0xbe, 0x387: 0xbf, + 0x389: 0xc0, + 0x390: 0xc1, 0x391: 0xc2, 0x392: 0xc3, 0x393: 0xc4, 0x394: 0xc5, 0x395: 0xc6, 0x396: 0xc7, 0x397: 0xc8, + 0x398: 0xc9, 0x399: 0xca, 0x39a: 0x4a, 0x39b: 0xcb, 0x39c: 0xcc, 0x39d: 0xcd, 0x39e: 0xce, 0x39f: 0x4b, + // Block 0xf, offset 0x3c0 + 0x3c4: 0x4c, 0x3c5: 0xcf, 0x3c6: 0xd0, + 0x3c8: 0x4d, 0x3c9: 0xd1, + // Block 0x10, offset 0x400 + 0x420: 0x4e, 0x421: 0x4f, 0x422: 0x50, 0x423: 0x51, 0x424: 0x52, 0x425: 0x53, 0x426: 0x54, 0x427: 0x55, + 0x428: 0x56, + // Block 0x11, offset 0x440 + 0x450: 0x0c, 0x451: 0x0d, + 0x45d: 0x0e, 0x45f: 0x0f, + 0x46f: 0x10, } -var nfkcDecompTrie = trie{nfkcDecompLookup[:], nfkcDecompValues[:], nfkcDecompSparseValues[:], nfkcDecompSparseOffset[:], 66} +var nfkcTrie = trie{nfkcLookup[:], nfkcValues[:], nfkcSparseValues[:], nfkcSparseOffset[:], 87} // recompMap: 7448 bytes (entries only) var recompMap = map[uint32]rune{ @@ -5595,1172 +6655,4 @@ var recompMap = map[uint32]rune{ 0x10A510BA: 0x110AB, } -// charInfoValues: 1024 entries, 2048 bytes -// Block 2 is the null block. -var charInfoValues = [1024]uint16{ - // Block 0x0, offset 0x0 - 0x003c: 0x8800, 0x003d: 0x8800, 0x003e: 0x8800, - // Block 0x1, offset 0x40 - 0x0041: 0x8800, 0x0042: 0x8800, 0x0043: 0x8800, 0x0044: 0x8800, 0x0045: 0x8800, - 0x0046: 0x8800, 0x0047: 0x8800, 0x0048: 0x8800, 0x0049: 0x8800, 0x004a: 0x8800, 0x004b: 0x8800, - 0x004c: 0x8800, 0x004d: 0x8800, 0x004e: 0x8800, 0x004f: 0x8800, 0x0050: 0x8800, - 0x0052: 0x8800, 0x0053: 0x8800, 0x0054: 0x8800, 0x0055: 0x8800, 0x0056: 0x8800, 0x0057: 0x8800, - 0x0058: 0x8800, 0x0059: 0x8800, 0x005a: 0x8800, - 0x0061: 0x8800, 0x0062: 0x8800, 0x0063: 0x8800, - 0x0064: 0x8800, 0x0065: 0x8800, 0x0066: 0x8800, 0x0067: 0x8800, 0x0068: 0x8800, 0x0069: 0x8800, - 0x006a: 0x8800, 0x006b: 0x8800, 0x006c: 0x8800, 0x006d: 0x8800, 0x006e: 0x8800, 0x006f: 0x8800, - 0x0070: 0x8800, 0x0072: 0x8800, 0x0073: 0x8800, 0x0074: 0x8800, 0x0075: 0x8800, - 0x0076: 0x8800, 0x0077: 0x8800, 0x0078: 0x8800, 0x0079: 0x8800, 0x007a: 0x8800, - // Block 0x2, offset 0x80 - // Block 0x3, offset 0xc0 - 0x00c0: 0x1100, 0x00c1: 0x1100, 0x00c2: 0x9900, 0x00c3: 0x1100, 0x00c4: 0x9900, 0x00c5: 0x9900, - 0x00c6: 0x8800, 0x00c7: 0x9900, 0x00c8: 0x1100, 0x00c9: 0x1100, 0x00ca: 0x9900, 0x00cb: 0x1100, - 0x00cc: 0x1100, 0x00cd: 0x1100, 0x00ce: 0x1100, 0x00cf: 0x9900, 0x00d1: 0x1100, - 0x00d2: 0x1100, 0x00d3: 0x1100, 0x00d4: 0x9900, 0x00d5: 0x9900, 0x00d6: 0x9900, - 0x00d8: 0x8800, 0x00d9: 0x1100, 0x00da: 0x1100, 0x00db: 0x1100, 0x00dc: 0x9900, 0x00dd: 0x1100, - 0x00e0: 0x1100, 0x00e1: 0x1100, 0x00e2: 0x9900, 0x00e3: 0x1100, - 0x00e4: 0x9900, 0x00e5: 0x9900, 0x00e6: 0x8800, 0x00e7: 0x9900, 0x00e8: 0x1100, 0x00e9: 0x1100, - 0x00ea: 0x9900, 0x00eb: 0x1100, 0x00ec: 0x1100, 0x00ed: 0x1100, 0x00ee: 0x1100, 0x00ef: 0x9900, - 0x00f1: 0x1100, 0x00f2: 0x1100, 0x00f3: 0x1100, 0x00f4: 0x9900, 0x00f5: 0x9900, - 0x00f6: 0x9900, 0x00f8: 0x8800, 0x00f9: 0x1100, 0x00fa: 0x1100, 0x00fb: 0x1100, - 0x00fc: 0x9900, 0x00fd: 0x1100, 0x00ff: 0x1100, - // Block 0x4, offset 0x100 - 0x0100: 0x66e6, 0x0101: 0x66e6, 0x0102: 0x66e6, 0x0103: 0x66e6, 0x0104: 0x66e6, 0x0105: 0x00e6, - 0x0106: 0x66e6, 0x0107: 0x66e6, 0x0108: 0x66e6, 0x0109: 0x66e6, 0x010a: 0x66e6, 0x010b: 0x66e6, - 0x010c: 0x66e6, 0x010d: 0x00e6, 0x010e: 0x00e6, 0x010f: 0x66e6, 0x0110: 0x00e6, 0x0111: 0x66e6, - 0x0112: 0x00e6, 0x0113: 0x66e6, 0x0114: 0x66e6, 0x0115: 0x00e8, 0x0116: 0x00dc, 0x0117: 0x00dc, - 0x0118: 0x00dc, 0x0119: 0x00dc, 0x011a: 0x00e8, 0x011b: 0x66d8, 0x011c: 0x00dc, 0x011d: 0x00dc, - 0x011e: 0x00dc, 0x011f: 0x00dc, 0x0120: 0x00dc, 0x0121: 0x00ca, 0x0122: 0x00ca, 0x0123: 0x66dc, - 0x0124: 0x66dc, 0x0125: 0x66dc, 0x0126: 0x66dc, 0x0127: 0x66ca, 0x0128: 0x66ca, 0x0129: 0x00dc, - 0x012a: 0x00dc, 0x012b: 0x00dc, 0x012c: 0x00dc, 0x012d: 0x66dc, 0x012e: 0x66dc, 0x012f: 0x00dc, - 0x0130: 0x66dc, 0x0131: 0x66dc, 0x0132: 0x00dc, 0x0133: 0x00dc, 0x0134: 0x0001, 0x0135: 0x0001, - 0x0136: 0x0001, 0x0137: 0x0001, 0x0138: 0x6601, 0x0139: 0x00dc, 0x013a: 0x00dc, 0x013b: 0x00dc, - 0x013c: 0x00dc, 0x013d: 0x00e6, 0x013e: 0x00e6, 0x013f: 0x00e6, - // Block 0x5, offset 0x140 - 0x0140: 0x55e6, 0x0141: 0x55e6, 0x0142: 0x66e6, 0x0143: 0x55e6, 0x0144: 0x55e6, 0x0145: 0x66f0, - 0x0146: 0x00e6, 0x0147: 0x00dc, 0x0148: 0x00dc, 0x0149: 0x00dc, 0x014a: 0x00e6, 0x014b: 0x00e6, - 0x014c: 0x00e6, 0x014d: 0x00dc, 0x014e: 0x00dc, 0x0150: 0x00e6, 0x0151: 0x00e6, - 0x0152: 0x00e6, 0x0153: 0x00dc, 0x0154: 0x00dc, 0x0155: 0x00dc, 0x0156: 0x00dc, 0x0157: 0x00e6, - 0x0158: 0x00e8, 0x0159: 0x00dc, 0x015a: 0x00dc, 0x015b: 0x00e6, 0x015c: 0x00e9, 0x015d: 0x00ea, - 0x015e: 0x00ea, 0x015f: 0x00e9, 0x0160: 0x00ea, 0x0161: 0x00ea, 0x0162: 0x00e9, 0x0163: 0x00e6, - 0x0164: 0x00e6, 0x0165: 0x00e6, 0x0166: 0x00e6, 0x0167: 0x00e6, 0x0168: 0x00e6, 0x0169: 0x00e6, - 0x016a: 0x00e6, 0x016b: 0x00e6, 0x016c: 0x00e6, 0x016d: 0x00e6, 0x016e: 0x00e6, 0x016f: 0x00e6, - 0x0174: 0x5500, - 0x017a: 0x5000, - 0x017e: 0x5500, - // Block 0x6, offset 0x180 - 0x0184: 0x5000, 0x0185: 0x5100, - 0x0186: 0x1100, 0x0187: 0x5500, 0x0188: 0x1100, 0x0189: 0x1100, 0x018a: 0x1100, - 0x018c: 0x1100, 0x018e: 0x1100, 0x018f: 0x1100, 0x0190: 0x1100, 0x0191: 0x8800, - 0x0195: 0x8800, 0x0197: 0x8800, - 0x0199: 0x8800, - 0x019f: 0x8800, 0x01a1: 0x8800, - 0x01a5: 0x8800, 0x01a9: 0x8800, - 0x01aa: 0x1100, 0x01ab: 0x1100, 0x01ac: 0x9900, 0x01ad: 0x1100, 0x01ae: 0x9900, 0x01af: 0x1100, - 0x01b0: 0x1100, 0x01b1: 0x8800, 0x01b5: 0x8800, - 0x01b7: 0x8800, 0x01b9: 0x8800, - 0x01bf: 0x8800, - // Block 0x7, offset 0x1c0 - 0x01c0: 0x1100, 0x01c1: 0x1100, 0x01c3: 0x1100, - 0x01c6: 0x8800, 0x01c7: 0x1100, - 0x01cc: 0x1100, 0x01cd: 0x1100, 0x01ce: 0x1100, 0x01d0: 0x8800, - 0x01d3: 0x8800, 0x01d5: 0x8800, 0x01d6: 0x8800, 0x01d7: 0x8800, - 0x01d8: 0x8800, 0x01d9: 0x1100, 0x01da: 0x8800, - 0x01de: 0x8800, 0x01e3: 0x8800, - 0x01e7: 0x8800, - 0x01eb: 0x8800, 0x01ed: 0x8800, - 0x01f0: 0x8800, 0x01f3: 0x8800, 0x01f5: 0x8800, - 0x01f6: 0x8800, 0x01f7: 0x8800, 0x01f8: 0x8800, 0x01f9: 0x1100, 0x01fa: 0x8800, - 0x01fe: 0x8800, - // Block 0x8, offset 0x200 - 0x0207: 0x5000, - 0x0211: 0x00dc, - 0x0212: 0x00e6, 0x0213: 0x00e6, 0x0214: 0x00e6, 0x0215: 0x00e6, 0x0216: 0x00dc, 0x0217: 0x00e6, - 0x0218: 0x00e6, 0x0219: 0x00e6, 0x021a: 0x00de, 0x021b: 0x00dc, 0x021c: 0x00e6, 0x021d: 0x00e6, - 0x021e: 0x00e6, 0x021f: 0x00e6, 0x0220: 0x00e6, 0x0221: 0x00e6, 0x0222: 0x00dc, 0x0223: 0x00dc, - 0x0224: 0x00dc, 0x0225: 0x00dc, 0x0226: 0x00dc, 0x0227: 0x00dc, 0x0228: 0x00e6, 0x0229: 0x00e6, - 0x022a: 0x00dc, 0x022b: 0x00e6, 0x022c: 0x00e6, 0x022d: 0x00de, 0x022e: 0x00e4, 0x022f: 0x00e6, - 0x0230: 0x000a, 0x0231: 0x000b, 0x0232: 0x000c, 0x0233: 0x000d, 0x0234: 0x000e, 0x0235: 0x000f, - 0x0236: 0x0010, 0x0237: 0x0011, 0x0238: 0x0012, 0x0239: 0x0013, 0x023a: 0x0013, 0x023b: 0x0014, - 0x023c: 0x0015, 0x023d: 0x0016, 0x023f: 0x0017, - // Block 0x9, offset 0x240 - 0x0248: 0x8800, 0x024a: 0x8800, 0x024b: 0x001b, - 0x024c: 0x001c, 0x024d: 0x001d, 0x024e: 0x001e, 0x024f: 0x001f, 0x0250: 0x0020, 0x0251: 0x0021, - 0x0252: 0x0022, 0x0253: 0x66e6, 0x0254: 0x66e6, 0x0255: 0x66dc, 0x0256: 0x00dc, 0x0257: 0x00e6, - 0x0258: 0x00e6, 0x0259: 0x00e6, 0x025a: 0x00e6, 0x025b: 0x00e6, 0x025c: 0x00dc, 0x025d: 0x00e6, - 0x025e: 0x00e6, 0x025f: 0x00dc, - 0x0270: 0x0023, 0x0275: 0x5000, - 0x0276: 0x5000, 0x0277: 0x5000, 0x0278: 0x5000, - // Block 0xa, offset 0x280 - 0x0280: 0x9900, 0x0281: 0x9900, 0x0282: 0x1100, 0x0283: 0x1100, 0x0284: 0x1100, 0x0285: 0x1100, - 0x0288: 0x9900, 0x0289: 0x9900, 0x028a: 0x1100, 0x028b: 0x1100, - 0x028c: 0x1100, 0x028d: 0x1100, 0x0290: 0x9900, 0x0291: 0x9900, - 0x0292: 0x1100, 0x0293: 0x1100, 0x0294: 0x1100, 0x0295: 0x1100, 0x0296: 0x1100, 0x0297: 0x1100, - 0x0299: 0x9900, 0x029b: 0x1100, 0x029d: 0x1100, - 0x029f: 0x1100, 0x02a0: 0x9900, 0x02a1: 0x9900, 0x02a2: 0x9900, 0x02a3: 0x9900, - 0x02a4: 0x9900, 0x02a5: 0x9900, 0x02a6: 0x9900, 0x02a7: 0x9900, 0x02a8: 0x9900, 0x02a9: 0x9900, - 0x02aa: 0x9900, 0x02ab: 0x9900, 0x02ac: 0x9900, 0x02ad: 0x9900, 0x02ae: 0x9900, 0x02af: 0x9900, - 0x02b0: 0x9900, 0x02b1: 0x5500, 0x02b2: 0x1100, 0x02b3: 0x5500, 0x02b4: 0x9900, 0x02b5: 0x5500, - 0x02b6: 0x1100, 0x02b7: 0x5500, 0x02b8: 0x1100, 0x02b9: 0x5500, 0x02ba: 0x1100, 0x02bb: 0x5500, - 0x02bc: 0x9900, 0x02bd: 0x5500, - // Block 0xb, offset 0x2c0 - 0x02c0: 0x5000, 0x02c1: 0x5100, 0x02c2: 0x1100, 0x02c3: 0x1100, 0x02c4: 0x1100, - 0x02c6: 0x9900, 0x02c7: 0x1100, 0x02c8: 0x1100, 0x02c9: 0x5500, 0x02ca: 0x1100, 0x02cb: 0x5500, - 0x02cc: 0x1100, 0x02cd: 0x5100, 0x02ce: 0x5100, 0x02cf: 0x5100, 0x02d0: 0x1100, 0x02d1: 0x1100, - 0x02d2: 0x1100, 0x02d3: 0x5500, 0x02d6: 0x1100, 0x02d7: 0x1100, - 0x02d8: 0x1100, 0x02d9: 0x1100, 0x02da: 0x1100, 0x02db: 0x5500, 0x02dd: 0x5100, - 0x02de: 0x5100, 0x02df: 0x5100, 0x02e0: 0x1100, 0x02e1: 0x1100, 0x02e2: 0x1100, 0x02e3: 0x5500, - 0x02e4: 0x1100, 0x02e5: 0x1100, 0x02e6: 0x1100, 0x02e7: 0x1100, 0x02e8: 0x1100, 0x02e9: 0x1100, - 0x02ea: 0x1100, 0x02eb: 0x5500, 0x02ec: 0x1100, 0x02ed: 0x5100, 0x02ee: 0x5500, 0x02ef: 0x5500, - 0x02f2: 0x1100, 0x02f3: 0x1100, 0x02f4: 0x1100, - 0x02f6: 0x9900, 0x02f7: 0x1100, 0x02f8: 0x1100, 0x02f9: 0x5500, 0x02fa: 0x1100, 0x02fb: 0x5500, - 0x02fc: 0x1100, 0x02fd: 0x5500, 0x02fe: 0x5800, - // Block 0xc, offset 0x300 - 0x0301: 0x1100, 0x0303: 0x8800, 0x0304: 0x1100, 0x0305: 0x8800, - 0x0307: 0x1100, 0x0308: 0x8800, 0x0309: 0x1100, - 0x030d: 0x8800, - 0x0320: 0x1100, 0x0321: 0x8800, 0x0322: 0x1100, - 0x0324: 0x8800, 0x0325: 0x8800, - 0x032d: 0x1100, 0x032e: 0x1100, 0x032f: 0x1100, - 0x0330: 0x1100, 0x0331: 0x1100, 0x0332: 0x8800, 0x0333: 0x8800, 0x0334: 0x1100, 0x0335: 0x1100, - 0x0336: 0x8800, 0x0337: 0x8800, 0x0338: 0x1100, 0x0339: 0x1100, 0x033a: 0x8800, 0x033b: 0x8800, - 0x033c: 0x8800, 0x033d: 0x8800, - // Block 0xd, offset 0x340 - 0x0346: 0x8800, 0x034b: 0x8800, - 0x034c: 0x1100, 0x034d: 0x8800, 0x034e: 0x1100, 0x034f: 0x8800, 0x0350: 0x1100, 0x0351: 0x8800, - 0x0352: 0x1100, 0x0353: 0x8800, 0x0354: 0x1100, 0x0355: 0x8800, 0x0356: 0x1100, 0x0357: 0x8800, - 0x0358: 0x1100, 0x0359: 0x8800, 0x035a: 0x1100, 0x035b: 0x8800, 0x035c: 0x1100, 0x035d: 0x8800, - 0x035e: 0x1100, 0x035f: 0x8800, 0x0360: 0x1100, 0x0361: 0x8800, 0x0362: 0x1100, - 0x0364: 0x8800, 0x0365: 0x1100, 0x0366: 0x8800, 0x0367: 0x1100, 0x0368: 0x8800, 0x0369: 0x1100, - 0x036f: 0x8800, - 0x0370: 0x1100, 0x0371: 0x1100, 0x0372: 0x8800, 0x0373: 0x1100, 0x0374: 0x1100, 0x0375: 0x8800, - 0x0376: 0x1100, 0x0377: 0x1100, 0x0378: 0x8800, 0x0379: 0x1100, 0x037a: 0x1100, 0x037b: 0x8800, - 0x037c: 0x1100, 0x037d: 0x1100, - // Block 0xe, offset 0x380 - 0x0394: 0x1100, - 0x0399: 0x6608, 0x039a: 0x6608, 0x039b: 0x5000, 0x039c: 0x5000, 0x039d: 0x8800, - 0x039e: 0x1100, 0x039f: 0x5000, - 0x03a6: 0x8800, - 0x03ab: 0x8800, 0x03ac: 0x1100, 0x03ad: 0x8800, 0x03ae: 0x1100, 0x03af: 0x8800, - 0x03b0: 0x1100, 0x03b1: 0x8800, 0x03b2: 0x1100, 0x03b3: 0x8800, 0x03b4: 0x1100, 0x03b5: 0x8800, - 0x03b6: 0x1100, 0x03b7: 0x8800, 0x03b8: 0x1100, 0x03b9: 0x8800, 0x03ba: 0x1100, 0x03bb: 0x8800, - 0x03bc: 0x1100, 0x03bd: 0x8800, 0x03be: 0x1100, 0x03bf: 0x8800, - // Block 0xf, offset 0x3c0 - 0x03c0: 0x1100, 0x03c1: 0x8800, 0x03c2: 0x1100, 0x03c4: 0x8800, 0x03c5: 0x1100, - 0x03c6: 0x8800, 0x03c7: 0x1100, 0x03c8: 0x8800, 0x03c9: 0x1100, - 0x03cf: 0x8800, 0x03d0: 0x1100, 0x03d1: 0x1100, - 0x03d2: 0x8800, 0x03d3: 0x1100, 0x03d4: 0x1100, 0x03d5: 0x8800, 0x03d6: 0x1100, 0x03d7: 0x1100, - 0x03d8: 0x8800, 0x03d9: 0x1100, 0x03da: 0x1100, 0x03db: 0x8800, 0x03dc: 0x1100, 0x03dd: 0x1100, - 0x03ef: 0x8800, - 0x03f0: 0x8800, 0x03f1: 0x8800, 0x03f2: 0x8800, 0x03f4: 0x1100, - 0x03f7: 0x1100, 0x03f8: 0x1100, 0x03f9: 0x1100, 0x03fa: 0x1100, - 0x03fd: 0x8800, 0x03fe: 0x1100, 0x03ff: 0x5000, -} - -// charInfoSparseOffset: 156 entries, 312 bytes -var charInfoSparseOffset = []uint16{0x0, 0x8, 0x13, 0x21, 0x25, 0x2f, 0x36, 0x39, 0x3c, 0x4a, 0x56, 0x58, 0x62, 0x67, 0x6e, 0x7d, 0x8a, 0x92, 0x96, 0x9b, 0x9d, 0xa5, 0xab, 0xae, 0xb5, 0xb9, 0xbd, 0xbf, 0xc1, 0xc8, 0xcc, 0xd1, 0xd6, 0xd9, 0xe2, 0xe4, 0xec, 0xf0, 0xf2, 0xf5, 0xf8, 0xfe, 0x10e, 0x11a, 0x11c, 0x122, 0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x130, 0x133, 0x136, 0x138, 0x13b, 0x13e, 0x142, 0x151, 0x159, 0x15b, 0x15e, 0x160, 0x169, 0x16d, 0x171, 0x173, 0x182, 0x186, 0x18c, 0x194, 0x198, 0x1a1, 0x1aa, 0x1b5, 0x1bb, 0x1bf, 0x1cd, 0x1dc, 0x1e0, 0x1e7, 0x1ec, 0x1fa, 0x206, 0x209, 0x20b, 0x20d, 0x20f, 0x211, 0x213, 0x215, 0x217, 0x219, 0x21b, 0x21e, 0x220, 0x222, 0x224, 0x226, 0x22f, 0x231, 0x234, 0x237, 0x23a, 0x23c, 0x23f, 0x241, 0x243, 0x245, 0x248, 0x24a, 0x24c, 0x24e, 0x250, 0x256, 0x258, 0x25a, 0x25c, 0x25e, 0x260, 0x26a, 0x26d, 0x26f, 0x279, 0x27e, 0x280, 0x282, 0x284, 0x286, 0x289, 0x28c, 0x290, 0x298, 0x29a, 0x29c, 0x2a3, 0x2a5, 0x2ab, 0x2b3, 0x2ba, 0x2c0, 0x2c2, 0x2c4, 0x2c7, 0x2d0, 0x2d3, 0x2da, 0x2df, 0x2e2, 0x2e5, 0x2e9, 0x2eb, 0x2ed, 0x2f0, 0x2f3} - -// charInfoSparseValues: 757 entries, 3028 bytes -var charInfoSparseValues = [757]valueRange{ - // Block 0x0, offset 0x1 - {value: 0x0000, lo: 0x07}, - {value: 0x5000, lo: 0xa0, hi: 0xa0}, - {value: 0x5800, lo: 0xa8, hi: 0xa8}, - {value: 0x5000, lo: 0xaa, hi: 0xaa}, - {value: 0x5000, lo: 0xaf, hi: 0xaf}, - {value: 0x5000, lo: 0xb2, hi: 0xb5}, - {value: 0x5000, lo: 0xb8, hi: 0xba}, - {value: 0x5000, lo: 0xbc, hi: 0xbe}, - // Block 0x1, offset 0x2 - {value: 0x0000, lo: 0x0a}, - {value: 0x1100, lo: 0x80, hi: 0x81}, - {value: 0x9900, lo: 0x82, hi: 0x83}, - {value: 0x1100, lo: 0x84, hi: 0x8f}, - {value: 0x9900, lo: 0x92, hi: 0x93}, - {value: 0x1100, lo: 0x94, hi: 0xa5}, - {value: 0x1100, lo: 0xa8, hi: 0xb0}, - {value: 0x5000, lo: 0xb2, hi: 0xb3}, - {value: 0x1100, lo: 0xb4, hi: 0xb7}, - {value: 0x1100, lo: 0xb9, hi: 0xbe}, - {value: 0x5000, lo: 0xbf, hi: 0xbf}, - // Block 0x2, offset 0x3 - {value: 0x0000, lo: 0x0d}, - {value: 0x5000, lo: 0x80, hi: 0x80}, - {value: 0x1100, lo: 0x83, hi: 0x88}, - {value: 0x5000, lo: 0x89, hi: 0x89}, - {value: 0x9900, lo: 0x8c, hi: 0x8d}, - {value: 0x1100, lo: 0x8e, hi: 0x91}, - {value: 0x1100, lo: 0x94, hi: 0x99}, - {value: 0x9900, lo: 0x9a, hi: 0x9b}, - {value: 0x1100, lo: 0x9c, hi: 0x9f}, - {value: 0x9900, lo: 0xa0, hi: 0xa1}, - {value: 0x1100, lo: 0xa2, hi: 0xa5}, - {value: 0x9900, lo: 0xa8, hi: 0xab}, - {value: 0x1100, lo: 0xac, hi: 0xbe}, - {value: 0x5800, lo: 0xbf, hi: 0xbf}, - // Block 0x3, offset 0x4 - {value: 0x0000, lo: 0x03}, - {value: 0x9900, lo: 0xa0, hi: 0xa1}, - {value: 0x9900, lo: 0xaf, hi: 0xb0}, - {value: 0x8800, lo: 0xb7, hi: 0xb7}, - // Block 0x4, offset 0x5 - {value: 0x0000, lo: 0x09}, - {value: 0x5000, lo: 0x84, hi: 0x8c}, - {value: 0x1100, lo: 0x8d, hi: 0x9c}, - {value: 0x1100, lo: 0x9e, hi: 0xa3}, - {value: 0x1100, lo: 0xa6, hi: 0xa9}, - {value: 0x9900, lo: 0xaa, hi: 0xab}, - {value: 0x1100, lo: 0xac, hi: 0xb0}, - {value: 0x5000, lo: 0xb1, hi: 0xb3}, - {value: 0x1100, lo: 0xb4, hi: 0xb5}, - {value: 0x1100, lo: 0xb8, hi: 0xbf}, - // Block 0x5, offset 0x6 - {value: 0x0000, lo: 0x06}, - {value: 0x1100, lo: 0x80, hi: 0x9b}, - {value: 0x1100, lo: 0x9e, hi: 0x9f}, - {value: 0x9900, lo: 0xa6, hi: 0xa9}, - {value: 0x1100, lo: 0xaa, hi: 0xad}, - {value: 0x9900, lo: 0xae, hi: 0xaf}, - {value: 0x1100, lo: 0xb0, hi: 0xb3}, - // Block 0x6, offset 0x7 - {value: 0x0000, lo: 0x02}, - {value: 0x8800, lo: 0x92, hi: 0x92}, - {value: 0x5000, lo: 0xb0, hi: 0xb8}, - // Block 0x7, offset 0x8 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x98, hi: 0x9d}, - {value: 0x5000, lo: 0xa0, hi: 0xa4}, - // Block 0x8, offset 0x9 - {value: 0x0000, lo: 0x0d}, - {value: 0x8800, lo: 0x81, hi: 0x81}, - {value: 0x8800, lo: 0x85, hi: 0x85}, - {value: 0x8800, lo: 0x89, hi: 0x89}, - {value: 0x9900, lo: 0x8a, hi: 0x8b}, - {value: 0x1100, lo: 0x8c, hi: 0x8d}, - {value: 0x9900, lo: 0x8e, hi: 0x8e}, - {value: 0x5000, lo: 0x90, hi: 0x91}, - {value: 0x5800, lo: 0x92, hi: 0x92}, - {value: 0x5100, lo: 0x93, hi: 0x94}, - {value: 0x5000, lo: 0x95, hi: 0x96}, - {value: 0x5000, lo: 0xb0, hi: 0xb2}, - {value: 0x5000, lo: 0xb4, hi: 0xb5}, - {value: 0x5000, lo: 0xb9, hi: 0xb9}, - // Block 0x9, offset 0xa - {value: 0x0000, lo: 0x0b}, - {value: 0x8800, lo: 0x83, hi: 0x83}, - {value: 0x8800, lo: 0x87, hi: 0x87}, - {value: 0x8800, lo: 0x8b, hi: 0x8b}, - {value: 0x8800, lo: 0x8d, hi: 0x8d}, - {value: 0x1100, lo: 0x90, hi: 0x91}, - {value: 0x1100, lo: 0x93, hi: 0x93}, - {value: 0x8800, lo: 0x96, hi: 0x96}, - {value: 0x1100, lo: 0x97, hi: 0x97}, - {value: 0x1100, lo: 0x9c, hi: 0x9e}, - {value: 0x8800, lo: 0xb4, hi: 0xb5}, - {value: 0x1100, lo: 0xb6, hi: 0xb7}, - // Block 0xa, offset 0xb - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0x83, hi: 0x87}, - // Block 0xb, offset 0xc - {value: 0x0000, lo: 0x09}, - {value: 0x1100, lo: 0x81, hi: 0x82}, - {value: 0x1100, lo: 0x90, hi: 0x93}, - {value: 0x1100, lo: 0x96, hi: 0x97}, - {value: 0x8800, lo: 0x98, hi: 0x99}, - {value: 0x1100, lo: 0x9a, hi: 0x9f}, - {value: 0x1100, lo: 0xa2, hi: 0xa7}, - {value: 0x8800, lo: 0xa8, hi: 0xa9}, - {value: 0x1100, lo: 0xaa, hi: 0xb5}, - {value: 0x1100, lo: 0xb8, hi: 0xb9}, - // Block 0xc, offset 0xd - {value: 0x0001, lo: 0x04}, - {value: 0x0018, lo: 0x81, hi: 0x82}, - {value: 0x00e6, lo: 0x84, hi: 0x84}, - {value: 0x00dc, lo: 0x85, hi: 0x85}, - {value: 0x0012, lo: 0x87, hi: 0x87}, - // Block 0xd, offset 0xe - {value: 0x0000, lo: 0x06}, - {value: 0x00e6, lo: 0x90, hi: 0x97}, - {value: 0x001e, lo: 0x98, hi: 0x98}, - {value: 0x001f, lo: 0x99, hi: 0x99}, - {value: 0x0020, lo: 0x9a, hi: 0x9a}, - {value: 0x1100, lo: 0xa2, hi: 0xa6}, - {value: 0x8800, lo: 0xa7, hi: 0xa7}, - // Block 0xe, offset 0xf - {value: 0x0000, lo: 0x0e}, - {value: 0x1100, lo: 0x80, hi: 0x80}, - {value: 0x8800, lo: 0x81, hi: 0x81}, - {value: 0x1100, lo: 0x82, hi: 0x82}, - {value: 0x8800, lo: 0x92, hi: 0x92}, - {value: 0x1100, lo: 0x93, hi: 0x93}, - {value: 0x8800, lo: 0x95, hi: 0x95}, - {value: 0x00e6, lo: 0x96, hi: 0x9c}, - {value: 0x00e6, lo: 0x9f, hi: 0xa2}, - {value: 0x00dc, lo: 0xa3, hi: 0xa3}, - {value: 0x00e6, lo: 0xa4, hi: 0xa4}, - {value: 0x00e6, lo: 0xa7, hi: 0xa8}, - {value: 0x00dc, lo: 0xaa, hi: 0xaa}, - {value: 0x00e6, lo: 0xab, hi: 0xac}, - {value: 0x00dc, lo: 0xad, hi: 0xad}, - // Block 0xf, offset 0x10 - {value: 0x0000, lo: 0x0c}, - {value: 0x0024, lo: 0x91, hi: 0x91}, - {value: 0x00e6, lo: 0xb0, hi: 0xb0}, - {value: 0x00dc, lo: 0xb1, hi: 0xb1}, - {value: 0x00e6, lo: 0xb2, hi: 0xb3}, - {value: 0x00dc, lo: 0xb4, hi: 0xb4}, - {value: 0x00e6, lo: 0xb5, hi: 0xb6}, - {value: 0x00dc, lo: 0xb7, hi: 0xb9}, - {value: 0x00e6, lo: 0xba, hi: 0xba}, - {value: 0x00dc, lo: 0xbb, hi: 0xbc}, - {value: 0x00e6, lo: 0xbd, hi: 0xbd}, - {value: 0x00dc, lo: 0xbe, hi: 0xbe}, - {value: 0x00e6, lo: 0xbf, hi: 0xbf}, - // Block 0x10, offset 0x11 - {value: 0x000a, lo: 0x07}, - {value: 0x00e6, lo: 0x80, hi: 0x80}, - {value: 0x00e6, lo: 0x81, hi: 0x81}, - {value: 0x00dc, lo: 0x82, hi: 0x83}, - {value: 0x00dc, lo: 0x84, hi: 0x85}, - {value: 0x00dc, lo: 0x86, hi: 0x87}, - {value: 0x00dc, lo: 0x88, hi: 0x89}, - {value: 0x00e6, lo: 0x8a, hi: 0x8a}, - // Block 0x11, offset 0x12 - {value: 0x0000, lo: 0x03}, - {value: 0x00e6, lo: 0xab, hi: 0xb1}, - {value: 0x00dc, lo: 0xb2, hi: 0xb2}, - {value: 0x00e6, lo: 0xb3, hi: 0xb3}, - // Block 0x12, offset 0x13 - {value: 0x0000, lo: 0x04}, - {value: 0x00e6, lo: 0x96, hi: 0x99}, - {value: 0x00e6, lo: 0x9b, hi: 0xa3}, - {value: 0x00e6, lo: 0xa5, hi: 0xa7}, - {value: 0x00e6, lo: 0xa9, hi: 0xad}, - // Block 0x13, offset 0x14 - {value: 0x0000, lo: 0x01}, - {value: 0x00dc, lo: 0x99, hi: 0x9b}, - // Block 0x14, offset 0x15 - {value: 0x0000, lo: 0x07}, - {value: 0x8800, lo: 0xa8, hi: 0xa8}, - {value: 0x1100, lo: 0xa9, hi: 0xa9}, - {value: 0x8800, lo: 0xb0, hi: 0xb0}, - {value: 0x1100, lo: 0xb1, hi: 0xb1}, - {value: 0x8800, lo: 0xb3, hi: 0xb3}, - {value: 0x1100, lo: 0xb4, hi: 0xb4}, - {value: 0x6607, lo: 0xbc, hi: 0xbc}, - // Block 0x15, offset 0x16 - {value: 0x0000, lo: 0x05}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x00e6, lo: 0x91, hi: 0x91}, - {value: 0x00dc, lo: 0x92, hi: 0x92}, - {value: 0x00e6, lo: 0x93, hi: 0x94}, - {value: 0x5500, lo: 0x98, hi: 0x9f}, - // Block 0x16, offset 0x17 - {value: 0x0000, lo: 0x02}, - {value: 0x0007, lo: 0xbc, hi: 0xbc}, - {value: 0x6600, lo: 0xbe, hi: 0xbe}, - // Block 0x17, offset 0x18 - {value: 0x0000, lo: 0x06}, - {value: 0x8800, lo: 0x87, hi: 0x87}, - {value: 0x1100, lo: 0x8b, hi: 0x8c}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x6600, lo: 0x97, hi: 0x97}, - {value: 0x5500, lo: 0x9c, hi: 0x9d}, - {value: 0x5500, lo: 0x9f, hi: 0x9f}, - // Block 0x18, offset 0x19 - {value: 0x0000, lo: 0x03}, - {value: 0x5500, lo: 0xb3, hi: 0xb3}, - {value: 0x5500, lo: 0xb6, hi: 0xb6}, - {value: 0x0007, lo: 0xbc, hi: 0xbc}, - // Block 0x19, offset 0x1a - {value: 0x0000, lo: 0x03}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x5500, lo: 0x99, hi: 0x9b}, - {value: 0x5500, lo: 0x9e, hi: 0x9e}, - // Block 0x1a, offset 0x1b - {value: 0x0000, lo: 0x01}, - {value: 0x0007, lo: 0xbc, hi: 0xbc}, - // Block 0x1b, offset 0x1c - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - // Block 0x1c, offset 0x1d - {value: 0x0000, lo: 0x06}, - {value: 0x8800, lo: 0x87, hi: 0x87}, - {value: 0x1100, lo: 0x88, hi: 0x88}, - {value: 0x1100, lo: 0x8b, hi: 0x8c}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x6600, lo: 0x96, hi: 0x97}, - {value: 0x5500, lo: 0x9c, hi: 0x9d}, - // Block 0x1d, offset 0x1e - {value: 0x0000, lo: 0x03}, - {value: 0x8800, lo: 0x92, hi: 0x92}, - {value: 0x1100, lo: 0x94, hi: 0x94}, - {value: 0x6600, lo: 0xbe, hi: 0xbe}, - // Block 0x1e, offset 0x1f - {value: 0x0000, lo: 0x04}, - {value: 0x8800, lo: 0x86, hi: 0x87}, - {value: 0x1100, lo: 0x8a, hi: 0x8c}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x6600, lo: 0x97, hi: 0x97}, - // Block 0x1f, offset 0x20 - {value: 0x6607, lo: 0x04}, - {value: 0x8800, lo: 0x86, hi: 0x86}, - {value: 0x1100, lo: 0x88, hi: 0x88}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x0054, lo: 0x95, hi: 0x96}, - // Block 0x20, offset 0x21 - {value: 0x0000, lo: 0x02}, - {value: 0x0007, lo: 0xbc, hi: 0xbc}, - {value: 0x8800, lo: 0xbf, hi: 0xbf}, - // Block 0x21, offset 0x22 - {value: 0x0000, lo: 0x08}, - {value: 0x1100, lo: 0x80, hi: 0x80}, - {value: 0x6600, lo: 0x82, hi: 0x82}, - {value: 0x8800, lo: 0x86, hi: 0x86}, - {value: 0x1100, lo: 0x87, hi: 0x88}, - {value: 0x9900, lo: 0x8a, hi: 0x8a}, - {value: 0x1100, lo: 0x8b, hi: 0x8b}, - {value: 0x0009, lo: 0x8d, hi: 0x8d}, - {value: 0x6600, lo: 0x95, hi: 0x96}, - // Block 0x22, offset 0x23 - {value: 0x0000, lo: 0x01}, - {value: 0x6600, lo: 0xbe, hi: 0xbe}, - // Block 0x23, offset 0x24 - {value: 0x0000, lo: 0x07}, - {value: 0x6609, lo: 0x8a, hi: 0x8a}, - {value: 0x6600, lo: 0x8f, hi: 0x8f}, - {value: 0x8800, lo: 0x99, hi: 0x99}, - {value: 0x1100, lo: 0x9a, hi: 0x9a}, - {value: 0x9900, lo: 0x9c, hi: 0x9c}, - {value: 0x1100, lo: 0x9d, hi: 0x9e}, - {value: 0x6600, lo: 0x9f, hi: 0x9f}, - // Block 0x24, offset 0x25 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0xb3, hi: 0xb3}, - {value: 0x0067, lo: 0xb8, hi: 0xb9}, - {value: 0x0009, lo: 0xba, hi: 0xba}, - // Block 0x25, offset 0x26 - {value: 0x0000, lo: 0x01}, - {value: 0x006b, lo: 0x88, hi: 0x8b}, - // Block 0x26, offset 0x27 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0xb3, hi: 0xb3}, - {value: 0x0076, lo: 0xb8, hi: 0xb9}, - // Block 0x27, offset 0x28 - {value: 0x0000, lo: 0x02}, - {value: 0x007a, lo: 0x88, hi: 0x8b}, - {value: 0x5000, lo: 0x9c, hi: 0x9d}, - // Block 0x28, offset 0x29 - {value: 0x0000, lo: 0x05}, - {value: 0x5000, lo: 0x8c, hi: 0x8c}, - {value: 0x00dc, lo: 0x98, hi: 0x99}, - {value: 0x00dc, lo: 0xb5, hi: 0xb5}, - {value: 0x00dc, lo: 0xb7, hi: 0xb7}, - {value: 0x00d8, lo: 0xb9, hi: 0xb9}, - // Block 0x29, offset 0x2a - {value: 0x0000, lo: 0x0f}, - {value: 0x5500, lo: 0x83, hi: 0x83}, - {value: 0x5500, lo: 0x8d, hi: 0x8d}, - {value: 0x5500, lo: 0x92, hi: 0x92}, - {value: 0x5500, lo: 0x97, hi: 0x97}, - {value: 0x5500, lo: 0x9c, hi: 0x9c}, - {value: 0x5500, lo: 0xa9, hi: 0xa9}, - {value: 0x0081, lo: 0xb1, hi: 0xb1}, - {value: 0x0082, lo: 0xb2, hi: 0xb2}, - {value: 0x5500, lo: 0xb3, hi: 0xb3}, - {value: 0x0084, lo: 0xb4, hi: 0xb4}, - {value: 0x5500, lo: 0xb5, hi: 0xb6}, - {value: 0x5000, lo: 0xb7, hi: 0xb7}, - {value: 0x5500, lo: 0xb8, hi: 0xb8}, - {value: 0x5000, lo: 0xb9, hi: 0xb9}, - {value: 0x0082, lo: 0xba, hi: 0xbd}, - // Block 0x2a, offset 0x2b - {value: 0x0000, lo: 0x0b}, - {value: 0x0082, lo: 0x80, hi: 0x80}, - {value: 0x5500, lo: 0x81, hi: 0x81}, - {value: 0x00e6, lo: 0x82, hi: 0x83}, - {value: 0x0009, lo: 0x84, hi: 0x84}, - {value: 0x00e6, lo: 0x86, hi: 0x87}, - {value: 0x5500, lo: 0x93, hi: 0x93}, - {value: 0x5500, lo: 0x9d, hi: 0x9d}, - {value: 0x5500, lo: 0xa2, hi: 0xa2}, - {value: 0x5500, lo: 0xa7, hi: 0xa7}, - {value: 0x5500, lo: 0xac, hi: 0xac}, - {value: 0x5500, lo: 0xb9, hi: 0xb9}, - // Block 0x2b, offset 0x2c - {value: 0x0000, lo: 0x01}, - {value: 0x00dc, lo: 0x86, hi: 0x86}, - // Block 0x2c, offset 0x2d - {value: 0x0000, lo: 0x05}, - {value: 0x8800, lo: 0xa5, hi: 0xa5}, - {value: 0x1100, lo: 0xa6, hi: 0xa6}, - {value: 0x6600, lo: 0xae, hi: 0xae}, - {value: 0x0007, lo: 0xb7, hi: 0xb7}, - {value: 0x0009, lo: 0xb9, hi: 0xba}, - // Block 0x2d, offset 0x2e - {value: 0x0000, lo: 0x01}, - {value: 0x00dc, lo: 0x8d, hi: 0x8d}, - // Block 0x2e, offset 0x2f - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xbc, hi: 0xbc}, - // Block 0x2f, offset 0x30 - {value: 0x0000, lo: 0x01}, - {value: 0x8800, lo: 0x80, hi: 0x92}, - // Block 0x30, offset 0x31 - {value: 0x0000, lo: 0x01}, - {value: 0xee00, lo: 0xa1, hi: 0xb5}, - // Block 0x31, offset 0x32 - {value: 0x0000, lo: 0x01}, - {value: 0x6600, lo: 0xa8, hi: 0xbf}, - // Block 0x32, offset 0x33 - {value: 0x0000, lo: 0x01}, - {value: 0x6600, lo: 0x80, hi: 0x82}, - // Block 0x33, offset 0x34 - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0x9d, hi: 0x9f}, - // Block 0x34, offset 0x35 - {value: 0x0000, lo: 0x02}, - {value: 0x0009, lo: 0x94, hi: 0x94}, - {value: 0x0009, lo: 0xb4, hi: 0xb4}, - // Block 0x35, offset 0x36 - {value: 0x0000, lo: 0x02}, - {value: 0x0009, lo: 0x92, hi: 0x92}, - {value: 0x00e6, lo: 0x9d, hi: 0x9d}, - // Block 0x36, offset 0x37 - {value: 0x0000, lo: 0x01}, - {value: 0x00e4, lo: 0xa9, hi: 0xa9}, - // Block 0x37, offset 0x38 - {value: 0x0008, lo: 0x02}, - {value: 0x00de, lo: 0xb9, hi: 0xba}, - {value: 0x00dc, lo: 0xbb, hi: 0xbb}, - // Block 0x38, offset 0x39 - {value: 0x0000, lo: 0x02}, - {value: 0x00e6, lo: 0x97, hi: 0x97}, - {value: 0x00dc, lo: 0x98, hi: 0x98}, - // Block 0x39, offset 0x3a - {value: 0x0000, lo: 0x03}, - {value: 0x0009, lo: 0xa0, hi: 0xa0}, - {value: 0x00e6, lo: 0xb5, hi: 0xbc}, - {value: 0x00dc, lo: 0xbf, hi: 0xbf}, - // Block 0x3a, offset 0x3b - {value: 0x7700, lo: 0x0e}, - {value: 0x8800, lo: 0x85, hi: 0x85}, - {value: 0x1100, lo: 0x86, hi: 0x87}, - {value: 0x1100, lo: 0x88, hi: 0x89}, - {value: 0x1100, lo: 0x8a, hi: 0x8b}, - {value: 0x1100, lo: 0x8c, hi: 0x8d}, - {value: 0x1100, lo: 0x8e, hi: 0x8e}, - {value: 0x8800, lo: 0x91, hi: 0x91}, - {value: 0x1100, lo: 0x92, hi: 0x92}, - {value: 0x0007, lo: 0xb4, hi: 0xb4}, - {value: 0x6600, lo: 0xb5, hi: 0xb5}, - {value: 0x8800, lo: 0xba, hi: 0xba}, - {value: 0x1100, lo: 0xbb, hi: 0xbc}, - {value: 0x1100, lo: 0xbd, hi: 0xbe}, - {value: 0x8800, lo: 0xbf, hi: 0xbf}, - // Block 0x3b, offset 0x3c - {value: 0x0000, lo: 0x07}, - {value: 0x1100, lo: 0x80, hi: 0x81}, - {value: 0x8800, lo: 0x82, hi: 0x82}, - {value: 0x1100, lo: 0x83, hi: 0x83}, - {value: 0x0009, lo: 0x84, hi: 0x84}, - {value: 0x00e6, lo: 0xab, hi: 0xab}, - {value: 0x00dc, lo: 0xac, hi: 0xac}, - {value: 0x00e6, lo: 0xad, hi: 0xb3}, - // Block 0x3c, offset 0x3d - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0xaa, hi: 0xaa}, - // Block 0x3d, offset 0x3e - {value: 0x0000, lo: 0x02}, - {value: 0x0007, lo: 0xa6, hi: 0xa6}, - {value: 0x0009, lo: 0xb2, hi: 0xb3}, - // Block 0x3e, offset 0x3f - {value: 0x0000, lo: 0x01}, - {value: 0x0007, lo: 0xb7, hi: 0xb7}, - // Block 0x3f, offset 0x40 - {value: 0x0000, lo: 0x08}, - {value: 0x00e6, lo: 0x90, hi: 0x92}, - {value: 0x0001, lo: 0x94, hi: 0x94}, - {value: 0x00dc, lo: 0x95, hi: 0x99}, - {value: 0x00e6, lo: 0x9a, hi: 0x9b}, - {value: 0x00dc, lo: 0x9c, hi: 0x9f}, - {value: 0x00e6, lo: 0xa0, hi: 0xa0}, - {value: 0x0001, lo: 0xa2, hi: 0xa8}, - {value: 0x00dc, lo: 0xad, hi: 0xad}, - // Block 0x40, offset 0x41 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0xac, hi: 0xae}, - {value: 0x5000, lo: 0xb0, hi: 0xba}, - {value: 0x5000, lo: 0xbc, hi: 0xbf}, - // Block 0x41, offset 0x42 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0x80, hi: 0x8d}, - {value: 0x5000, lo: 0x8f, hi: 0xaa}, - {value: 0x5000, lo: 0xb8, hi: 0xb8}, - // Block 0x42, offset 0x43 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x9b, hi: 0xbf}, - // Block 0x43, offset 0x44 - {value: 0x0000, lo: 0x0e}, - {value: 0x00e6, lo: 0x80, hi: 0x81}, - {value: 0x00dc, lo: 0x82, hi: 0x82}, - {value: 0x00e6, lo: 0x83, hi: 0x89}, - {value: 0x00dc, lo: 0x8a, hi: 0x8a}, - {value: 0x00e6, lo: 0x8b, hi: 0x8c}, - {value: 0x00ea, lo: 0x8d, hi: 0x8d}, - {value: 0x00d6, lo: 0x8e, hi: 0x8e}, - {value: 0x00dc, lo: 0x8f, hi: 0x8f}, - {value: 0x00ca, lo: 0x90, hi: 0x90}, - {value: 0x00e6, lo: 0x91, hi: 0xa6}, - {value: 0x00e9, lo: 0xbc, hi: 0xbc}, - {value: 0x00dc, lo: 0xbd, hi: 0xbd}, - {value: 0x00e6, lo: 0xbe, hi: 0xbe}, - {value: 0x00dc, lo: 0xbf, hi: 0xbf}, - // Block 0x44, offset 0x45 - {value: 0x0000, lo: 0x03}, - {value: 0x1100, lo: 0x80, hi: 0xb5}, - {value: 0x9900, lo: 0xb6, hi: 0xb7}, - {value: 0x1100, lo: 0xb8, hi: 0xbf}, - // Block 0x45, offset 0x46 - {value: 0x0000, lo: 0x05}, - {value: 0x1100, lo: 0x80, hi: 0x99}, - {value: 0x9900, lo: 0x9a, hi: 0x9b}, - {value: 0x1100, lo: 0x9c, hi: 0xa1}, - {value: 0x9900, lo: 0xa2, hi: 0xa3}, - {value: 0x1100, lo: 0xa4, hi: 0xbf}, - // Block 0x46, offset 0x47 - {value: 0x0000, lo: 0x07}, - {value: 0x1100, lo: 0x80, hi: 0x99}, - {value: 0x5000, lo: 0x9a, hi: 0x9a}, - {value: 0x5100, lo: 0x9b, hi: 0x9b}, - {value: 0x9900, lo: 0xa0, hi: 0xa1}, - {value: 0x1100, lo: 0xa2, hi: 0xb7}, - {value: 0x9900, lo: 0xb8, hi: 0xb9}, - {value: 0x1100, lo: 0xba, hi: 0xbf}, - // Block 0x47, offset 0x48 - {value: 0x0000, lo: 0x03}, - {value: 0x1100, lo: 0x80, hi: 0x8b}, - {value: 0x9900, lo: 0x8c, hi: 0x8d}, - {value: 0x1100, lo: 0x8e, hi: 0xb9}, - // Block 0x48, offset 0x49 - {value: 0x0000, lo: 0x08}, - {value: 0x9900, lo: 0x80, hi: 0x91}, - {value: 0x1100, lo: 0x92, hi: 0x95}, - {value: 0x9900, lo: 0x98, hi: 0x99}, - {value: 0x1100, lo: 0x9a, hi: 0x9d}, - {value: 0x9900, lo: 0xa0, hi: 0xb1}, - {value: 0x1100, lo: 0xb2, hi: 0xb7}, - {value: 0x9900, lo: 0xb8, hi: 0xb9}, - {value: 0x1100, lo: 0xba, hi: 0xbf}, - // Block 0x49, offset 0x4a - {value: 0x0000, lo: 0x08}, - {value: 0x1100, lo: 0x80, hi: 0xb4}, - {value: 0x9900, lo: 0xb6, hi: 0xb6}, - {value: 0x1100, lo: 0xb7, hi: 0xba}, - {value: 0x5500, lo: 0xbb, hi: 0xbb}, - {value: 0x1100, lo: 0xbc, hi: 0xbc}, - {value: 0x5000, lo: 0xbd, hi: 0xbd}, - {value: 0x5500, lo: 0xbe, hi: 0xbe}, - {value: 0x5800, lo: 0xbf, hi: 0xbf}, - // Block 0x4a, offset 0x4b - {value: 0x0000, lo: 0x0a}, - {value: 0x5500, lo: 0x80, hi: 0x81}, - {value: 0x5000, lo: 0x82, hi: 0x8a}, - {value: 0x5000, lo: 0x91, hi: 0x91}, - {value: 0x5000, lo: 0x97, hi: 0x97}, - {value: 0x5000, lo: 0xa4, hi: 0xa6}, - {value: 0x5000, lo: 0xaf, hi: 0xaf}, - {value: 0x5000, lo: 0xb3, hi: 0xb4}, - {value: 0x5000, lo: 0xb6, hi: 0xb7}, - {value: 0x5000, lo: 0xbc, hi: 0xbc}, - {value: 0x5000, lo: 0xbe, hi: 0xbe}, - // Block 0x4b, offset 0x4c - {value: 0x0000, lo: 0x05}, - {value: 0x5000, lo: 0x87, hi: 0x89}, - {value: 0x5000, lo: 0x97, hi: 0x97}, - {value: 0x5000, lo: 0x9f, hi: 0x9f}, - {value: 0x5000, lo: 0xb0, hi: 0xb1}, - {value: 0x5000, lo: 0xb4, hi: 0xbf}, - // Block 0x4c, offset 0x4d - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0x80, hi: 0x8e}, - {value: 0x5000, lo: 0x90, hi: 0x9c}, - {value: 0x5000, lo: 0xa8, hi: 0xa8}, - // Block 0x4d, offset 0x4e - {value: 0x0000, lo: 0x0d}, - {value: 0x00e6, lo: 0x90, hi: 0x91}, - {value: 0x0001, lo: 0x92, hi: 0x93}, - {value: 0x00e6, lo: 0x94, hi: 0x97}, - {value: 0x0001, lo: 0x98, hi: 0x9a}, - {value: 0x00e6, lo: 0x9b, hi: 0x9c}, - {value: 0x00e6, lo: 0xa1, hi: 0xa1}, - {value: 0x0001, lo: 0xa5, hi: 0xa6}, - {value: 0x00e6, lo: 0xa7, hi: 0xa7}, - {value: 0x00dc, lo: 0xa8, hi: 0xa8}, - {value: 0x00e6, lo: 0xa9, hi: 0xa9}, - {value: 0x0001, lo: 0xaa, hi: 0xab}, - {value: 0x00dc, lo: 0xac, hi: 0xaf}, - {value: 0x00e6, lo: 0xb0, hi: 0xb0}, - // Block 0x4e, offset 0x4f - {value: 0x0000, lo: 0x0e}, - {value: 0x5000, lo: 0x80, hi: 0x83}, - {value: 0x5000, lo: 0x85, hi: 0x87}, - {value: 0x5000, lo: 0x89, hi: 0x93}, - {value: 0x5000, lo: 0x95, hi: 0x96}, - {value: 0x5000, lo: 0x99, hi: 0x9d}, - {value: 0x5000, lo: 0xa0, hi: 0xa2}, - {value: 0x5000, lo: 0xa4, hi: 0xa4}, - {value: 0x5500, lo: 0xa6, hi: 0xa6}, - {value: 0x5000, lo: 0xa8, hi: 0xa8}, - {value: 0x5500, lo: 0xaa, hi: 0xab}, - {value: 0x5000, lo: 0xac, hi: 0xad}, - {value: 0x5000, lo: 0xaf, hi: 0xb1}, - {value: 0x5000, lo: 0xb3, hi: 0xb9}, - {value: 0x5000, lo: 0xbb, hi: 0xbf}, - // Block 0x4f, offset 0x50 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0x80, hi: 0x80}, - {value: 0x5000, lo: 0x85, hi: 0x89}, - {value: 0x5000, lo: 0x90, hi: 0xbf}, - // Block 0x50, offset 0x51 - {value: 0x0000, lo: 0x06}, - {value: 0x5000, lo: 0x89, hi: 0x89}, - {value: 0x8800, lo: 0x90, hi: 0x90}, - {value: 0x8800, lo: 0x92, hi: 0x92}, - {value: 0x8800, lo: 0x94, hi: 0x94}, - {value: 0x1100, lo: 0x9a, hi: 0x9b}, - {value: 0x1100, lo: 0xae, hi: 0xae}, - // Block 0x51, offset 0x52 - {value: 0x0000, lo: 0x04}, - {value: 0x1100, lo: 0x8d, hi: 0x8f}, - {value: 0x8800, lo: 0x90, hi: 0x90}, - {value: 0x8800, lo: 0x92, hi: 0x92}, - {value: 0x8800, lo: 0x94, hi: 0x94}, - // Block 0x52, offset 0x53 - {value: 0x0000, lo: 0x0d}, - {value: 0x8800, lo: 0x83, hi: 0x83}, - {value: 0x1100, lo: 0x84, hi: 0x84}, - {value: 0x8800, lo: 0x88, hi: 0x88}, - {value: 0x1100, lo: 0x89, hi: 0x89}, - {value: 0x8800, lo: 0x8b, hi: 0x8b}, - {value: 0x1100, lo: 0x8c, hi: 0x8c}, - {value: 0x8800, lo: 0xa3, hi: 0xa3}, - {value: 0x1100, lo: 0xa4, hi: 0xa4}, - {value: 0x8800, lo: 0xa5, hi: 0xa5}, - {value: 0x1100, lo: 0xa6, hi: 0xa6}, - {value: 0x5000, lo: 0xac, hi: 0xad}, - {value: 0x5000, lo: 0xaf, hi: 0xb0}, - {value: 0x8800, lo: 0xbc, hi: 0xbc}, - // Block 0x53, offset 0x54 - {value: 0x0000, lo: 0x0b}, - {value: 0x1100, lo: 0x80, hi: 0x81}, - {value: 0x8800, lo: 0x82, hi: 0x83}, - {value: 0x1100, lo: 0x84, hi: 0x85}, - {value: 0x8800, lo: 0x86, hi: 0x87}, - {value: 0x1100, lo: 0x88, hi: 0x89}, - {value: 0x8800, lo: 0x91, hi: 0x92}, - {value: 0x8800, lo: 0xa2, hi: 0xa2}, - {value: 0x8800, lo: 0xa8, hi: 0xa9}, - {value: 0x8800, lo: 0xab, hi: 0xab}, - {value: 0x1100, lo: 0xac, hi: 0xaf}, - {value: 0x8800, lo: 0xb2, hi: 0xb5}, - // Block 0x54, offset 0x55 - {value: 0x0000, lo: 0x02}, - {value: 0x1100, lo: 0xa0, hi: 0xa3}, - {value: 0x1100, lo: 0xaa, hi: 0xad}, - // Block 0x55, offset 0x56 - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0xa9, hi: 0xaa}, - // Block 0x56, offset 0x57 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xa0, hi: 0xbf}, - // Block 0x57, offset 0x58 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xbf}, - // Block 0x58, offset 0x59 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xaa}, - // Block 0x59, offset 0x5a - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x8c, hi: 0x8c}, - // Block 0x5a, offset 0x5b - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xb4, hi: 0xb6}, - // Block 0x5b, offset 0x5c - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0x9c, hi: 0x9c}, - // Block 0x5c, offset 0x5d - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xbc, hi: 0xbd}, - // Block 0x5d, offset 0x5e - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0xaf, hi: 0xb1}, - // Block 0x5e, offset 0x5f - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0xaf, hi: 0xaf}, - {value: 0x0009, lo: 0xbf, hi: 0xbf}, - // Block 0x5f, offset 0x60 - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0xa0, hi: 0xbf}, - // Block 0x60, offset 0x61 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x9f, hi: 0x9f}, - // Block 0x61, offset 0x62 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xb3, hi: 0xb3}, - // Block 0x62, offset 0x63 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0x95}, - // Block 0x63, offset 0x64 - {value: 0x0000, lo: 0x08}, - {value: 0x5000, lo: 0x80, hi: 0x80}, - {value: 0x00da, lo: 0xaa, hi: 0xaa}, - {value: 0x00e4, lo: 0xab, hi: 0xab}, - {value: 0x00e8, lo: 0xac, hi: 0xac}, - {value: 0x00de, lo: 0xad, hi: 0xad}, - {value: 0x00e0, lo: 0xae, hi: 0xaf}, - {value: 0x5000, lo: 0xb6, hi: 0xb6}, - {value: 0x5000, lo: 0xb8, hi: 0xba}, - // Block 0x64, offset 0x65 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xb1, hi: 0xbf}, - // Block 0x65, offset 0x66 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x8e}, - {value: 0x5000, lo: 0x92, hi: 0x9f}, - // Block 0x66, offset 0x67 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x9e}, - {value: 0x5000, lo: 0xa0, hi: 0xbf}, - // Block 0x67, offset 0x68 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x87}, - {value: 0x5000, lo: 0x90, hi: 0xbe}, - // Block 0x68, offset 0x69 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xbe}, - // Block 0x69, offset 0x6a - {value: 0x0000, lo: 0x02}, - {value: 0x00e6, lo: 0xaf, hi: 0xaf}, - {value: 0x00e6, lo: 0xbc, hi: 0xbd}, - // Block 0x6a, offset 0x6b - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0xb0, hi: 0xb1}, - // Block 0x6b, offset 0x6c - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0xb0, hi: 0xb0}, - // Block 0x6c, offset 0x6d - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0x86, hi: 0x86}, - // Block 0x6d, offset 0x6e - {value: 0x0000, lo: 0x02}, - {value: 0x0009, lo: 0x84, hi: 0x84}, - {value: 0x00e6, lo: 0xa0, hi: 0xb1}, - // Block 0x6e, offset 0x6f - {value: 0x0000, lo: 0x01}, - {value: 0x00dc, lo: 0xab, hi: 0xad}, - // Block 0x6f, offset 0x70 - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0x93, hi: 0x93}, - // Block 0x70, offset 0x71 - {value: 0x0000, lo: 0x01}, - {value: 0x0007, lo: 0xb3, hi: 0xb3}, - // Block 0x71, offset 0x72 - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0x80, hi: 0x80}, - // Block 0x72, offset 0x73 - {value: 0x0000, lo: 0x05}, - {value: 0x00e6, lo: 0xb0, hi: 0xb0}, - {value: 0x00e6, lo: 0xb2, hi: 0xb3}, - {value: 0x00dc, lo: 0xb4, hi: 0xb4}, - {value: 0x00e6, lo: 0xb7, hi: 0xb8}, - {value: 0x00e6, lo: 0xbe, hi: 0xbf}, - // Block 0x73, offset 0x74 - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0x81, hi: 0x81}, - // Block 0x74, offset 0x75 - {value: 0x0000, lo: 0x01}, - {value: 0x0009, lo: 0xad, hi: 0xad}, - // Block 0x75, offset 0x76 - {value: 0x0000, lo: 0x01}, - {value: 0x1100, lo: 0x80, hi: 0xbf}, - // Block 0x76, offset 0x77 - {value: 0x0000, lo: 0x01}, - {value: 0x1100, lo: 0x80, hi: 0xa3}, - // Block 0x77, offset 0x78 - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0x80, hi: 0xbf}, - // Block 0x78, offset 0x79 - {value: 0x0000, lo: 0x09}, - {value: 0x5500, lo: 0x80, hi: 0x8d}, - {value: 0x5500, lo: 0x90, hi: 0x90}, - {value: 0x5500, lo: 0x92, hi: 0x92}, - {value: 0x5500, lo: 0x95, hi: 0x9e}, - {value: 0x5500, lo: 0xa0, hi: 0xa0}, - {value: 0x5500, lo: 0xa2, hi: 0xa2}, - {value: 0x5500, lo: 0xa5, hi: 0xa6}, - {value: 0x5500, lo: 0xaa, hi: 0xad}, - {value: 0x5500, lo: 0xb0, hi: 0xbf}, - // Block 0x79, offset 0x7a - {value: 0x0000, lo: 0x02}, - {value: 0x5500, lo: 0x80, hi: 0xad}, - {value: 0x5500, lo: 0xb0, hi: 0xbf}, - // Block 0x7a, offset 0x7b - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0x80, hi: 0x99}, - // Block 0x7b, offset 0x7c - {value: 0x0000, lo: 0x09}, - {value: 0x5000, lo: 0x80, hi: 0x86}, - {value: 0x5000, lo: 0x93, hi: 0x97}, - {value: 0x5500, lo: 0x9d, hi: 0x9d}, - {value: 0x001a, lo: 0x9e, hi: 0x9e}, - {value: 0x5500, lo: 0x9f, hi: 0x9f}, - {value: 0x5000, lo: 0xa0, hi: 0xa9}, - {value: 0x5500, lo: 0xaa, hi: 0xb6}, - {value: 0x5500, lo: 0xb8, hi: 0xbc}, - {value: 0x5500, lo: 0xbe, hi: 0xbe}, - // Block 0x7c, offset 0x7d - {value: 0x0000, lo: 0x04}, - {value: 0x5500, lo: 0x80, hi: 0x81}, - {value: 0x5500, lo: 0x83, hi: 0x84}, - {value: 0x5500, lo: 0x86, hi: 0x8e}, - {value: 0x5000, lo: 0x8f, hi: 0xbf}, - // Block 0x7d, offset 0x7e - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xb1}, - // Block 0x7e, offset 0x7f - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x93, hi: 0xbf}, - // Block 0x7f, offset 0x80 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xbd}, - // Block 0x80, offset 0x81 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x90, hi: 0xbf}, - // Block 0x81, offset 0x82 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x8f}, - {value: 0x5000, lo: 0x92, hi: 0xbf}, - // Block 0x82, offset 0x83 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x87}, - {value: 0x5000, lo: 0xb0, hi: 0xbc}, - // Block 0x83, offset 0x84 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0x90, hi: 0x99}, - {value: 0x00e6, lo: 0xa0, hi: 0xa6}, - {value: 0x5000, lo: 0xb0, hi: 0xbf}, - // Block 0x84, offset 0x85 - {value: 0x0000, lo: 0x07}, - {value: 0x5000, lo: 0x80, hi: 0x84}, - {value: 0x5000, lo: 0x87, hi: 0x92}, - {value: 0x5000, lo: 0x94, hi: 0xa6}, - {value: 0x5000, lo: 0xa8, hi: 0xab}, - {value: 0x5000, lo: 0xb0, hi: 0xb2}, - {value: 0x5000, lo: 0xb4, hi: 0xb4}, - {value: 0x5000, lo: 0xb6, hi: 0xbf}, - // Block 0x85, offset 0x86 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0xbc}, - // Block 0x86, offset 0x87 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x81, hi: 0xbf}, - // Block 0x87, offset 0x88 - {value: 0x0000, lo: 0x06}, - {value: 0x5000, lo: 0x82, hi: 0x87}, - {value: 0x5000, lo: 0x8a, hi: 0x8f}, - {value: 0x5000, lo: 0x92, hi: 0x97}, - {value: 0x5000, lo: 0x9a, hi: 0x9c}, - {value: 0x5000, lo: 0xa0, hi: 0xa6}, - {value: 0x5000, lo: 0xa8, hi: 0xae}, - // Block 0x88, offset 0x89 - {value: 0x0000, lo: 0x01}, - {value: 0x00dc, lo: 0xbd, hi: 0xbd}, - // Block 0x89, offset 0x8a - {value: 0x00db, lo: 0x05}, - {value: 0x00dc, lo: 0x8d, hi: 0x8d}, - {value: 0x00e6, lo: 0x8f, hi: 0x8f}, - {value: 0x00e6, lo: 0xb8, hi: 0xb8}, - {value: 0x0001, lo: 0xb9, hi: 0xba}, - {value: 0x0009, lo: 0xbf, hi: 0xbf}, - // Block 0x8a, offset 0x8b - {value: 0x65fe, lo: 0x07}, - {value: 0x8800, lo: 0x99, hi: 0x99}, - {value: 0x1100, lo: 0x9a, hi: 0x9a}, - {value: 0x8800, lo: 0x9b, hi: 0x9b}, - {value: 0x1100, lo: 0x9c, hi: 0x9c}, - {value: 0x8800, lo: 0xa5, hi: 0xa5}, - {value: 0x1100, lo: 0xab, hi: 0xab}, - {value: 0x0009, lo: 0xb9, hi: 0xba}, - // Block 0x8b, offset 0x8c - {value: 0x0000, lo: 0x06}, - {value: 0x5500, lo: 0x9e, hi: 0xa4}, - {value: 0x00d8, lo: 0xa5, hi: 0xa6}, - {value: 0x0001, lo: 0xa7, hi: 0xa9}, - {value: 0x00e2, lo: 0xad, hi: 0xad}, - {value: 0x00d8, lo: 0xae, hi: 0xb2}, - {value: 0x00dc, lo: 0xbb, hi: 0xbf}, - // Block 0x8c, offset 0x8d - {value: 0x0000, lo: 0x05}, - {value: 0x00dc, lo: 0x80, hi: 0x82}, - {value: 0x00e6, lo: 0x85, hi: 0x89}, - {value: 0x00dc, lo: 0x8a, hi: 0x8b}, - {value: 0x00e6, lo: 0xaa, hi: 0xad}, - {value: 0x5500, lo: 0xbb, hi: 0xbf}, - // Block 0x8d, offset 0x8e - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0x80, hi: 0x80}, - // Block 0x8e, offset 0x8f - {value: 0x0000, lo: 0x01}, - {value: 0x00e6, lo: 0x82, hi: 0x84}, - // Block 0x8f, offset 0x90 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x94}, - {value: 0x5000, lo: 0x96, hi: 0xbf}, - // Block 0x90, offset 0x91 - {value: 0x0000, lo: 0x08}, - {value: 0x5000, lo: 0x80, hi: 0x9c}, - {value: 0x5000, lo: 0x9e, hi: 0x9f}, - {value: 0x5000, lo: 0xa2, hi: 0xa2}, - {value: 0x5000, lo: 0xa5, hi: 0xa6}, - {value: 0x5000, lo: 0xa9, hi: 0xac}, - {value: 0x5000, lo: 0xae, hi: 0xb9}, - {value: 0x5000, lo: 0xbb, hi: 0xbb}, - {value: 0x5000, lo: 0xbd, hi: 0xbf}, - // Block 0x91, offset 0x92 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x83}, - {value: 0x5000, lo: 0x85, hi: 0xbf}, - // Block 0x92, offset 0x93 - {value: 0x0000, lo: 0x06}, - {value: 0x5000, lo: 0x80, hi: 0x85}, - {value: 0x5000, lo: 0x87, hi: 0x8a}, - {value: 0x5000, lo: 0x8d, hi: 0x94}, - {value: 0x5000, lo: 0x96, hi: 0x9c}, - {value: 0x5000, lo: 0x9e, hi: 0xb9}, - {value: 0x5000, lo: 0xbb, hi: 0xbe}, - // Block 0x93, offset 0x94 - {value: 0x0000, lo: 0x04}, - {value: 0x5000, lo: 0x80, hi: 0x84}, - {value: 0x5000, lo: 0x86, hi: 0x86}, - {value: 0x5000, lo: 0x8a, hi: 0x90}, - {value: 0x5000, lo: 0x92, hi: 0xbf}, - // Block 0x94, offset 0x95 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0xa5}, - {value: 0x5000, lo: 0xa8, hi: 0xbf}, - // Block 0x95, offset 0x96 - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x8b}, - {value: 0x5000, lo: 0x8e, hi: 0xbf}, - // Block 0x96, offset 0x97 - {value: 0x0000, lo: 0x03}, - {value: 0x5000, lo: 0x80, hi: 0x8a}, - {value: 0x5000, lo: 0x90, hi: 0xae}, - {value: 0x5000, lo: 0xb0, hi: 0xbf}, - // Block 0x97, offset 0x98 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x80, hi: 0x8f}, - // Block 0x98, offset 0x99 - {value: 0x0000, lo: 0x01}, - {value: 0x5000, lo: 0x90, hi: 0x90}, - // Block 0x99, offset 0x9a - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x82}, - {value: 0x5000, lo: 0x90, hi: 0xba}, - // Block 0x9a, offset 0x9b - {value: 0x0000, lo: 0x02}, - {value: 0x5000, lo: 0x80, hi: 0x88}, - {value: 0x5000, lo: 0x90, hi: 0x91}, - // Block 0x9b, offset 0x9c - {value: 0x0000, lo: 0x01}, - {value: 0x5500, lo: 0x80, hi: 0x9d}, -} - -// charInfoLookup: 1152 bytes -// Block 0 is the null block. -var charInfoLookup = [1152]uint8{ - // Block 0x0, offset 0x0 - // Block 0x1, offset 0x40 - // Block 0x2, offset 0x80 - // Block 0x3, offset 0xc0 - 0x0c2: 0x10, 0x0c3: 0x03, 0x0c4: 0x11, 0x0c5: 0x12, 0x0c6: 0x13, 0x0c7: 0x14, - 0x0c8: 0x15, 0x0ca: 0x16, 0x0cb: 0x17, 0x0cc: 0x04, 0x0cd: 0x05, 0x0ce: 0x06, 0x0cf: 0x18, - 0x0d0: 0x07, 0x0d1: 0x19, 0x0d2: 0x1a, 0x0d3: 0x1b, 0x0d6: 0x08, 0x0d7: 0x1c, - 0x0d8: 0x1d, 0x0d9: 0x09, 0x0db: 0x1e, 0x0dc: 0x1f, 0x0dd: 0x20, 0x0df: 0x21, - 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, - 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, - 0x0f0: 0x11, - // Block 0x4, offset 0x100 - 0x120: 0x22, 0x121: 0x23, 0x124: 0x24, 0x125: 0x25, 0x126: 0x26, 0x127: 0x27, - 0x128: 0x28, 0x129: 0x29, 0x12a: 0x2a, 0x12b: 0x2b, 0x12c: 0x26, 0x12d: 0x2c, 0x12e: 0x2d, 0x12f: 0x2e, - 0x131: 0x2f, 0x132: 0x30, 0x133: 0x31, 0x134: 0x32, 0x135: 0x2e, 0x137: 0x33, - 0x138: 0x34, 0x139: 0x35, 0x13a: 0x36, 0x13b: 0x37, 0x13c: 0x38, 0x13d: 0x39, 0x13e: 0x3a, 0x13f: 0x3b, - // Block 0x5, offset 0x140 - 0x140: 0x3c, 0x142: 0x3d, 0x143: 0x3e, 0x144: 0x3f, 0x145: 0x40, 0x146: 0x41, 0x147: 0x42, - 0x14d: 0x43, - 0x15c: 0x44, 0x15f: 0x45, - 0x162: 0x46, 0x164: 0x47, - 0x168: 0x48, 0x169: 0x49, 0x16c: 0x4a, 0x16d: 0x4b, 0x16e: 0x4c, 0x16f: 0x4d, - 0x170: 0x4e, 0x173: 0x4f, 0x174: 0x50, 0x175: 0x51, 0x176: 0x52, 0x177: 0x53, - 0x178: 0x54, 0x179: 0x55, 0x17a: 0x56, 0x17b: 0x57, 0x17c: 0x58, 0x17d: 0x0a, 0x17e: 0x59, 0x17f: 0x0b, - // Block 0x6, offset 0x180 - 0x180: 0x5a, 0x181: 0x5b, 0x182: 0x5c, 0x183: 0x5d, 0x184: 0x5e, 0x185: 0x5f, 0x186: 0x60, 0x187: 0x61, - 0x188: 0x62, 0x189: 0x0c, 0x18a: 0x63, 0x18b: 0x64, 0x18c: 0x65, - 0x191: 0x66, 0x192: 0x67, 0x193: 0x68, - 0x1a8: 0x69, 0x1a9: 0x6a, 0x1ab: 0x6b, - 0x1b1: 0x6c, 0x1b3: 0x6d, 0x1b5: 0x6e, 0x1b7: 0x6f, - 0x1ba: 0x70, 0x1bb: 0x71, 0x1bc: 0x67, 0x1bd: 0x67, 0x1be: 0x67, 0x1bf: 0x72, - // Block 0x7, offset 0x1c0 - 0x1c0: 0x73, 0x1c1: 0x0d, 0x1c2: 0x0e, 0x1c3: 0x0f, 0x1c4: 0x74, 0x1c5: 0x67, 0x1c6: 0x75, - 0x1c8: 0x76, 0x1c9: 0x77, 0x1ca: 0x67, 0x1cb: 0x78, 0x1cc: 0x67, 0x1cd: 0x67, 0x1ce: 0x67, 0x1cf: 0x67, - // Block 0x8, offset 0x200 - 0x219: 0x79, 0x21b: 0x7a, 0x21d: 0x7b, - 0x220: 0x7c, 0x223: 0x7d, 0x224: 0x7e, 0x225: 0x7f, 0x226: 0x80, 0x227: 0x81, - 0x22a: 0x82, 0x22b: 0x83, 0x22f: 0x84, - 0x230: 0x85, 0x231: 0x85, 0x232: 0x85, 0x233: 0x85, 0x234: 0x85, 0x235: 0x85, 0x236: 0x85, 0x237: 0x85, - 0x238: 0x85, 0x239: 0x85, 0x23a: 0x85, 0x23b: 0x85, 0x23c: 0x85, 0x23d: 0x85, 0x23e: 0x85, 0x23f: 0x85, - // Block 0x9, offset 0x240 - 0x240: 0x85, 0x241: 0x85, 0x242: 0x85, 0x243: 0x85, 0x244: 0x85, 0x245: 0x85, 0x246: 0x85, 0x247: 0x85, - 0x248: 0x85, 0x249: 0x85, 0x24a: 0x85, 0x24b: 0x85, 0x24c: 0x85, 0x24d: 0x85, 0x24e: 0x85, 0x24f: 0x85, - 0x250: 0x85, 0x251: 0x85, 0x252: 0x85, 0x253: 0x85, 0x254: 0x85, 0x255: 0x85, 0x256: 0x85, 0x257: 0x85, - 0x258: 0x85, 0x259: 0x85, 0x25a: 0x85, 0x25b: 0x85, 0x25c: 0x85, 0x25d: 0x85, 0x25e: 0x85, 0x25f: 0x85, - 0x260: 0x85, 0x261: 0x85, 0x262: 0x85, 0x263: 0x85, 0x264: 0x85, 0x265: 0x85, 0x266: 0x85, 0x267: 0x85, - 0x268: 0x85, 0x269: 0x85, 0x26a: 0x85, 0x26b: 0x85, 0x26c: 0x85, 0x26d: 0x85, 0x26e: 0x85, 0x26f: 0x85, - 0x270: 0x85, 0x271: 0x85, 0x272: 0x85, 0x273: 0x85, 0x274: 0x85, 0x275: 0x85, 0x276: 0x85, 0x277: 0x85, - 0x278: 0x85, 0x279: 0x85, 0x27a: 0x85, 0x27b: 0x85, 0x27c: 0x85, 0x27d: 0x85, 0x27e: 0x85, 0x27f: 0x85, - // Block 0xa, offset 0x280 - 0x280: 0x85, 0x281: 0x85, 0x282: 0x85, 0x283: 0x85, 0x284: 0x85, 0x285: 0x85, 0x286: 0x85, 0x287: 0x85, - 0x288: 0x85, 0x289: 0x85, 0x28a: 0x85, 0x28b: 0x85, 0x28c: 0x85, 0x28d: 0x85, 0x28e: 0x85, 0x28f: 0x85, - 0x290: 0x85, 0x291: 0x85, 0x292: 0x85, 0x293: 0x85, 0x294: 0x85, 0x295: 0x85, 0x296: 0x85, 0x297: 0x85, - 0x298: 0x85, 0x299: 0x85, 0x29a: 0x85, 0x29b: 0x85, 0x29c: 0x85, 0x29d: 0x85, 0x29e: 0x86, - // Block 0xb, offset 0x2c0 - 0x2e4: 0x87, 0x2e5: 0x87, 0x2e6: 0x87, 0x2e7: 0x87, - 0x2e8: 0x88, 0x2e9: 0x89, 0x2ea: 0x87, 0x2eb: 0x8a, 0x2ec: 0x8b, 0x2ed: 0x8c, 0x2ee: 0x8d, 0x2ef: 0x8e, - 0x2f0: 0x67, 0x2f1: 0x67, 0x2f2: 0x67, 0x2f3: 0x67, 0x2f4: 0x8f, 0x2f5: 0x90, 0x2f6: 0x91, 0x2f7: 0x92, - 0x2f8: 0x93, 0x2f9: 0x94, 0x2fa: 0x67, 0x2fb: 0x95, 0x2fc: 0x96, 0x2fd: 0x67, 0x2fe: 0x78, 0x2ff: 0x97, - // Block 0xc, offset 0x300 - 0x307: 0x98, - 0x328: 0x99, - // Block 0xd, offset 0x340 - 0x341: 0x7c, 0x342: 0x9a, - // Block 0xe, offset 0x380 - 0x385: 0x9b, 0x386: 0x9c, 0x387: 0x9d, - 0x389: 0x9e, - 0x390: 0x67, 0x391: 0x9f, 0x392: 0xa0, 0x393: 0xa1, 0x394: 0xa2, 0x395: 0xa3, 0x396: 0x67, 0x397: 0x67, - 0x398: 0x67, 0x399: 0x67, 0x39a: 0xa4, 0x39b: 0x67, 0x39c: 0x67, 0x39d: 0x67, 0x39e: 0x67, 0x39f: 0xa5, - // Block 0xf, offset 0x3c0 - 0x3c4: 0xa6, 0x3c5: 0xa7, 0x3c6: 0xa8, - 0x3c8: 0xa9, 0x3c9: 0xaa, - // Block 0x10, offset 0x400 - 0x420: 0x87, 0x421: 0x87, 0x422: 0x87, 0x423: 0x87, 0x424: 0x87, 0x425: 0x87, 0x426: 0x87, 0x427: 0x87, - 0x428: 0xab, - // Block 0x11, offset 0x440 - 0x450: 0x0c, 0x451: 0x0d, - 0x45d: 0x0e, 0x45f: 0x0f, - 0x46f: 0x10, -} - -var charInfoTrie = trie{charInfoLookup[:], charInfoValues[:], charInfoSparseValues[:], charInfoSparseOffset[:], 16} - -// Total size of tables: 48KB (48736 bytes) +// Total size of tables: 50KB (50848 bytes) diff --git a/libgo/go/exp/norm/triegen.go b/libgo/go/exp/norm/triegen.go index 4ad9e0e057c..2e275a06254 100644 --- a/libgo/go/exp/norm/triegen.go +++ b/libgo/go/exp/norm/triegen.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + // Trie table generator. // Used by make*tables tools to generate a go file with trie data structures // for mapping UTF-8 to a 16-bit value. All but the last byte in a UTF-8 byte diff --git a/libgo/go/exp/proxy/per_host.go b/libgo/go/exp/proxy/per_host.go index 397ef57cd92..0c627e9ab54 100644 --- a/libgo/go/exp/proxy/per_host.go +++ b/libgo/go/exp/proxy/per_host.go @@ -75,7 +75,7 @@ func (p *PerHost) dialerForRequest(host string) Dialer { } // AddFromString parses a string that contains comma-separated values -// specifing hosts that should use the bypass proxy. Each value is either an +// specifying hosts that should use the bypass proxy. Each value is either an // IP address, a CIDR range, a zone (*.example.com) or a hostname // (localhost). A best effort is made to parse the string and errors are // ignored. diff --git a/libgo/go/exp/proxy/socks5.go b/libgo/go/exp/proxy/socks5.go index 466e135eb10..62fa5c9296d 100644 --- a/libgo/go/exp/proxy/socks5.go +++ b/libgo/go/exp/proxy/socks5.go @@ -98,9 +98,9 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, socks5Version) if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { - buf = append(buf, 2, /* num auth methods */ socks5AuthNone, socks5AuthPassword) + buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) } else { - buf = append(buf, 1, /* num auth methods */ socks5AuthNone) + buf = append(buf, 1 /* num auth methods */, socks5AuthNone) } if _, err = conn.Write(buf); err != nil { @@ -139,7 +139,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { } buf = buf[:0] - buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */ ) + buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) if ip := net.ParseIP(host); ip != nil { if len(ip) == 4 { diff --git a/libgo/go/exp/signal/signal.go b/libgo/go/exp/signal/signal.go deleted file mode 100644 index bce4530e7bc..00000000000 --- a/libgo/go/exp/signal/signal.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin freebsd linux netbsd openbsd - -// Package signal implements operating system-independent signal handling. -package signal - -import ( - "os" - "runtime" -) - -// Incoming is the global signal channel. -// All signals received by the program will be delivered to this channel. -var Incoming <-chan os.Signal - -func process(ch chan<- os.Signal) { - for { - var mask uint32 = runtime.Sigrecv() - for sig := uint(0); sig < 32; sig++ { - if mask&(1<<sig) != 0 { - ch <- os.UnixSignal(sig) - } - } - } -} - -func init() { - runtime.Siginit() - ch := make(chan os.Signal) // Done here so Incoming can have type <-chan Signal - Incoming = ch - go process(ch) -} - -// BUG(rsc): This package is unavailable on Plan 9 and Windows. diff --git a/libgo/go/exp/signal/signal_test.go b/libgo/go/exp/signal/signal_test.go deleted file mode 100644 index a7cecb38256..00000000000 --- a/libgo/go/exp/signal/signal_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin freebsd linux netbsd openbsd - -package signal - -import ( - "os" - "syscall" - "testing" -) - -const sighup = os.UnixSignal(syscall.SIGHUP) - -func TestSignal(t *testing.T) { - // Send this process a SIGHUP. - syscall.Syscall(syscall.SYS_KILL, uintptr(syscall.Getpid()), syscall.SIGHUP, 0) - - if sig := (<-Incoming).(os.UnixSignal); sig != sighup { - t.Errorf("signal was %v, want %v", sig, sighup) - } -} diff --git a/libgo/go/exp/terminal/terminal.go b/libgo/go/exp/terminal/terminal.go index c3ba5bde2ee..c1ed0c0c443 100644 --- a/libgo/go/exp/terminal/terminal.go +++ b/libgo/go/exp/terminal/terminal.go @@ -389,12 +389,12 @@ func (t *Terminal) Write(buf []byte) (n int, err error) { // We have a prompt and possibly user input on the screen. We // have to clear it first. - t.move(0, /* up */ 0, /* down */ t.cursorX, /* left */ 0 /* right */ ) + t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) t.cursorX = 0 t.clearLineToRight() for t.cursorY > 0 { - t.move(1, /* up */ 0, 0, 0) + t.move(1 /* up */, 0, 0, 0) t.cursorY-- t.clearLineToRight() } diff --git a/libgo/go/exp/types/check.go b/libgo/go/exp/types/check.go index 09e29d1261a..ae0beb4e9b0 100644 --- a/libgo/go/exp/types/check.go +++ b/libgo/go/exp/types/check.go @@ -17,14 +17,14 @@ import ( const debug = false type checker struct { - fset *token.FileSet - scanner.ErrorVector - types map[ast.Expr]Type + fset *token.FileSet + errors scanner.ErrorList + types map[ast.Expr]Type } func (c *checker) errorf(pos token.Pos, format string, args ...interface{}) string { msg := fmt.Sprintf(format, args...) - c.Error(c.fset.Position(pos), msg) + c.errors.Add(c.fset.Position(pos), msg) return msg } @@ -221,5 +221,6 @@ func Check(fset *token.FileSet, pkg *ast.Package) (types map[ast.Expr]Type, err c.checkObj(obj, false) } - return c.types, c.GetError(scanner.NoMultiples) + c.errors.RemoveMultiples() + return c.types, c.errors.Err() } diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go index a573fbb2463..cb996f28055 100644 --- a/libgo/go/exp/types/gcimporter.go +++ b/libgo/go/exp/types/gcimporter.go @@ -11,20 +11,20 @@ import ( "errors" "fmt" "go/ast" + "go/build" "go/token" "io" "math/big" "os" "path/filepath" - "runtime" "strconv" + "strings" "text/scanner" ) const trace = false // set to true for debugging var ( - pkgRoot = filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH) pkgExts = [...]string{".a", ".5", ".6", ".8"} ) @@ -39,8 +39,15 @@ func findPkg(path string) (filename, id string) { var noext string switch path[0] { default: - // "x" -> "$GOROOT/pkg/$GOOS_$GOARCH/x.ext", "x" - noext = filepath.Join(pkgRoot, path) + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + bp, _ := build.Import(path, "", build.FindOnly) + if bp.PkgObj == "" { + return + } + noext = bp.PkgObj + if strings.HasSuffix(noext, ".a") { + noext = noext[:len(noext)-2] + } case '.': // "./x" -> "/this/directory/x.ext", "/this/directory/x" @@ -739,7 +746,7 @@ func (p *gcParser) parseVarDecl() { } // FuncBody = "{" ... "}" . -// +// func (p *gcParser) parseFuncBody() { p.expect('{') for i := 1; i > 0; p.next() { diff --git a/libgo/go/exp/types/gcimporter_test.go b/libgo/go/exp/types/gcimporter_test.go index 912d467ea08..c229b50113d 100644 --- a/libgo/go/exp/types/gcimporter_test.go +++ b/libgo/go/exp/types/gcimporter_test.go @@ -6,7 +6,9 @@ package types import ( "go/ast" + "go/build" "io/ioutil" + "os" "os/exec" "path/filepath" "runtime" @@ -31,7 +33,7 @@ func init() { gcPath = gcName return } - gcPath = filepath.Join(runtime.GOROOT(), "/bin/tool/", gcName) + gcPath = filepath.Join(build.ToolDir, gcName) } func compile(t *testing.T, dirname, filename string) { @@ -61,7 +63,7 @@ func testPath(t *testing.T, path string) bool { const maxTime = 3 * time.Second func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) { - dirname := filepath.Join(pkgRoot, dir) + dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir) list, err := ioutil.ReadDir(dirname) if err != nil { t.Errorf("testDir(%s): %s", dirname, err) @@ -90,6 +92,13 @@ func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) { } func TestGcImport(t *testing.T) { + // On cross-compile builds, the path will not exist. + // Need to use GOHOSTOS, which is not available. + if _, err := os.Stat(gcPath); err != nil { + t.Logf("skipping test: %v", err) + return + } + compile(t, "testdata", "exports.go") nimports := 0 diff --git a/libgo/go/exp/types/types.go b/libgo/go/exp/types/types.go index 3aa896892e3..85d244cf04a 100644 --- a/libgo/go/exp/types/types.go +++ b/libgo/go/exp/types/types.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// PACKAGE UNDER CONSTRUCTION. ANY AND ALL PARTS MAY CHANGE. -// Package types declares the types used to represent Go types. +// Package types declares the types used to represent Go types +// (UNDER CONSTRUCTION). ANY AND ALL PARTS MAY CHANGE. // package types diff --git a/libgo/go/exp/winfsnotify/winfsnotify_test.go b/libgo/go/exp/winfsnotify/winfsnotify_test.go index 59ac1624a26..4a1929a8397 100644 --- a/libgo/go/exp/winfsnotify/winfsnotify_test.go +++ b/libgo/go/exp/winfsnotify/winfsnotify_test.go @@ -7,6 +7,7 @@ package winfsnotify import ( + "io/ioutil" "os" "testing" "time" @@ -115,7 +116,13 @@ func TestNotifyClose(t *testing.T) { t.Fatal("double Close() test failed: second Close() call didn't return") } - err := watcher.Watch("_test") + dir, err := ioutil.TempDir("", "wininotify") + if err != nil { + t.Fatalf("TempDir failed: %s", err) + } + defer os.RemoveAll(dir) + + err = watcher.Watch(dir) if err == nil { t.Fatal("expected error on Watch() after Close(), got nil") } diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 1b02f52baa9..f34df59422f 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -423,6 +423,7 @@ var fmttests = []struct { {"p0=%p", new(int), "p0=0xPTR"}, {"p1=%s", &pValue, "p1=String(p)"}, // String method... {"p2=%p", &pValue, "p2=0xPTR"}, // ... not called with %p + {"p3=%p", (*int)(nil), "p3=0x0"}, {"p4=%#p", new(int), "p4=PTR"}, // %p on non-pointers @@ -431,6 +432,14 @@ var fmttests = []struct { {"%p", make([]int, 1), "0xPTR"}, {"%p", 27, "%!p(int=27)"}, // not a pointer at all + // %q on pointers + {"%q", (*int)(nil), "%!q(*int=<nil>)"}, + {"%q", new(int), "%!q(*int=0xPTR)"}, + + // %v on pointers formats 0 as <nil> + {"%v", (*int)(nil), "<nil>"}, + {"%v", new(int), "0xPTR"}, + // %d on Stringer should give integer if possible {"%s", time.Time{}.Month(), "January"}, {"%d", time.Time{}.Month(), "1"}, diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 3b7d3464e20..c3ba2f339e5 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -553,6 +553,14 @@ func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) { } func (p *pp) fmtPointer(value reflect.Value, verb rune, goSyntax bool) { + switch verb { + case 'p', 'v', 'b', 'd', 'o', 'x', 'X': + // ok + default: + p.badVerb(verb) + return + } + var u uintptr switch value.Kind() { case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: @@ -561,6 +569,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune, goSyntax bool) { p.badVerb(verb) return } + if goSyntax { p.add('(') p.buf.WriteString(value.Type().String()) @@ -572,6 +581,8 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune, goSyntax bool) { p.fmt0x64(uint64(u), true) } p.add(')') + } else if verb == 'v' && u == 0 { + p.buf.Write(nilAngleBytes) } else { p.fmt0x64(uint64(u), !p.fmt.sharp) } @@ -929,24 +940,7 @@ BigSwitch: break BigSwitch } } - if goSyntax { - p.buf.WriteByte('(') - p.buf.WriteString(value.Type().String()) - p.buf.WriteByte(')') - p.buf.WriteByte('(') - if v == 0 { - p.buf.Write(nilBytes) - } else { - p.fmt0x64(uint64(v), true) - } - p.buf.WriteByte(')') - break - } - if v == 0 { - p.buf.Write(nilAngleBytes) - break - } - p.fmt0x64(uint64(v), true) + fallthrough case reflect.Chan, reflect.Func, reflect.UnsafePointer: p.fmtPointer(value, verb, goSyntax) default: diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 36c6aebad0e..fa9a5584a88 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -512,7 +512,7 @@ func (s *ss) scanBool(verb rune) bool { } return true case 'f', 'F': - if s.accept("aL") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) { + if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) { s.error(boolError) } return false diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index b26c828cbfc..61b48f9cc6d 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -317,6 +317,7 @@ var overflowTests = []ScanTest{ {"(1-1e500i)", &complex128Val, 0}, } +var truth bool var i, j, k int var f float64 var s, t string @@ -350,6 +351,9 @@ var multiTests = []ScanfMultiTest{ // Bad UTF-8: should see every byte. {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""}, + + // Fixed bugs + {"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""}, } func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) { diff --git a/libgo/go/go/ast/print.go b/libgo/go/go/ast/print.go index f6c63c0d889..02cf9e02234 100644 --- a/libgo/go/go/ast/print.go +++ b/libgo/go/go/ast/print.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file contains printing suppport for ASTs. +// This file contains printing support for ASTs. package ast diff --git a/libgo/go/go/ast/resolve.go b/libgo/go/go/ast/resolve.go index c7c8e7c101e..908e61c5da0 100644 --- a/libgo/go/go/ast/resolve.go +++ b/libgo/go/go/ast/resolve.go @@ -14,12 +14,12 @@ import ( ) type pkgBuilder struct { - scanner.ErrorVector - fset *token.FileSet + fset *token.FileSet + errors scanner.ErrorList } func (p *pkgBuilder) error(pos token.Pos, msg string) { - p.Error(p.fset.Position(pos), msg) + p.errors.Add(p.fset.Position(pos), msg) } func (p *pkgBuilder) errorf(pos token.Pos, format string, args ...interface{}) { @@ -169,5 +169,6 @@ func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, pkgScope.Outer = universe // reset universe scope } - return &Package{pkgName, pkgScope, imports, files}, p.GetError(scanner.Sorted) + p.errors.Sort() + return &Package{pkgName, pkgScope, imports, files}, p.errors.Err() } diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index 68e8d342005..eece7610562 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -2,10 +2,948 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package build provides tools for building Go packages. package build -import "errors" +import ( + "bytes" + "errors" + "fmt" + "go/ast" + "go/doc" + "go/parser" + "go/token" + "io" + "io/ioutil" + "log" + "os" + pathpkg "path" + "path/filepath" + "runtime" + "sort" + "strconv" + "strings" + "unicode" +) + +// A Context specifies the supporting context for a build. +type Context struct { + GOARCH string // target architecture + GOOS string // target operating system + GOROOT string // Go root + GOPATH string // Go path + CgoEnabled bool // whether cgo can be used + BuildTags []string // additional tags to recognize in +build lines + UseAllFiles bool // use files regardless of +build lines, file names + Gccgo bool // assume use of gccgo when computing object paths + + // By default, Import uses the operating system's file system calls + // to read directories and files. To read from other sources, + // callers can set the following functions. They all have default + // behaviors that use the local file system, so clients need only set + // the functions whose behaviors they wish to change. + + // JoinPath joins the sequence of path fragments into a single path. + // If JoinPath is nil, Import uses filepath.Join. + JoinPath func(elem ...string) string + + // SplitPathList splits the path list into a slice of individual paths. + // If SplitPathList is nil, Import uses filepath.SplitList. + SplitPathList func(list string) []string + + // IsAbsPath reports whether path is an absolute path. + // If IsAbsPath is nil, Import uses filepath.IsAbs. + IsAbsPath func(path string) bool + + // IsDir reports whether the path names a directory. + // If IsDir is nil, Import calls os.Stat and uses the result's IsDir method. + IsDir func(path string) bool + + // HasSubdir reports whether dir is a subdirectory of + // (perhaps multiple levels below) root. + // If so, HasSubdir sets rel to a slash-separated path that + // can be joined to root to produce a path equivalent to dir. + // If HasSubdir is nil, Import uses an implementation built on + // filepath.EvalSymlinks. + HasSubdir func(root, dir string) (rel string, ok bool) + + // ReadDir returns a slice of os.FileInfo, sorted by Name, + // describing the content of the named directory. + // If ReadDir is nil, Import uses io.ReadDir. + ReadDir func(dir string) (fi []os.FileInfo, err error) + + // OpenFile opens a file (not a directory) for reading. + // If OpenFile is nil, Import uses os.Open. + OpenFile func(path string) (r io.ReadCloser, err error) +} + +// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join. +func (ctxt *Context) joinPath(elem ...string) string { + if f := ctxt.JoinPath; f != nil { + return f(elem...) + } + return filepath.Join(elem...) +} + +// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList. +func (ctxt *Context) splitPathList(s string) []string { + if f := ctxt.SplitPathList; f != nil { + return f(s) + } + return filepath.SplitList(s) +} + +// isAbsPath calls ctxt.IsAbsSPath (if not nil) or else filepath.IsAbs. +func (ctxt *Context) isAbsPath(path string) bool { + if f := ctxt.IsAbsPath; f != nil { + return f(path) + } + return filepath.IsAbs(path) +} + +// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat. +func (ctxt *Context) isDir(path string) bool { + if f := ctxt.IsDir; f != nil { + return f(path) + } + fi, err := os.Stat(path) + return err == nil && fi.IsDir() +} + +// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses +// the local file system to answer the question. +func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) { + if f := ctxt.HasSubdir; f != nil { + return f(root, dir) + } + + if p, err := filepath.EvalSymlinks(root); err == nil { + root = p + } + if p, err := filepath.EvalSymlinks(dir); err == nil { + dir = p + } + const sep = string(filepath.Separator) + root = filepath.Clean(root) + if !strings.HasSuffix(root, sep) { + root += sep + } + dir = filepath.Clean(dir) + if !strings.HasPrefix(dir, root) { + return "", false + } + return filepath.ToSlash(dir[len(root):]), true +} + +// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir. +func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) { + if f := ctxt.ReadDir; f != nil { + return f(path) + } + return ioutil.ReadDir(path) +} + +// openFile calls ctxt.OpenFile (if not nil) or else os.Open. +func (ctxt *Context) openFile(path string) (io.ReadCloser, error) { + if fn := ctxt.OpenFile; fn != nil { + return fn(path) + } + + f, err := os.Open(path) + if err != nil { + return nil, err // nil interface + } + return f, nil +} + +// isFile determines whether path is a file by trying to open it. +// It reuses openFile instead of adding another function to the +// list in Context. +func (ctxt *Context) isFile(path string) bool { + f, err := ctxt.openFile(path) + if err != nil { + return false + } + f.Close() + return true +} + +// gopath returns the list of Go path directories. +func (ctxt *Context) gopath() []string { + var all []string + for _, p := range ctxt.splitPathList(ctxt.GOPATH) { + if p == "" || p == ctxt.GOROOT { + // Empty paths are uninteresting. + // If the path is the GOROOT, ignore it. + // People sometimes set GOPATH=$GOROOT, which is useless + // but would cause us to find packages with import paths + // like "pkg/math". + // Do not get confused by this common mistake. + continue + } + all = append(all, p) + } + return all +} + +// SrcDirs returns a list of package source root directories. +// It draws from the current Go root and Go path but omits directories +// that do not exist. +func (ctxt *Context) SrcDirs() []string { + var all []string + if ctxt.GOROOT != "" { + dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg") + if ctxt.isDir(dir) { + all = append(all, dir) + } + } + for _, p := range ctxt.gopath() { + dir := ctxt.joinPath(p, "src") + if ctxt.isDir(dir) { + all = append(all, dir) + } + } + return all +} + +// Default is the default Context for builds. +// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables +// if set, or else the compiled code's GOARCH, GOOS, and GOROOT. +var Default Context = defaultContext() + +var cgoEnabled = map[string]bool{ + "darwin/386": true, + "darwin/amd64": true, + "linux/386": true, + "linux/amd64": true, + "freebsd/386": true, + "freebsd/amd64": true, + "windows/386": true, + "windows/amd64": true, +} + +func defaultContext() Context { + var c Context + + c.GOARCH = envOr("GOARCH", runtime.GOARCH) + c.GOOS = envOr("GOOS", runtime.GOOS) + c.GOROOT = runtime.GOROOT() + c.GOPATH = envOr("GOPATH", "") + + switch os.Getenv("CGO_ENABLED") { + case "1": + c.CgoEnabled = true + case "0": + c.CgoEnabled = false + default: + c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH] + } + + return c +} + +func envOr(name, def string) string { + s := os.Getenv(name) + if s == "" { + return def + } + return s +} + +// An ImportMode controls the behavior of the Import method. +type ImportMode uint + +const ( + // If FindOnly is set, Import stops after locating the directory + // that should contain the sources for a package. It does not + // read any files in the directory. + FindOnly ImportMode = 1 << iota + + // If AllowBinary is set, Import can be satisfied by a compiled + // package object without corresponding sources. + AllowBinary +) + +// A Package describes the Go package found in a directory. +type Package struct { + Dir string // directory containing package sources + Name string // package name + Doc string // documentation synopsis + ImportPath string // import path of package ("" if unknown) + Root string // root of Go tree where this package lives + SrcRoot string // package source root directory ("" if unknown) + PkgRoot string // package install root directory ("" if unknown) + BinDir string // command install directory ("" if unknown) + Goroot bool // package found in Go root + PkgObj string // installed .a file + + // Source files + GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string // .go source files that import "C" + CFiles []string // .c source files + HFiles []string // .h source files + SFiles []string // .s source files + + // Cgo directives + CgoPkgConfig []string // Cgo pkg-config directives + CgoCFLAGS []string // Cgo CFLAGS directives + CgoLDFLAGS []string // Cgo LDFLAGS directives + + // Dependency information + Imports []string // imports from GoFiles, CgoFiles + ImportPos map[string][]token.Position // line information for Imports + + // Test information + TestGoFiles []string // _test.go files in package + TestImports []string // imports from TestGoFiles + TestImportPos map[string][]token.Position // line information for TestImports + XTestGoFiles []string // _test.go files outside package + XTestImports []string // imports from XTestGoFiles + XTestImportPos map[string][]token.Position // line information for XTestImports +} + +// IsCommand reports whether the package is considered a +// command to be installed (not just a library). +// Packages named "main" are treated as commands. +func (p *Package) IsCommand() bool { + return p.Name == "main" +} + +// ImportDir is like Import but processes the Go package found in +// the named directory. +func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) { + return ctxt.Import(".", dir, mode) +} + +// Import returns details about the Go package named by the import path, +// interpreting local import paths relative to the src directory. If the path +// is a local import path naming a package that can be imported using a +// standard import path, the returned package will set p.ImportPath to +// that path. +// +// In the directory containing the package, .go, .c, .h, and .s files are +// considered part of the package except for: +// +// - .go files in package documentation +// - files starting with _ or . +// - files with build constraints not satisfied by the context +// +// If an error occurs, Import returns a non-nil error also returns a non-nil +// *Package containing partial information. +// +func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) { + p := &Package{ + ImportPath: path, + } + + var pkga string + if ctxt.Gccgo { + dir, elem := pathpkg.Split(p.ImportPath) + pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a" + } else { + pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a" + } + + binaryOnly := false + if IsLocalImport(path) { + if src == "" { + return p, fmt.Errorf("import %q: import relative to unknown directory", path) + } + if !ctxt.isAbsPath(path) { + p.Dir = ctxt.joinPath(src, path) + } + // Determine canonical import path, if any. + if ctxt.GOROOT != "" { + root := ctxt.joinPath(ctxt.GOROOT, "src", "pkg") + if sub, ok := ctxt.hasSubdir(root, p.Dir); ok { + p.Goroot = true + p.ImportPath = sub + p.Root = ctxt.GOROOT + goto Found + } + } + all := ctxt.gopath() + for i, root := range all { + rootsrc := ctxt.joinPath(root, "src") + if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok { + // We found a potential import path for dir, + // but check that using it wouldn't find something + // else first. + if ctxt.GOROOT != "" { + if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) { + goto Found + } + } + for _, earlyRoot := range all[:i] { + if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) { + goto Found + } + } + + // sub would not name some other directory instead of this one. + // Record it. + p.ImportPath = sub + p.Root = root + goto Found + } + } + // It's okay that we didn't find a root containing dir. + // Keep going with the information we have. + } else { + if strings.HasPrefix(path, "/") { + return p, fmt.Errorf("import %q: cannot import absolute path", path) + } + // Determine directory from import path. + if ctxt.GOROOT != "" { + dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path) + isDir := ctxt.isDir(dir) + binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) + if isDir || binaryOnly { + p.Dir = dir + p.Goroot = true + p.Root = ctxt.GOROOT + goto Found + } + } + for _, root := range ctxt.gopath() { + dir := ctxt.joinPath(root, "src", path) + isDir := ctxt.isDir(dir) + binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(root, pkga)) + if isDir || binaryOnly { + p.Dir = dir + p.Root = root + goto Found + } + } + return p, fmt.Errorf("import %q: cannot find package", path) + } + +Found: + if p.Root != "" { + if p.Goroot { + p.SrcRoot = ctxt.joinPath(p.Root, "src", "pkg") + } else { + p.SrcRoot = ctxt.joinPath(p.Root, "src") + } + p.PkgRoot = ctxt.joinPath(p.Root, "pkg") + p.BinDir = ctxt.joinPath(p.Root, "bin") + p.PkgObj = ctxt.joinPath(p.Root, pkga) + } + + if mode&FindOnly != 0 { + return p, nil + } + if binaryOnly && (mode&AllowBinary) != 0 { + return p, nil + } + + dirs, err := ctxt.readDir(p.Dir) + if err != nil { + return p, err + } + + var Sfiles []string // files with ".S" (capital S) + var firstFile string + imported := make(map[string][]token.Position) + testImported := make(map[string][]token.Position) + xTestImported := make(map[string][]token.Position) + fset := token.NewFileSet() + for _, d := range dirs { + if d.IsDir() { + continue + } + name := d.Name() + if strings.HasPrefix(name, "_") || + strings.HasPrefix(name, ".") { + continue + } + if !ctxt.UseAllFiles && !ctxt.goodOSArchFile(name) { + continue + } + + i := strings.LastIndex(name, ".") + if i < 0 { + i = len(name) + } + ext := name[i:] + switch ext { + case ".go", ".c", ".s", ".h", ".S": + // tentatively okay + default: + // skip + continue + } + + filename := ctxt.joinPath(p.Dir, name) + f, err := ctxt.openFile(filename) + if err != nil { + return p, err + } + data, err := ioutil.ReadAll(f) + f.Close() + if err != nil { + return p, fmt.Errorf("read %s: %v", filename, err) + } + + // Look for +build comments to accept or reject the file. + if !ctxt.UseAllFiles && !ctxt.shouldBuild(data) { + continue + } + + // Going to save the file. For non-Go files, can stop here. + switch ext { + case ".c": + p.CFiles = append(p.CFiles, name) + continue + case ".h": + p.HFiles = append(p.HFiles, name) + continue + case ".s": + p.SFiles = append(p.SFiles, name) + continue + case ".S": + Sfiles = append(Sfiles, name) + continue + } + + pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments) + if err != nil { + return p, err + } + + pkg := string(pf.Name.Name) + if pkg == "documentation" { + continue + } + + isTest := strings.HasSuffix(name, "_test.go") + isXTest := false + if isTest && strings.HasSuffix(pkg, "_test") { + isXTest = true + pkg = pkg[:len(pkg)-len("_test")] + } + + if p.Name == "" { + p.Name = pkg + firstFile = name + } else if pkg != p.Name { + return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir) + } + if pf.Doc != nil && p.Doc == "" { + p.Doc = doc.Synopsis(pf.Doc.Text()) + } + + // Record imports and information about cgo. + isCgo := false + for _, decl := range pf.Decls { + d, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + for _, dspec := range d.Specs { + spec, ok := dspec.(*ast.ImportSpec) + if !ok { + continue + } + quoted := string(spec.Path.Value) + path, err := strconv.Unquote(quoted) + if err != nil { + log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted) + } + if isXTest { + xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos())) + } else if isTest { + testImported[path] = append(testImported[path], fset.Position(spec.Pos())) + } else { + imported[path] = append(imported[path], fset.Position(spec.Pos())) + } + if path == "C" { + if isTest { + return p, fmt.Errorf("use of cgo in test %s not supported", filename) + } + cg := spec.Doc + if cg == nil && len(d.Specs) == 1 { + cg = d.Doc + } + if cg != nil { + if err := ctxt.saveCgo(filename, p, cg); err != nil { + return p, err + } + } + isCgo = true + } + } + } + if isCgo { + if ctxt.CgoEnabled { + p.CgoFiles = append(p.CgoFiles, name) + } + } else if isXTest { + p.XTestGoFiles = append(p.XTestGoFiles, name) + } else if isTest { + p.TestGoFiles = append(p.TestGoFiles, name) + } else { + p.GoFiles = append(p.GoFiles, name) + } + } + if p.Name == "" { + return p, fmt.Errorf("no Go source files in %s", p.Dir) + } + + p.Imports, p.ImportPos = cleanImports(imported) + p.TestImports, p.TestImportPos = cleanImports(testImported) + p.XTestImports, p.XTestImportPos = cleanImports(xTestImported) + + // add the .S files only if we are using cgo + // (which means gcc will compile them). + // The standard assemblers expect .s files. + if len(p.CgoFiles) > 0 { + p.SFiles = append(p.SFiles, Sfiles...) + sort.Strings(p.SFiles) + } + + return p, nil +} + +func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) { + all := make([]string, 0, len(m)) + for path := range m { + all = append(all, path) + } + sort.Strings(all) + return all, m +} + +// Import is shorthand for Default.Import. +func Import(path, src string, mode ImportMode) (*Package, error) { + return Default.Import(path, src, mode) +} + +// ImportDir is shorthand for Default.ImportDir. +func ImportDir(dir string, mode ImportMode) (*Package, error) { + return Default.ImportDir(dir, mode) +} + +var slashslash = []byte("//") + +// shouldBuild reports whether it is okay to use this file, +// The rule is that in the file's leading run of // comments +// and blank lines, which must be followed by a blank line +// (to avoid including a Go package clause doc comment), +// lines beginning with '// +build' are taken as build directives. +// +// The file is accepted only if each such line lists something +// matching the file. For example: +// +// // +build windows linux +// +// marks the file as applicable only on Windows and Linux. +// +func (ctxt *Context) shouldBuild(content []byte) bool { + // Pass 1. Identify leading run of // comments and blank lines, + // which must be followed by a blank line. + end := 0 + p := content + for len(p) > 0 { + line := p + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, p = line[:i], p[i+1:] + } else { + p = p[len(p):] + } + line = bytes.TrimSpace(line) + if len(line) == 0 { // Blank line + end = cap(content) - cap(line) // &line[0] - &content[0] + continue + } + if !bytes.HasPrefix(line, slashslash) { // Not comment line + break + } + } + content = content[:end] + + // Pass 2. Process each line in the run. + p = content + for len(p) > 0 { + line := p + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, p = line[:i], p[i+1:] + } else { + p = p[len(p):] + } + line = bytes.TrimSpace(line) + if bytes.HasPrefix(line, slashslash) { + line = bytes.TrimSpace(line[len(slashslash):]) + if len(line) > 0 && line[0] == '+' { + // Looks like a comment +line. + f := strings.Fields(string(line)) + if f[0] == "+build" { + ok := false + for _, tok := range f[1:] { + if ctxt.match(tok) { + ok = true + break + } + } + if !ok { + return false // this one doesn't match + } + } + } + } + } + return true // everything matches +} + +// saveCgo saves the information from the #cgo lines in the import "C" comment. +// These lines set CFLAGS and LDFLAGS and pkg-config directives that affect +// the way cgo's C code is built. +// +// TODO(rsc): This duplicates code in cgo. +// Once the dust settles, remove this code from cgo. +func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error { + text := cg.Text() + for _, line := range strings.Split(text, "\n") { + orig := line + + // Line is + // #cgo [GOOS/GOARCH...] LDFLAGS: stuff + // + line = strings.TrimSpace(line) + if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') { + continue + } + + // Split at colon. + line = strings.TrimSpace(line[4:]) + i := strings.Index(line, ":") + if i < 0 { + return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) + } + line, argstr := line[:i], line[i+1:] + + // Parse GOOS/GOARCH stuff. + f := strings.Fields(line) + if len(f) < 1 { + return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) + } + + cond, verb := f[:len(f)-1], f[len(f)-1] + if len(cond) > 0 { + ok := false + for _, c := range cond { + if ctxt.match(c) { + ok = true + break + } + } + if !ok { + continue + } + } + + args, err := splitQuoted(argstr) + if err != nil { + return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) + } + for _, arg := range args { + if !safeName(arg) { + return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg) + } + } + + switch verb { + case "CFLAGS": + di.CgoCFLAGS = append(di.CgoCFLAGS, args...) + case "LDFLAGS": + di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...) + case "pkg-config": + di.CgoPkgConfig = append(di.CgoPkgConfig, args...) + default: + return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig) + } + } + return nil +} + +var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:") + +func safeName(s string) bool { + if s == "" { + return false + } + for i := 0; i < len(s); i++ { + if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 { + return false + } + } + return true +} + +// splitQuoted splits the string s around each instance of one or more consecutive +// white space characters while taking into account quotes and escaping, and +// returns an array of substrings of s or an empty list if s contains only white space. +// Single quotes and double quotes are recognized to prevent splitting within the +// quoted region, and are removed from the resulting substrings. If a quote in s +// isn't closed err will be set and r will have the unclosed argument as the +// last element. The backslash is used for escaping. +// +// For example, the following string: +// +// a b:"c d" 'e''f' "g\"" +// +// Would be parsed as: +// +// []string{"a", "b:c d", "ef", `g"`} +// +func splitQuoted(s string) (r []string, err error) { + var args []string + arg := make([]rune, len(s)) + escaped := false + quoted := false + quote := '\x00' + i := 0 + for _, rune := range s { + switch { + case escaped: + escaped = false + case rune == '\\': + escaped = true + continue + case quote != '\x00': + if rune == quote { + quote = '\x00' + continue + } + case rune == '"' || rune == '\'': + quoted = true + quote = rune + continue + case unicode.IsSpace(rune): + if quoted || i > 0 { + quoted = false + args = append(args, string(arg[:i])) + i = 0 + } + continue + } + arg[i] = rune + i++ + } + if quoted || i > 0 { + args = append(args, string(arg[:i])) + } + if quote != 0 { + err = errors.New("unclosed quote") + } else if escaped { + err = errors.New("unfinished escaping") + } + return args, err +} + +// match returns true if the name is one of: +// +// $GOOS +// $GOARCH +// cgo (if cgo is enabled) +// !cgo (if cgo is disabled) +// tag (if tag is listed in ctxt.BuildTags) +// !tag (if tag is not listed in ctxt.BuildTags) +// a slash-separated list of any of these +// +func (ctxt *Context) match(name string) bool { + if name == "" { + return false + } + if i := strings.Index(name, ","); i >= 0 { + // comma-separated list + return ctxt.match(name[:i]) && ctxt.match(name[i+1:]) + } + if strings.HasPrefix(name, "!!") { // bad syntax, reject always + return false + } + if strings.HasPrefix(name, "!") { // negation + return !ctxt.match(name[1:]) + } + + // Tags must be letters, digits, underscores. + // Unlike in Go identifiers, all digits is fine (e.g., "386"). + for _, c := range name { + if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { + return false + } + } + + // special tags + if ctxt.CgoEnabled && name == "cgo" { + return true + } + if name == ctxt.GOOS || name == ctxt.GOARCH { + return true + } + + // other tags + for _, tag := range ctxt.BuildTags { + if tag == name { + return true + } + } + + return false +} + +// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH +// suffix which does not match the current system. +// The recognized name formats are: +// +// name_$(GOOS).* +// name_$(GOARCH).* +// name_$(GOOS)_$(GOARCH).* +// name_$(GOOS)_test.* +// name_$(GOARCH)_test.* +// name_$(GOOS)_$(GOARCH)_test.* +// +func (ctxt *Context) goodOSArchFile(name string) bool { + if dot := strings.Index(name, "."); dot != -1 { + name = name[:dot] + } + l := strings.Split(name, "_") + if n := len(l); n > 0 && l[n-1] == "test" { + l = l[:n-1] + } + n := len(l) + if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] { + return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH + } + if n >= 1 && knownOS[l[n-1]] { + return l[n-1] == ctxt.GOOS + } + if n >= 1 && knownArch[l[n-1]] { + return l[n-1] == ctxt.GOARCH + } + return true +} + +var knownOS = make(map[string]bool) +var knownArch = make(map[string]bool) + +func init() { + for _, v := range strings.Fields(goosList) { + knownOS[v] = true + } + for _, v := range strings.Fields(goarchList) { + knownArch[v] = true + } +} + +// ToolDir is the directory containing build tools. +var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) + +// IsLocalImport reports whether the import path is +// a local import path, like ".", "..", "./foo", or "../foo". +func IsLocalImport(path string) bool { + return path == "." || path == ".." || + strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../") +} // ArchChar returns the architecture character for the given goarch. // For example, ArchChar("amd64") returns "6". diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go index 3c706a46edd..06b8b0e94f8 100644 --- a/libgo/go/go/build/build_test.go +++ b/libgo/go/go/build/build_test.go @@ -5,83 +5,14 @@ package build import ( + "os" "path/filepath" - "reflect" "runtime" - "sort" "testing" ) -func sortstr(x []string) []string { - sort.Strings(x) - return x -} - -var buildPkgs = []struct { - dir string - info *DirInfo -}{ - { - "go/build/pkgtest", - &DirInfo{ - GoFiles: []string{"pkgtest.go"}, - SFiles: []string{"sqrt_" + runtime.GOARCH + ".s"}, - Package: "pkgtest", - Imports: []string{"bytes"}, - TestImports: []string{"fmt", "pkgtest"}, - TestGoFiles: sortstr([]string{"sqrt_test.go", "sqrt_" + runtime.GOARCH + "_test.go"}), - XTestGoFiles: []string{"xsqrt_test.go"}, - }, - }, - { - "go/build/cmdtest", - &DirInfo{ - GoFiles: []string{"main.go"}, - Package: "main", - Imports: []string{"go/build/pkgtest"}, - TestImports: []string{}, - }, - }, - { - "go/build/cgotest", - &DirInfo{ - CgoFiles: ifCgo([]string{"cgotest.go"}), - CFiles: []string{"cgotest.c"}, - HFiles: []string{"cgotest.h"}, - Imports: []string{"C", "unsafe"}, - TestImports: []string{}, - Package: "cgotest", - }, - }, -} - -func ifCgo(x []string) []string { - if DefaultContext.CgoEnabled { - return x - } - return nil -} - -func TestBuild(t *testing.T) { - for _, tt := range buildPkgs { - tree := Path[0] // Goroot - dir := filepath.Join(tree.SrcDir(), tt.dir) - info, err := ScanDir(dir) - if err != nil { - t.Errorf("ScanDir(%#q): %v", tt.dir, err) - continue - } - // Don't bother testing import positions. - tt.info.ImportPos, tt.info.TestImportPos = info.ImportPos, info.TestImportPos - if !reflect.DeepEqual(info, tt.info) { - t.Errorf("ScanDir(%#q) = %#v, want %#v\n", tt.dir, info, tt.info) - continue - } - } -} - func TestMatch(t *testing.T) { - ctxt := DefaultContext + ctxt := Default what := "default" match := func(tag string) { if !ctxt.match(tag) { @@ -106,3 +37,40 @@ func TestMatch(t *testing.T) { match(runtime.GOOS + "," + runtime.GOARCH + ",!bar") nomatch(runtime.GOOS + "," + runtime.GOARCH + ",bar") } + +func TestDotSlashImport(t *testing.T) { + p, err := ImportDir("testdata/other", 0) + if err != nil { + t.Fatal(err) + } + if len(p.Imports) != 1 || p.Imports[0] != "./file" { + t.Fatalf("testdata/other: Imports=%v, want [./file]", p.Imports) + } + + p1, err := Import("./file", "testdata/other", 0) + if err != nil { + t.Fatal(err) + } + if p1.Name != "file" { + t.Fatalf("./file: Name=%q, want %q", p1.Name, "file") + } + dir := filepath.Clean("testdata/other/file") // Clean to use \ on Windows + if p1.Dir != dir { + t.Fatalf("./file: Dir=%q, want %q", p1.Name, dir) + } +} + +func TestLocalDirectory(t *testing.T) { + cwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + + p, err := ImportDir(cwd, 0) + if err != nil { + t.Fatal(err) + } + if p.ImportPath != "go/build" { + t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build") + } +} diff --git a/libgo/go/go/build/cgotest/cgotest.go b/libgo/go/go/build/cgotest/cgotest.go deleted file mode 100644 index 93bbf06883f..00000000000 --- a/libgo/go/go/build/cgotest/cgotest.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -char* greeting = "hello, world"; -*/ -// #include "cgotest.h" -import "C" -import "unsafe" - -var Greeting = C.GoString(C.greeting) - -func DoAdd(x, y int) (sum int) { - C.Add(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&sum))) - return -} diff --git a/libgo/go/go/build/cmdtest/main.go b/libgo/go/go/build/cmdtest/main.go deleted file mode 100644 index bed4f485a0a..00000000000 --- a/libgo/go/go/build/cmdtest/main.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "go/build/pkgtest" - -func main() { - pkgtest.Foo() - print(int(pkgtest.Sqrt(9))) -} diff --git a/libgo/go/go/build/dir.go b/libgo/go/go/build/dir.go deleted file mode 100644 index 0917e736aa4..00000000000 --- a/libgo/go/go/build/dir.go +++ /dev/null @@ -1,709 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package build - -import ( - "bytes" - "errors" - "fmt" - "go/ast" - "go/parser" - "go/token" - "io/ioutil" - "log" - "os" - "path" - "path/filepath" - "runtime" - "sort" - "strconv" - "strings" - "unicode" -) - -// A Context specifies the supporting context for a build. -type Context struct { - GOARCH string // target architecture - GOOS string // target operating system - CgoEnabled bool // whether cgo can be used - BuildTags []string // additional tags to recognize in +build lines - - // By default, ScanDir uses the operating system's - // file system calls to read directories and files. - // Callers can override those calls to provide other - // ways to read data by setting ReadDir and ReadFile. - // ScanDir does not make any assumptions about the - // format of the strings dir and file: they can be - // slash-separated, backslash-separated, even URLs. - - // ReadDir returns a slice of os.FileInfo, sorted by Name, - // describing the content of the named directory. - // The dir argument is the argument to ScanDir. - // If ReadDir is nil, ScanDir uses io.ReadDir. - ReadDir func(dir string) (fi []os.FileInfo, err error) - - // ReadFile returns the content of the file named file - // in the directory named dir. The dir argument is the - // argument to ScanDir, and the file argument is the - // Name field from an os.FileInfo returned by ReadDir. - // The returned path is the full name of the file, to be - // used in error messages. - // - // If ReadFile is nil, ScanDir uses filepath.Join(dir, file) - // as the path and ioutil.ReadFile to read the data. - ReadFile func(dir, file string) (path string, content []byte, err error) -} - -func (ctxt *Context) readDir(dir string) ([]os.FileInfo, error) { - if f := ctxt.ReadDir; f != nil { - return f(dir) - } - return ioutil.ReadDir(dir) -} - -func (ctxt *Context) readFile(dir, file string) (string, []byte, error) { - if f := ctxt.ReadFile; f != nil { - return f(dir, file) - } - p := filepath.Join(dir, file) - content, err := ioutil.ReadFile(p) - return p, content, err -} - -// The DefaultContext is the default Context for builds. -// It uses the GOARCH and GOOS environment variables -// if set, or else the compiled code's GOARCH and GOOS. -var DefaultContext Context = defaultContext() - -var cgoEnabled = map[string]bool{ - "darwin/386": true, - "darwin/amd64": true, - "linux/386": true, - "linux/amd64": true, - "freebsd/386": true, - "freebsd/amd64": true, - "windows/386": true, - "windows/amd64": true, -} - -func defaultContext() Context { - var c Context - - c.GOARCH = envOr("GOARCH", runtime.GOARCH) - c.GOOS = envOr("GOOS", runtime.GOOS) - - s := os.Getenv("CGO_ENABLED") - switch s { - case "1": - c.CgoEnabled = true - case "0": - c.CgoEnabled = false - default: - c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH] - } - - return c -} - -func envOr(name, def string) string { - s := os.Getenv(name) - if s == "" { - return def - } - return s -} - -type DirInfo struct { - Package string // Name of package in dir - PackageComment *ast.CommentGroup // Package comments from GoFiles - ImportPath string // Import path of package in dir - Imports []string // All packages imported by GoFiles - ImportPos map[string][]token.Position // Source code location of imports - - // Source files - GoFiles []string // .go files in dir (excluding CgoFiles, TestGoFiles, XTestGoFiles) - HFiles []string // .h files in dir - CFiles []string // .c files in dir - SFiles []string // .s (and, when using cgo, .S files in dir) - CgoFiles []string // .go files that import "C" - - // Cgo directives - CgoPkgConfig []string // Cgo pkg-config directives - CgoCFLAGS []string // Cgo CFLAGS directives - CgoLDFLAGS []string // Cgo LDFLAGS directives - - // Test information - TestGoFiles []string // _test.go files in package - XTestGoFiles []string // _test.go files outside package - TestImports []string // All packages imported by (X)TestGoFiles - TestImportPos map[string][]token.Position -} - -func (d *DirInfo) IsCommand() bool { - // TODO(rsc): This is at least a little bogus. - return d.Package == "main" -} - -// ScanDir calls DefaultContext.ScanDir. -func ScanDir(dir string) (info *DirInfo, err error) { - return DefaultContext.ScanDir(dir) -} - -// TODO(rsc): Move this comment to a more appropriate place. - -// ScanDir returns a structure with details about the Go package -// found in the given directory. -// -// Most .go, .c, .h, and .s files in the directory are considered part -// of the package. The exceptions are: -// -// - .go files in package main (unless no other package is found) -// - .go files in package documentation -// - files starting with _ or . -// - files with build constraints not satisfied by the context -// -// Build Constraints -// -// A build constraint is a line comment beginning with the directive +build -// that lists the conditions under which a file should be included in the package. -// Constraints may appear in any kind of source file (not just Go), but -// they must be appear near the top of the file, preceded -// only by blank lines and other line comments. -// -// A build constraint is evaluated as the OR of space-separated options; -// each option evaluates as the AND of its comma-separated terms; -// and each term is an alphanumeric word or, preceded by !, its negation. -// That is, the build constraint: -// -// // +build linux,386 darwin,!cgo -// -// corresponds to the boolean formula: -// -// (linux AND 386) OR (darwin AND (NOT cgo)) -// -// During a particular build, the following words are satisfied: -// -// - the target operating system, as spelled by runtime.GOOS -// - the target architecture, as spelled by runtime.GOARCH -// - "cgo", if ctxt.CgoEnabled is true -// - any additional words listed in ctxt.BuildTags -// -// If a file's name, after stripping the extension and a possible _test suffix, -// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating -// system and architecture values, then the file is considered to have an implicit -// build constraint requiring those terms. -// -// Examples -// -// To keep a file from being considered for the build: -// -// // +build ignore -// -// (any other unsatisfied word will work as well, but ``ignore'' is conventional.) -// -// To build a file only when using cgo, and only on Linux and OS X: -// -// // +build linux,cgo darwin,cgo -// -// Such a file is usually paired with another file implementing the -// default functionality for other systems, which in this case would -// carry the constraint: -// -// // +build !linux !darwin !cgo -// -// Naming a file dns_windows.go will cause it to be included only when -// building the package for Windows; similarly, math_386.s will be included -// only when building the package for 32-bit x86. -// -func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { - dirs, err := ctxt.readDir(dir) - if err != nil { - return nil, err - } - - var Sfiles []string // files with ".S" (capital S) - var di DirInfo - imported := make(map[string][]token.Position) - testImported := make(map[string][]token.Position) - fset := token.NewFileSet() - for _, d := range dirs { - if d.IsDir() { - continue - } - name := d.Name() - if strings.HasPrefix(name, "_") || - strings.HasPrefix(name, ".") { - continue - } - if !ctxt.goodOSArchFile(name) { - continue - } - - ext := path.Ext(name) - switch ext { - case ".go", ".c", ".s", ".h", ".S": - // tentatively okay - default: - // skip - continue - } - - // Look for +build comments to accept or reject the file. - filename, data, err := ctxt.readFile(dir, name) - if err != nil { - return nil, err - } - if !ctxt.shouldBuild(data) { - continue - } - - // Going to save the file. For non-Go files, can stop here. - switch ext { - case ".c": - di.CFiles = append(di.CFiles, name) - continue - case ".h": - di.HFiles = append(di.HFiles, name) - continue - case ".s": - di.SFiles = append(di.SFiles, name) - continue - case ".S": - Sfiles = append(Sfiles, name) - continue - } - - pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments) - if err != nil { - return nil, err - } - - pkg := string(pf.Name.Name) - if pkg == "main" && di.Package != "" && di.Package != "main" { - continue - } - if pkg == "documentation" { - continue - } - - isTest := strings.HasSuffix(name, "_test.go") - if isTest && strings.HasSuffix(pkg, "_test") { - pkg = pkg[:len(pkg)-len("_test")] - } - - if pkg != di.Package && di.Package == "main" { - // Found non-main package but was recording - // information about package main. Reset. - di = DirInfo{} - } - if di.Package == "" { - di.Package = pkg - } else if pkg != di.Package { - return nil, fmt.Errorf("%s: found packages %s and %s", dir, pkg, di.Package) - } - if pf.Doc != nil { - if di.PackageComment != nil { - di.PackageComment.List = append(di.PackageComment.List, pf.Doc.List...) - } else { - di.PackageComment = pf.Doc - } - } - - // Record imports and information about cgo. - isCgo := false - for _, decl := range pf.Decls { - d, ok := decl.(*ast.GenDecl) - if !ok { - continue - } - for _, dspec := range d.Specs { - spec, ok := dspec.(*ast.ImportSpec) - if !ok { - continue - } - quoted := string(spec.Path.Value) - path, err := strconv.Unquote(quoted) - if err != nil { - log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted) - } - if isTest { - testImported[path] = append(testImported[path], fset.Position(spec.Pos())) - } else { - imported[path] = append(imported[path], fset.Position(spec.Pos())) - } - if path == "C" { - if isTest { - return nil, fmt.Errorf("%s: use of cgo in test not supported", filename) - } - cg := spec.Doc - if cg == nil && len(d.Specs) == 1 { - cg = d.Doc - } - if cg != nil { - if err := ctxt.saveCgo(filename, &di, cg); err != nil { - return nil, err - } - } - isCgo = true - } - } - } - if isCgo { - if ctxt.CgoEnabled { - di.CgoFiles = append(di.CgoFiles, name) - } - } else if isTest { - if pkg == string(pf.Name.Name) { - di.TestGoFiles = append(di.TestGoFiles, name) - } else { - di.XTestGoFiles = append(di.XTestGoFiles, name) - } - } else { - di.GoFiles = append(di.GoFiles, name) - } - } - if di.Package == "" { - return nil, fmt.Errorf("%s: no Go source files", dir) - } - di.Imports = make([]string, len(imported)) - di.ImportPos = imported - i := 0 - for p := range imported { - di.Imports[i] = p - i++ - } - di.TestImports = make([]string, len(testImported)) - di.TestImportPos = testImported - i = 0 - for p := range testImported { - di.TestImports[i] = p - i++ - } - - // add the .S files only if we are using cgo - // (which means gcc will compile them). - // The standard assemblers expect .s files. - if len(di.CgoFiles) > 0 { - di.SFiles = append(di.SFiles, Sfiles...) - sort.Strings(di.SFiles) - } - - // File name lists are sorted because ReadDir sorts. - sort.Strings(di.Imports) - sort.Strings(di.TestImports) - return &di, nil -} - -var slashslash = []byte("//") - -// shouldBuild reports whether it is okay to use this file, -// The rule is that in the file's leading run of // comments -// and blank lines, which must be followed by a blank line -// (to avoid including a Go package clause doc comment), -// lines beginning with '// +build' are taken as build directives. -// -// The file is accepted only if each such line lists something -// matching the file. For example: -// -// // +build windows linux -// -// marks the file as applicable only on Windows and Linux. -// -func (ctxt *Context) shouldBuild(content []byte) bool { - // Pass 1. Identify leading run of // comments and blank lines, - // which must be followed by a blank line. - end := 0 - p := content - for len(p) > 0 { - line := p - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, p = line[:i], p[i+1:] - } else { - p = p[len(p):] - } - line = bytes.TrimSpace(line) - if len(line) == 0 { // Blank line - end = cap(content) - cap(line) // &line[0] - &content[0] - continue - } - if !bytes.HasPrefix(line, slashslash) { // Not comment line - break - } - } - content = content[:end] - - // Pass 2. Process each line in the run. - p = content - for len(p) > 0 { - line := p - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, p = line[:i], p[i+1:] - } else { - p = p[len(p):] - } - line = bytes.TrimSpace(line) - if bytes.HasPrefix(line, slashslash) { - line = bytes.TrimSpace(line[len(slashslash):]) - if len(line) > 0 && line[0] == '+' { - // Looks like a comment +line. - f := strings.Fields(string(line)) - if f[0] == "+build" { - ok := false - for _, tok := range f[1:] { - if ctxt.match(tok) { - ok = true - break - } - } - if !ok { - return false // this one doesn't match - } - } - } - } - } - return true // everything matches -} - -// saveCgo saves the information from the #cgo lines in the import "C" comment. -// These lines set CFLAGS and LDFLAGS and pkg-config directives that affect -// the way cgo's C code is built. -// -// TODO(rsc): This duplicates code in cgo. -// Once the dust settles, remove this code from cgo. -func (ctxt *Context) saveCgo(filename string, di *DirInfo, cg *ast.CommentGroup) error { - text := cg.Text() - for _, line := range strings.Split(text, "\n") { - orig := line - - // Line is - // #cgo [GOOS/GOARCH...] LDFLAGS: stuff - // - line = strings.TrimSpace(line) - if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') { - continue - } - - // Split at colon. - line = strings.TrimSpace(line[4:]) - i := strings.Index(line, ":") - if i < 0 { - return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) - } - line, argstr := line[:i], line[i+1:] - - // Parse GOOS/GOARCH stuff. - f := strings.Fields(line) - if len(f) < 1 { - return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) - } - - cond, verb := f[:len(f)-1], f[len(f)-1] - if len(cond) > 0 { - ok := false - for _, c := range cond { - if ctxt.match(c) { - ok = true - break - } - } - if !ok { - continue - } - } - - args, err := splitQuoted(argstr) - if err != nil { - return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig) - } - for _, arg := range args { - if !safeName(arg) { - return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg) - } - } - - switch verb { - case "CFLAGS": - di.CgoCFLAGS = append(di.CgoCFLAGS, args...) - case "LDFLAGS": - di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...) - case "pkg-config": - di.CgoPkgConfig = append(di.CgoPkgConfig, args...) - default: - return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig) - } - } - return nil -} - -var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:") - -func safeName(s string) bool { - if s == "" { - return false - } - for i := 0; i < len(s); i++ { - if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 { - return false - } - } - return true -} - -// splitQuoted splits the string s around each instance of one or more consecutive -// white space characters while taking into account quotes and escaping, and -// returns an array of substrings of s or an empty list if s contains only white space. -// Single quotes and double quotes are recognized to prevent splitting within the -// quoted region, and are removed from the resulting substrings. If a quote in s -// isn't closed err will be set and r will have the unclosed argument as the -// last element. The backslash is used for escaping. -// -// For example, the following string: -// -// a b:"c d" 'e''f' "g\"" -// -// Would be parsed as: -// -// []string{"a", "b:c d", "ef", `g"`} -// -func splitQuoted(s string) (r []string, err error) { - var args []string - arg := make([]rune, len(s)) - escaped := false - quoted := false - quote := '\x00' - i := 0 - for _, rune := range s { - switch { - case escaped: - escaped = false - case rune == '\\': - escaped = true - continue - case quote != '\x00': - if rune == quote { - quote = '\x00' - continue - } - case rune == '"' || rune == '\'': - quoted = true - quote = rune - continue - case unicode.IsSpace(rune): - if quoted || i > 0 { - quoted = false - args = append(args, string(arg[:i])) - i = 0 - } - continue - } - arg[i] = rune - i++ - } - if quoted || i > 0 { - args = append(args, string(arg[:i])) - } - if quote != 0 { - err = errors.New("unclosed quote") - } else if escaped { - err = errors.New("unfinished escaping") - } - return args, err -} - -// match returns true if the name is one of: -// -// $GOOS -// $GOARCH -// cgo (if cgo is enabled) -// !cgo (if cgo is disabled) -// tag (if tag is listed in ctxt.BuildTags) -// !tag (if tag is not listed in ctxt.BuildTags) -// a slash-separated list of any of these -// -func (ctxt *Context) match(name string) bool { - if name == "" { - return false - } - if i := strings.Index(name, ","); i >= 0 { - // comma-separated list - return ctxt.match(name[:i]) && ctxt.match(name[i+1:]) - } - if strings.HasPrefix(name, "!!") { // bad syntax, reject always - return false - } - if strings.HasPrefix(name, "!") { // negation - return !ctxt.match(name[1:]) - } - - // Tags must be letters, digits, underscores. - // Unlike in Go identifiers, all digits is fine (e.g., "386"). - for _, c := range name { - if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { - return false - } - } - - // special tags - if ctxt.CgoEnabled && name == "cgo" { - return true - } - if name == ctxt.GOOS || name == ctxt.GOARCH { - return true - } - - // other tags - for _, tag := range ctxt.BuildTags { - if tag == name { - return true - } - } - - return false -} - -// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH -// suffix which does not match the current system. -// The recognized name formats are: -// -// name_$(GOOS).* -// name_$(GOARCH).* -// name_$(GOOS)_$(GOARCH).* -// name_$(GOOS)_test.* -// name_$(GOARCH)_test.* -// name_$(GOOS)_$(GOARCH)_test.* -// -func (ctxt *Context) goodOSArchFile(name string) bool { - if dot := strings.Index(name, "."); dot != -1 { - name = name[:dot] - } - l := strings.Split(name, "_") - if n := len(l); n > 0 && l[n-1] == "test" { - l = l[:n-1] - } - n := len(l) - if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] { - return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH - } - if n >= 1 && knownOS[l[n-1]] { - return l[n-1] == ctxt.GOOS - } - if n >= 1 && knownArch[l[n-1]] { - return l[n-1] == ctxt.GOARCH - } - return true -} - -var knownOS = make(map[string]bool) -var knownArch = make(map[string]bool) - -func init() { - for _, v := range strings.Fields(goosList) { - knownOS[v] = true - } - for _, v := range strings.Fields(goarchList) { - knownArch[v] = true - } -} diff --git a/libgo/go/go/build/doc.go b/libgo/go/go/build/doc.go new file mode 100644 index 00000000000..67c26ac7f4f --- /dev/null +++ b/libgo/go/go/build/doc.go @@ -0,0 +1,109 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package build gathers information about Go packages. +// +// Go Path +// +// The Go path is a list of directory trees containing Go source code. +// It is consulted to resolve imports that cannot be found in the standard +// Go tree. The default path is the value of the GOPATH environment +// variable, interpreted as a path list appropriate to the operating system +// (on Unix, the variable is a colon-separated string; +// on Windows, a semicolon-separated string; +// on Plan 9, a list). +// +// Each directory listed in the Go path must have a prescribed structure: +// +// The src/ directory holds source code. The path below 'src' determines +// the import path or executable name. +// +// The pkg/ directory holds installed package objects. +// As in the Go tree, each target operating system and +// architecture pair has its own subdirectory of pkg +// (pkg/GOOS_GOARCH). +// +// If DIR is a directory listed in the Go path, a package with +// source in DIR/src/foo/bar can be imported as "foo/bar" and +// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a" +// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a"). +// +// The bin/ directory holds compiled commands. +// Each command is named for its source directory, but only +// using the final element, not the entire path. That is, the +// command with source in DIR/src/foo/quux is installed into +// DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped +// so that you can add DIR/bin to your PATH to get at the +// installed commands. +// +// Here's an example directory layout: +// +// GOPATH=/home/user/gocode +// +// /home/user/gocode/ +// src/ +// foo/ +// bar/ (go code in package bar) +// x.go +// quux/ (go code in package main) +// y.go +// bin/ +// quux (installed command) +// pkg/ +// linux_amd64/ +// foo/ +// bar.a (installed package object) +// +// Build Constraints +// +// A build constraint is a line comment beginning with the directive +build +// that lists the conditions under which a file should be included in the package. +// Constraints may appear in any kind of source file (not just Go), but +// they must be appear near the top of the file, preceded +// only by blank lines and other line comments. +// +// A build constraint is evaluated as the OR of space-separated options; +// each option evaluates as the AND of its comma-separated terms; +// and each term is an alphanumeric word or, preceded by !, its negation. +// That is, the build constraint: +// +// // +build linux,386 darwin,!cgo +// +// corresponds to the boolean formula: +// +// (linux AND 386) OR (darwin AND (NOT cgo)) +// +// During a particular build, the following words are satisfied: +// +// - the target operating system, as spelled by runtime.GOOS +// - the target architecture, as spelled by runtime.GOARCH +// - "cgo", if ctxt.CgoEnabled is true +// - any additional words listed in ctxt.BuildTags +// +// If a file's name, after stripping the extension and a possible _test suffix, +// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating +// system and architecture values, then the file is considered to have an implicit +// build constraint requiring those terms. +// +// To keep a file from being considered for the build: +// +// // +build ignore +// +// (any other unsatisfied word will work as well, but ``ignore'' is conventional.) +// +// To build a file only when using cgo, and only on Linux and OS X: +// +// // +build linux,cgo darwin,cgo +// +// Such a file is usually paired with another file implementing the +// default functionality for other systems, which in this case would +// carry the constraint: +// +// // +build !linux !darwin !cgo +// +// Naming a file dns_windows.go will cause it to be included only when +// building the package for Windows; similarly, math_386.s will be included +// only when building the package for 32-bit x86. +// +package build diff --git a/libgo/go/go/build/path.go b/libgo/go/go/build/path.go deleted file mode 100644 index 7e931faff19..00000000000 --- a/libgo/go/go/build/path.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package build - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "runtime" -) - -// Path is a validated list of Trees derived from $GOROOT and $GOPATH at init. -var Path []*Tree - -// Tree describes a Go source tree, either $GOROOT or one from $GOPATH. -type Tree struct { - Path string - Goroot bool -} - -func newTree(p string) (*Tree, error) { - if !filepath.IsAbs(p) { - return nil, errors.New("must be absolute") - } - ep, err := filepath.EvalSymlinks(p) - if err != nil { - return nil, err - } - return &Tree{Path: ep}, nil -} - -// SrcDir returns the tree's package source directory. -func (t *Tree) SrcDir() string { - if t.Goroot { - return filepath.Join(t.Path, "src", "pkg") - } - return filepath.Join(t.Path, "src") -} - -// PkgDir returns the tree's package object directory. -func (t *Tree) PkgDir() string { - goos, goarch := runtime.GOOS, runtime.GOARCH - if e := os.Getenv("GOOS"); e != "" { - goos = e - } - if e := os.Getenv("GOARCH"); e != "" { - goarch = e - } - return filepath.Join(t.Path, "pkg", goos+"_"+goarch) -} - -// BinDir returns the tree's binary executable directory. -func (t *Tree) BinDir() string { - if t.Goroot { - if gobin := os.Getenv("GOBIN"); gobin != "" { - return filepath.Clean(gobin) - } - } - return filepath.Join(t.Path, "bin") -} - -// HasSrc returns whether the given package's -// source can be found inside this Tree. -func (t *Tree) HasSrc(pkg string) bool { - fi, err := os.Stat(filepath.Join(t.SrcDir(), pkg)) - if err != nil { - return false - } - return fi.IsDir() -} - -// HasPkg returns whether the given package's -// object file can be found inside this Tree. -func (t *Tree) HasPkg(pkg string) bool { - fi, err := os.Stat(filepath.Join(t.PkgDir(), pkg+".a")) - if err != nil { - return false - } - return !fi.IsDir() -} - -var ( - ErrNotFound = errors.New("package could not be found locally") - ErrTreeNotFound = errors.New("no valid GOROOT or GOPATH could be found") -) - -// FindTree takes an import or filesystem path and returns the -// tree where the package source should be and the package import path. -func FindTree(path string) (tree *Tree, pkg string, err error) { - if isLocalPath(path) { - if path, err = filepath.Abs(path); err != nil { - return - } - if path, err = filepath.EvalSymlinks(path); err != nil { - return - } - for _, t := range Path { - tpath := t.SrcDir() + string(filepath.Separator) - if !filepath.HasPrefix(path, tpath) { - continue - } - tree = t - pkg = filepath.ToSlash(path[len(tpath):]) - return - } - err = fmt.Errorf("path %q not inside a GOPATH", path) - return - } - tree = defaultTree - pkg = filepath.ToSlash(path) - for _, t := range Path { - if t.HasSrc(pkg) { - tree = t - return - } - } - if tree == nil { - err = ErrTreeNotFound - } else { - err = ErrNotFound - } - return -} - -// isLocalPath returns whether the given path is local (/foo ./foo ../foo . ..) -// Windows paths that starts with drive letter (c:\foo c:foo) are considered local. -func isLocalPath(s string) bool { - const sep = string(filepath.Separator) - return s == "." || s == ".." || - filepath.HasPrefix(s, sep) || - filepath.HasPrefix(s, "."+sep) || filepath.HasPrefix(s, ".."+sep) || - filepath.VolumeName(s) != "" -} - -var ( - // argument lists used by the build's gc and ld methods - gcImportArgs []string - ldImportArgs []string - - // default tree for remote packages - defaultTree *Tree -) - -// set up Path: parse and validate GOROOT and GOPATH variables -func init() { - root := runtime.GOROOT() - t, err := newTree(root) - if err == nil { - t.Goroot = true - Path = []*Tree{t} - } - - for _, p := range filepath.SplitList(os.Getenv("GOPATH")) { - if p == "" { - continue - } - t, err := newTree(p) - if err != nil { - continue - } - - Path = append(Path, t) - gcImportArgs = append(gcImportArgs, "-I", t.PkgDir()) - ldImportArgs = append(ldImportArgs, "-L", t.PkgDir()) - - // select first GOPATH entry as default - if defaultTree == nil { - defaultTree = t - } - } - - // use GOROOT if no valid GOPATH specified - if defaultTree == nil && len(Path) > 0 { - defaultTree = Path[0] - } -} diff --git a/libgo/go/go/build/pkgtest/pkgtest.go b/libgo/go/go/build/pkgtest/pkgtest.go deleted file mode 100644 index 08eea1e2bc3..00000000000 --- a/libgo/go/go/build/pkgtest/pkgtest.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgtest - -import "bytes" - -func Foo() *bytes.Buffer { - return nil -} - -func Sqrt(x float64) float64 diff --git a/libgo/go/go/build/pkgtest/sqrt_386_test.go b/libgo/go/go/build/pkgtest/sqrt_386_test.go deleted file mode 100644 index 26b483fa0ba..00000000000 --- a/libgo/go/go/build/pkgtest/sqrt_386_test.go +++ /dev/null @@ -1 +0,0 @@ -package pkgtest diff --git a/libgo/go/go/build/pkgtest/sqrt_amd64_test.go b/libgo/go/go/build/pkgtest/sqrt_amd64_test.go deleted file mode 100644 index 26b483fa0ba..00000000000 --- a/libgo/go/go/build/pkgtest/sqrt_amd64_test.go +++ /dev/null @@ -1 +0,0 @@ -package pkgtest diff --git a/libgo/go/go/build/pkgtest/sqrt_arm_test.go b/libgo/go/go/build/pkgtest/sqrt_arm_test.go deleted file mode 100644 index 26b483fa0ba..00000000000 --- a/libgo/go/go/build/pkgtest/sqrt_arm_test.go +++ /dev/null @@ -1 +0,0 @@ -package pkgtest diff --git a/libgo/go/go/build/pkgtest/sqrt_test.go b/libgo/go/go/build/pkgtest/sqrt_test.go deleted file mode 100644 index ee9fd5de688..00000000000 --- a/libgo/go/go/build/pkgtest/sqrt_test.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgtest - -import "fmt" - -var _ = fmt.Printf diff --git a/libgo/go/go/build/pkgtest/xsqrt_test.go b/libgo/go/go/build/pkgtest/xsqrt_test.go deleted file mode 100644 index 3898d1dda59..00000000000 --- a/libgo/go/go/build/pkgtest/xsqrt_test.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgtest_test - -import "pkgtest" - -var _ = pkgtest.Foo diff --git a/libgo/go/go/build/syslist_test.go b/libgo/go/go/build/syslist_test.go index d27630d758d..9157faf8cb9 100644 --- a/libgo/go/go/build/syslist_test.go +++ b/libgo/go/go/build/syslist_test.go @@ -55,7 +55,7 @@ var tests = []GoodFileTest{ func TestGoodOSArch(t *testing.T) { for _, test := range tests { - if DefaultContext.goodOSArchFile(test.name) != test.result { + if Default.goodOSArchFile(test.name) != test.result { t.Fatalf("goodOSArchFile(%q) != %v", test.name, test.result) } } diff --git a/libgo/go/go/build/testdata/other/file/file.go b/libgo/go/go/build/testdata/other/file/file.go new file mode 100644 index 00000000000..bbfd3e9e598 --- /dev/null +++ b/libgo/go/go/build/testdata/other/file/file.go @@ -0,0 +1,5 @@ +// Test data - not compiled. + +package file + +func F() {} diff --git a/libgo/go/go/build/testdata/other/main.go b/libgo/go/go/build/testdata/other/main.go new file mode 100644 index 00000000000..e0904357c92 --- /dev/null +++ b/libgo/go/go/build/testdata/other/main.go @@ -0,0 +1,11 @@ +// Test data - not compiled. + +package main + +import ( + "./file" +) + +func main() { + file.F() +} diff --git a/libgo/go/go/doc/doc_test.go b/libgo/go/go/doc/doc_test.go index 9ffe72032c2..f957ede4abf 100644 --- a/libgo/go/go/doc/doc_test.go +++ b/libgo/go/go/doc/doc_test.go @@ -14,12 +14,14 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" "strings" "testing" "text/template" ) var update = flag.Bool("update", false, "update golden (.out) files") +var files = flag.String("files", "", "consider only Go test files matching this regular expression") const dataDir = "testdata" @@ -66,14 +68,26 @@ type bundle struct { } func test(t *testing.T, mode Mode) { - // get all packages + // determine file filter + filter := isGoFile + if *files != "" { + rx, err := regexp.Compile(*files) + if err != nil { + t.Fatal(err) + } + filter = func(fi os.FileInfo) bool { + return isGoFile(fi) && rx.MatchString(fi.Name()) + } + } + + // get packages fset := token.NewFileSet() - pkgs, err := parser.ParseDir(fset, dataDir, isGoFile, parser.ParseComments) + pkgs, err := parser.ParseDir(fset, dataDir, filter, parser.ParseComments) if err != nil { t.Fatal(err) } - // test all packages + // test packages for _, pkg := range pkgs { importpath := dataDir + "/" + pkg.Name doc := New(pkg, importpath, mode) diff --git a/libgo/go/go/doc/example.go b/libgo/go/go/doc/example.go index d5b58d26643..a7e0e250a2e 100644 --- a/libgo/go/go/doc/example.go +++ b/libgo/go/go/doc/example.go @@ -2,47 +2,98 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Extract example functions from package ASTs. +// Extract example functions from file ASTs. package doc import ( "go/ast" - "go/printer" + "go/token" + "regexp" + "sort" "strings" "unicode" "unicode/utf8" ) type Example struct { - Name string // name of the item being demonstrated - Body *printer.CommentedNode // code - Output string // expected output + Name string // name of the item being exemplified + Doc string // example function doc string + Code ast.Node + Comments []*ast.CommentGroup + Output string // expected output } -func Examples(pkg *ast.Package) []*Example { - var examples []*Example - for _, src := range pkg.Files { - for _, decl := range src.Decls { +func Examples(files ...*ast.File) []*Example { + var list []*Example + for _, file := range files { + hasTests := false // file contains tests or benchmarks + numDecl := 0 // number of non-import declarations in the file + var flist []*Example + for _, decl := range file.Decls { + if g, ok := decl.(*ast.GenDecl); ok && g.Tok != token.IMPORT { + numDecl++ + continue + } f, ok := decl.(*ast.FuncDecl) if !ok { continue } + numDecl++ name := f.Name.Name + if isTest(name, "Test") || isTest(name, "Benchmark") { + hasTests = true + continue + } if !isTest(name, "Example") { continue } - examples = append(examples, &Example{ - Name: name[len("Example"):], - Body: &printer.CommentedNode{ - Node: f.Body, - Comments: src.Comments, - }, - Output: f.Doc.Text(), + var doc string + if f.Doc != nil { + doc = f.Doc.Text() + } + flist = append(flist, &Example{ + Name: name[len("Example"):], + Doc: doc, + Code: f.Body, + Comments: file.Comments, + Output: exampleOutput(f, file.Comments), }) } + if !hasTests && numDecl > 1 && len(flist) == 1 { + // If this file only has one example function, some + // other top-level declarations, and no tests or + // benchmarks, use the whole file as the example. + flist[0].Code = file + } + list = append(list, flist...) + } + sort.Sort(exampleByName(list)) + return list +} + +var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`) + +func exampleOutput(fun *ast.FuncDecl, comments []*ast.CommentGroup) string { + // find the last comment in the function + var last *ast.CommentGroup + for _, cg := range comments { + if cg.Pos() < fun.Pos() { + continue + } + if cg.End() > fun.End() { + break + } + last = cg } - return examples + if last != nil { + // test that it begins with the correct prefix + text := last.Text() + if loc := outputPrefix.FindStringIndex(text); loc != nil { + return strings.TrimSpace(text[loc[1]:]) + } + } + return "" // no suitable comment found } // isTest tells whether name looks like a test, example, or benchmark. @@ -58,3 +109,9 @@ func isTest(name, prefix string) bool { rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) return !unicode.IsLower(rune) } + +type exampleByName []*Example + +func (s exampleByName) Len() int { return len(s) } +func (s exampleByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s exampleByName) Less(i, j int) bool { return s[i].Name < s[j].Name } diff --git a/libgo/go/go/doc/exports.go b/libgo/go/go/doc/exports.go index 68dd3841bed..146be5d8707 100644 --- a/libgo/go/go/doc/exports.go +++ b/libgo/go/go/doc/exports.go @@ -22,12 +22,38 @@ func filterIdentList(list []*ast.Ident) []*ast.Ident { return list[0:j] } +// removeErrorField removes anonymous fields named "error" from an interface. +// This is called when "error" has been determined to be a local name, +// not the predeclared type. +// +func removeErrorField(ityp *ast.InterfaceType) { + list := ityp.Methods.List // we know that ityp.Methods != nil + j := 0 + for _, field := range list { + keepField := true + if n := len(field.Names); n == 0 { + // anonymous field + if fname, _ := baseTypeName(field.Type); fname == "error" { + keepField = false + } + } + if keepField { + list[j] = field + j++ + } + } + if j < len(list) { + ityp.Incomplete = true + } + ityp.Methods.List = list[0:j] +} + // filterFieldList removes unexported fields (field names) from the field list // in place and returns true if fields were removed. Anonymous fields are // recorded with the parent type. filterType is called with the types of // all remaining fields. // -func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList) (removedFields bool) { +func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) { if fields == nil { return } @@ -37,9 +63,15 @@ func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList) (remo keepField := false if n := len(field.Names); n == 0 { // anonymous field - name := r.recordAnonymousField(parent, field.Type) - if ast.IsExported(name) { + fname := r.recordAnonymousField(parent, field.Type) + if ast.IsExported(fname) { + keepField = true + } else if ityp != nil && fname == "error" { + // possibly the predeclared error interface; keep + // it for now but remember this interface so that + // it can be fixed if error is also defined locally keepField = true + r.remember(ityp) } } else { field.Names = filterIdentList(field.Names) @@ -86,14 +118,14 @@ func (r *reader) filterType(parent *namedType, typ ast.Expr) { case *ast.ArrayType: r.filterType(nil, t.Elt) case *ast.StructType: - if r.filterFieldList(parent, t.Fields) { + if r.filterFieldList(parent, t.Fields, nil) { t.Incomplete = true } case *ast.FuncType: r.filterParamList(t.Params) r.filterParamList(t.Results) case *ast.InterfaceType: - if r.filterFieldList(parent, t.Methods) { + if r.filterFieldList(parent, t.Methods, t) { t.Incomplete = true } case *ast.MapType: @@ -116,9 +148,12 @@ func (r *reader) filterSpec(spec ast.Spec) bool { return true } case *ast.TypeSpec: - if ast.IsExported(s.Name.Name) { + if name := s.Name.Name; ast.IsExported(name) { r.filterType(r.lookupType(s.Name.Name), s.Type) return true + } else if name == "error" { + // special case: remember that error is declared locally + r.errorDecl = true } } return false diff --git a/libgo/go/go/doc/headscan.go b/libgo/go/go/doc/headscan.go index 37486b126fd..f5593476382 100644 --- a/libgo/go/go/doc/headscan.go +++ b/libgo/go/go/doc/headscan.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + /* The headscan command extracts comment headings from package files; it is used to detect false positives which may require an adjustment diff --git a/libgo/go/go/doc/reader.go b/libgo/go/go/doc/reader.go index dcf49f68fd3..5eaae37b7de 100644 --- a/libgo/go/go/doc/reader.go +++ b/libgo/go/go/doc/reader.go @@ -17,7 +17,7 @@ import ( // // Internally, we treat functions like methods and collect them in method sets. -// methodSet describes a set of methods. Entries where Decl == nil are conflict +// A methodSet describes a set of methods. Entries where Decl == nil are conflict // entries (more then one method with the same name at the same embedding level). // type methodSet map[string]*Func @@ -110,6 +110,9 @@ func baseTypeName(x ast.Expr) (name string, imported bool) { return } +// An embeddedSet describes a set of embedded types. +type embeddedSet map[*namedType]bool + // A namedType represents a named unqualified (package local, or possibly // predeclared) type. The namedType for a type name is always found via // reader.lookupType. @@ -119,9 +122,9 @@ type namedType struct { name string // type name decl *ast.GenDecl // nil if declaration hasn't been seen yet - isEmbedded bool // true if this type is embedded - isStruct bool // true if this type is a struct - embedded map[*namedType]bool // true if the embedded type is a pointer + isEmbedded bool // true if this type is embedded + isStruct bool // true if this type is a struct + embedded embeddedSet // true if the embedded type is a pointer // associated declarations values []*Value // consts and vars @@ -152,6 +155,10 @@ type reader struct { values []*Value // consts and vars types map[string]*namedType funcs methodSet + + // support for package-local error type declarations + errorDecl bool // if set, type "error" was declared locally + fixlist []*ast.InterfaceType // list of interfaces containing anonymous field "error" } func (r *reader) isVisible(name string) bool { @@ -173,7 +180,7 @@ func (r *reader) lookupType(name string) *namedType { // type not found - add one without declaration typ := &namedType{ name: name, - embedded: make(map[*namedType]bool), + embedded: make(embeddedSet), funcs: make(methodSet), methods: make(methodSet), } @@ -210,6 +217,10 @@ func (r *reader) readDoc(comment *ast.CommentGroup) { r.doc += "\n" + text } +func (r *reader) remember(typ *ast.InterfaceType) { + r.fixlist = append(r.fixlist, typ) +} + func specNames(specs []ast.Spec) []string { names := make([]string, 0, len(specs)) // reasonable estimate for _, s := range specs { @@ -274,7 +285,7 @@ func (r *reader) readValue(decl *ast.GenDecl) { // determine values list with which to associate the Value for this decl values := &r.values const threshold = 0.75 - if domName != "" && domFreq >= int(float64(len(decl.Specs))*threshold) { + if domName != "" && r.isVisible(domName) && domFreq >= int(float64(len(decl.Specs))*threshold) { // typed entries are sufficiently frequent if typ := r.lookupType(domName); typ != nil { values = &typ.values // associate with that type @@ -315,7 +326,7 @@ func (r *reader) readType(decl *ast.GenDecl, spec *ast.TypeSpec) { return // no name or blank name - ignore the type } - // A type should be added at most once, so info.decl + // A type should be added at most once, so typ.decl // should be nil - if it is not, simply overwrite it. typ.decl = decl @@ -421,6 +432,17 @@ func (r *reader) readFile(src *ast.File) { r.readValue(d) case token.TYPE: // types are handled individually + if len(d.Specs) == 1 && !d.Lparen.IsValid() { + // common case: single declaration w/o parentheses + // (if a single declaration is parenthesized, + // create a new fake declaration below, so that + // go/doc type declarations always appear w/o + // parentheses) + if s, ok := d.Specs[0].(*ast.TypeSpec); ok { + r.readType(d, s) + } + break + } for _, spec := range d.Specs { if s, ok := spec.(*ast.TypeSpec); ok { // use an individual (possibly fake) declaration @@ -428,8 +450,15 @@ func (r *reader) readFile(src *ast.File) { // gets to (re-)use the declaration documentation // if there's none associated with the spec itself fake := &ast.GenDecl{ - d.Doc, d.Pos(), token.TYPE, token.NoPos, - []ast.Spec{s}, token.NoPos, + Doc: d.Doc, + // don't use the existing TokPos because it + // will lead to the wrong selection range for + // the fake declaration if there are more + // than one type in the group (this affects + // src/cmd/godoc/godoc.go's posLink_urlFunc) + TokPos: s.Pos(), + Tok: token.TYPE, + Specs: []ast.Spec{s}, } r.readType(fake, s) } @@ -449,7 +478,7 @@ func (r *reader) readFile(src *ast.File) { // non-empty BUG comment; collect comment without BUG prefix list := append([]*ast.Comment(nil), c.List...) // make a copy list[0].Text = text[m[1]:] - r.bugs = append(r.bugs, (&ast.CommentGroup{list}).Text()) + r.bugs = append(r.bugs, (&ast.CommentGroup{List: list}).Text()) } } } @@ -519,7 +548,7 @@ func customizeRecv(f *Func, recvTypeName string, embeddedIsPtr bool, level int) _, origRecvIsPtr := newField.Type.(*ast.StarExpr) var typ ast.Expr = ast.NewIdent(recvTypeName) if !embeddedIsPtr && origRecvIsPtr { - typ = &ast.StarExpr{token.NoPos, typ} + typ = &ast.StarExpr{X: typ} } newField.Type = typ @@ -543,7 +572,8 @@ func customizeRecv(f *Func, recvTypeName string, embeddedIsPtr bool, level int) // collectEmbeddedMethods collects the embedded methods of typ in mset. // -func (r *reader) collectEmbeddedMethods(mset methodSet, typ *namedType, recvTypeName string, embeddedIsPtr bool, level int) { +func (r *reader) collectEmbeddedMethods(mset methodSet, typ *namedType, recvTypeName string, embeddedIsPtr bool, level int, visited embeddedSet) { + visited[typ] = true for embedded, isPtr := range typ.embedded { // Once an embedded type is embedded as a pointer type // all embedded types in those types are treated like @@ -557,8 +587,11 @@ func (r *reader) collectEmbeddedMethods(mset methodSet, typ *namedType, recvType mset.add(customizeRecv(m, recvTypeName, thisEmbeddedIsPtr, level)) } } - r.collectEmbeddedMethods(mset, embedded, recvTypeName, thisEmbeddedIsPtr, level+1) + if !visited[embedded] { + r.collectEmbeddedMethods(mset, embedded, recvTypeName, thisEmbeddedIsPtr, level+1, visited) + } } + delete(visited, typ) } // computeMethodSets determines the actual method sets for each type encountered. @@ -568,12 +601,19 @@ func (r *reader) computeMethodSets() { // collect embedded methods for t if t.isStruct { // struct - r.collectEmbeddedMethods(t.methods, t, t.name, false, 1) + r.collectEmbeddedMethods(t.methods, t, t.name, false, 1, make(embeddedSet)) } else { // interface // TODO(gri) fix this } } + + // if error was declared locally, don't treat it as exported field anymore + if r.errorDecl { + for _, ityp := range r.fixlist { + removeErrorField(ityp) + } + } } // cleanupTypes removes the association of functions and methods with diff --git a/libgo/go/go/doc/synopsis.go b/libgo/go/go/doc/synopsis.go new file mode 100644 index 00000000000..2192d78c0cd --- /dev/null +++ b/libgo/go/go/doc/synopsis.go @@ -0,0 +1,52 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package doc + +import "unicode" + +// firstSentenceLen returns the length of the first sentence in s. +// The sentence ends after the first period followed by space and +// not preceded by exactly one uppercase letter. +// +func firstSentenceLen(s string) int { + var ppp, pp, p rune + for i, q := range s { + if q == '\n' || q == '\r' || q == '\t' { + q = ' ' + } + if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) { + return i + } + ppp, pp, p = pp, p, q + } + return len(s) +} + +// Synopsis returns a cleaned version of the first sentence in s. +// That sentence ends after the first period followed by space and +// not preceded by exactly one uppercase letter. The result string +// has no \n, \r, or \t characters and uses only single spaces between +// words. +// +func Synopsis(s string) string { + n := firstSentenceLen(s) + var b []byte + p := byte(' ') + for i := 0; i < n; i++ { + q := s[i] + if q == '\n' || q == '\r' || q == '\t' { + q = ' ' + } + if q != ' ' || p != ' ' { + b = append(b, q) + p = q + } + } + // remove trailing blank, if any + if n := len(b); n > 0 && p == ' ' { + b = b[0 : n-1] + } + return string(b) +} diff --git a/libgo/go/go/doc/synopsis_test.go b/libgo/go/go/doc/synopsis_test.go new file mode 100644 index 00000000000..dfc6598af47 --- /dev/null +++ b/libgo/go/go/doc/synopsis_test.go @@ -0,0 +1,44 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package doc + +import "testing" + +var tests = []struct { + txt string + fsl int + syn string +}{ + {"", 0, ""}, + {"foo", 3, "foo"}, + {"foo.", 4, "foo."}, + {"foo.bar", 7, "foo.bar"}, + {" foo. ", 6, "foo."}, + {" foo\t bar.\n", 12, "foo bar."}, + {" foo\t bar.\n", 12, "foo bar."}, + {"a b\n\nc\r\rd\t\t", 12, "a b c d"}, + {"a b\n\nc\r\rd\t\t . BLA", 15, "a b c d ."}, + {"Package poems by T.S.Eliot. To rhyme...", 27, "Package poems by T.S.Eliot."}, + {"Package poems by T. S. Eliot. To rhyme...", 29, "Package poems by T. S. Eliot."}, + {"foo implements the foo ABI. The foo ABI is...", 27, "foo implements the foo ABI."}, + {"Package\nfoo. ..", 12, "Package foo."}, + {"P . Q.", 3, "P ."}, + {"P. Q. ", 8, "P. Q."}, + {"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."}, + {"Package こんにちは 世界\n", 31, "Package こんにちは 世界"}, +} + +func TestSynopsis(t *testing.T) { + for _, e := range tests { + fsl := firstSentenceLen(e.txt) + if fsl != e.fsl { + t.Errorf("got fsl = %d; want %d for %q\n", fsl, e.fsl, e.txt) + } + syn := Synopsis(e.txt) + if syn != e.syn { + t.Errorf("got syn = %q; want %q for %q\n", syn, e.syn, e.txt) + } + } +} diff --git a/libgo/go/go/doc/testdata/b.0.golden b/libgo/go/go/doc/testdata/b.0.golden index 7c33300616d..9d93392eaa5 100644 --- a/libgo/go/go/doc/testdata/b.0.golden +++ b/libgo/go/go/doc/testdata/b.0.golden @@ -12,18 +12,46 @@ FILENAMES CONSTANTS // + const ( + C1 notExported = iota + C2 + + C4 + C5 + ) + + // + const C notExported = 0 + + // const Pi = 3.14 // Pi VARIABLES // + var ( + U1, U2, U4, U5 notExported + + U7 notExported = 7 + ) + + // var MaxInt int // MaxInt + // + var V notExported + + // + var V1, V2, V4, V5 notExported + FUNCTIONS // func F(x int) int + // + func F1() notExported + // Always under the package functions list. func NotAFactory() int diff --git a/libgo/go/go/doc/testdata/b.1.golden b/libgo/go/go/doc/testdata/b.1.golden index f30380516bd..66c47b5c2a7 100644 --- a/libgo/go/go/doc/testdata/b.1.golden +++ b/libgo/go/go/doc/testdata/b.1.golden @@ -38,8 +38,42 @@ TYPES // func (x *T) M() + // + type notExported int + + // + const ( + C1 notExported = iota + C2 + c3 + C4 + C5 + ) + + // + const C notExported = 0 + + // + var ( + U1, U2, u3, U4, U5 notExported + u6 notExported + U7 notExported = 7 + ) + + // + var V notExported + + // + var V1, V2, v3, V4, V5 notExported + + // + func F1() notExported + + // + func f2() notExported + // Should only appear if AllDecls is set. - type uint struct{} + type uint struct{} // overrides a predeclared type uint // Associated with uint type if AllDecls is set. func UintFactory() uint diff --git a/libgo/go/go/doc/testdata/b.2.golden b/libgo/go/go/doc/testdata/b.2.golden index 7c33300616d..9d93392eaa5 100644 --- a/libgo/go/go/doc/testdata/b.2.golden +++ b/libgo/go/go/doc/testdata/b.2.golden @@ -12,18 +12,46 @@ FILENAMES CONSTANTS // + const ( + C1 notExported = iota + C2 + + C4 + C5 + ) + + // + const C notExported = 0 + + // const Pi = 3.14 // Pi VARIABLES // + var ( + U1, U2, U4, U5 notExported + + U7 notExported = 7 + ) + + // var MaxInt int // MaxInt + // + var V notExported + + // + var V1, V2, V4, V5 notExported + FUNCTIONS // func F(x int) int + // + func F1() notExported + // Always under the package functions list. func NotAFactory() int diff --git a/libgo/go/go/doc/testdata/b.go b/libgo/go/go/doc/testdata/b.go index 28660f9be7c..e50663b3dfa 100644 --- a/libgo/go/go/doc/testdata/b.go +++ b/libgo/go/go/doc/testdata/b.go @@ -6,6 +6,7 @@ package b import "a" +// ---------------------------------------------------------------------------- // Basic declarations const Pi = 3.14 // Pi @@ -28,3 +29,30 @@ func uintFactory() uint {} // Should only appear if AllDecls is set. type uint struct{} // overrides a predeclared type uint + +// ---------------------------------------------------------------------------- +// Exported declarations associated with non-exported types must always be shown. + +type notExported int + +const C notExported = 0 + +const ( + C1 notExported = iota + C2 + c3 + C4 + C5 +) + +var V notExported +var V1, V2, v3, V4, V5 notExported + +var ( + U1, U2, u3, U4, U5 notExported + u6 notExported + U7 notExported = 7 +) + +func F1() notExported {} +func f2() notExported {} diff --git a/libgo/go/go/doc/testdata/benchmark.go b/libgo/go/go/doc/testdata/benchmark.go index 0bf567b7c4d..0aded5bb4c7 100644 --- a/libgo/go/go/doc/testdata/benchmark.go +++ b/libgo/go/go/doc/testdata/benchmark.go @@ -16,7 +16,7 @@ var matchBenchmarks = flag.String("test.bench", "", "regular expression to selec var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds") // An internal type but exported because it is cross-package; part of the implementation -// of gotest. +// of go test. type InternalBenchmark struct { Name string F func(b *B) @@ -213,7 +213,7 @@ func (r BenchmarkResult) String() string { } // An internal function but exported because it is cross-package; part of the implementation -// of gotest. +// of go test. func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) { // If no flag was specified, don't run benchmarks. if len(*matchBenchmarks) == 0 { @@ -281,7 +281,7 @@ func (b *B) trimOutput() { } // Benchmark benchmarks a single function. Useful for creating -// custom benchmarks that do not use gotest. +// custom benchmarks that do not use go test. func Benchmark(f func(b *B)) BenchmarkResult { b := &B{ common: common{ diff --git a/libgo/go/go/doc/testdata/e.0.golden b/libgo/go/go/doc/testdata/e.0.golden index 096a50ff41f..6987e5867cf 100644 --- a/libgo/go/go/doc/testdata/e.0.golden +++ b/libgo/go/go/doc/testdata/e.0.golden @@ -40,3 +40,70 @@ TYPES T4 } + // + type U1 struct { + *U1 + } + + // U1.M should appear as method of U1. + func (*U1) M() + + // + type U2 struct { + *U3 + } + + // U2.M should appear as method of U2 and as method of U3 only if ... + func (*U2) M() + + // + type U3 struct { + *U2 + } + + // U3.N should appear as method of U3 and as method of U2 only if ... + func (*U3) N() + + // + type U4 struct { + // contains filtered or unexported fields + } + + // U4.M should appear as method of U4. + func (*U4) M() + + // + type V1 struct { + *V2 + *V5 + } + + // + type V2 struct { + *V3 + } + + // + type V3 struct { + *V4 + } + + // + type V4 struct { + *V5 + } + + // V4.M should appear as method of V2 and V3 if AllMethods is set. + func (*V4) M() + + // + type V5 struct { + *V6 + } + + // + type V6 struct{} + + // V6.M should appear as method of V1 and V5 if AllMethods is set. + func (*V6) M() + diff --git a/libgo/go/go/doc/testdata/e.1.golden b/libgo/go/go/doc/testdata/e.1.golden index 28be74a1fd6..cbe22e0bf63 100644 --- a/libgo/go/go/doc/testdata/e.1.golden +++ b/libgo/go/go/doc/testdata/e.1.golden @@ -43,6 +43,73 @@ TYPES } // + type U1 struct { + *U1 + } + + // U1.M should appear as method of U1. + func (*U1) M() + + // + type U2 struct { + *U3 + } + + // U2.M should appear as method of U2 and as method of U3 only if ... + func (*U2) M() + + // + type U3 struct { + *U2 + } + + // U3.N should appear as method of U3 and as method of U2 only if ... + func (*U3) N() + + // + type U4 struct { + *u5 + } + + // U4.M should appear as method of U4. + func (*U4) M() + + // + type V1 struct { + *V2 + *V5 + } + + // + type V2 struct { + *V3 + } + + // + type V3 struct { + *V4 + } + + // + type V4 struct { + *V5 + } + + // V4.M should appear as method of V2 and V3 if AllMethods is set. + func (*V4) M() + + // + type V5 struct { + *V6 + } + + // + type V6 struct{} + + // V6.M should appear as method of V1 and V5 if AllMethods is set. + func (*V6) M() + + // type t1 struct{} // t1.M should not appear as method in a Tx type. @@ -70,3 +137,8 @@ TYPES // t2.M should not appear as method in a Tx type. func (t2e) M() + // + type u5 struct { + *U4 + } + diff --git a/libgo/go/go/doc/testdata/e.2.golden b/libgo/go/go/doc/testdata/e.2.golden index f9a2b816774..e7b05e80faf 100644 --- a/libgo/go/go/doc/testdata/e.2.golden +++ b/libgo/go/go/doc/testdata/e.2.golden @@ -43,3 +43,88 @@ TYPES // T4.M should appear as method of T5 only if AllMethods is set. func (*T5) M() + // + type U1 struct { + *U1 + } + + // U1.M should appear as method of U1. + func (*U1) M() + + // + type U2 struct { + *U3 + } + + // U2.M should appear as method of U2 and as method of U3 only if ... + func (*U2) M() + + // U3.N should appear as method of U3 and as method of U2 only if ... + func (U2) N() + + // + type U3 struct { + *U2 + } + + // U2.M should appear as method of U2 and as method of U3 only if ... + func (U3) M() + + // U3.N should appear as method of U3 and as method of U2 only if ... + func (*U3) N() + + // + type U4 struct { + // contains filtered or unexported fields + } + + // U4.M should appear as method of U4. + func (*U4) M() + + // + type V1 struct { + *V2 + *V5 + } + + // V6.M should appear as method of V1 and V5 if AllMethods is set. + func (V1) M() + + // + type V2 struct { + *V3 + } + + // V4.M should appear as method of V2 and V3 if AllMethods is set. + func (V2) M() + + // + type V3 struct { + *V4 + } + + // V4.M should appear as method of V2 and V3 if AllMethods is set. + func (V3) M() + + // + type V4 struct { + *V5 + } + + // V4.M should appear as method of V2 and V3 if AllMethods is set. + func (*V4) M() + + // + type V5 struct { + *V6 + } + + // V6.M should appear as method of V1 and V5 if AllMethods is set. + func (V5) M() + + // + type V6 struct{} + + // V6.M should appear as method of V1 and V5 if AllMethods is set. + func (*V6) M() + diff --git a/libgo/go/go/doc/testdata/e.go b/libgo/go/go/doc/testdata/e.go index 526a91f4f00..19dd138cf40 100644 --- a/libgo/go/go/doc/testdata/e.go +++ b/libgo/go/go/doc/testdata/e.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -77,3 +77,71 @@ func (*T4) M() {} type T5 struct { T4 } + +// ---------------------------------------------------------------------------- +// Recursive type declarations must not lead to endless recursion. + +type U1 struct { + *U1 +} + +// U1.M should appear as method of U1. +func (*U1) M() {} + +type U2 struct { + *U3 +} + +// U2.M should appear as method of U2 and as method of U3 only if AllMethods is set. +func (*U2) M() {} + +type U3 struct { + *U2 +} + +// U3.N should appear as method of U3 and as method of U2 only if AllMethods is set. +func (*U3) N() {} + +type U4 struct { + *u5 +} + +// U4.M should appear as method of U4. +func (*U4) M() {} + +type u5 struct { + *U4 +} + +// ---------------------------------------------------------------------------- +// A higher-level embedded type (and its methods) wins over the same type (and +// its methods) embedded at a lower level. + +type V1 struct { + *V2 + *V5 +} + +type V2 struct { + *V3 +} + +type V3 struct { + *V4 +} + +type V4 struct { + *V5 +} + +type V5 struct { + *V6 +} + +type V6 struct{} + +// V4.M should appear as method of V2 and V3 if AllMethods is set. +func (*V4) M() {} + +// V6.M should appear as method of V1 and V5 if AllMethods is set. +func (*V6) M() {} diff --git a/libgo/go/go/doc/testdata/error1.0.golden b/libgo/go/go/doc/testdata/error1.0.golden new file mode 100644 index 00000000000..6c6fe5d49bd --- /dev/null +++ b/libgo/go/go/doc/testdata/error1.0.golden @@ -0,0 +1,30 @@ +// +PACKAGE error1 + +IMPORTPATH + testdata/error1 + +FILENAMES + testdata/error1.go + +TYPES + // + type I0 interface { + // When embedded, the predeclared error interface + // must remain visible in interface types. + error + } + + // + type S0 struct { + // contains filtered or unexported fields + } + + // + type T0 struct { + ExportedField interface { + // error should be visible + error + } + } + diff --git a/libgo/go/go/doc/testdata/error1.1.golden b/libgo/go/go/doc/testdata/error1.1.golden new file mode 100644 index 00000000000..a8dc2e71dc3 --- /dev/null +++ b/libgo/go/go/doc/testdata/error1.1.golden @@ -0,0 +1,32 @@ +// +PACKAGE error1 + +IMPORTPATH + testdata/error1 + +FILENAMES + testdata/error1.go + +TYPES + // + type I0 interface { + // When embedded, the predeclared error interface + // must remain visible in interface types. + error + } + + // + type S0 struct { + // In struct types, an embedded error must only be visible + // if AllDecls is set. + error + } + + // + type T0 struct { + ExportedField interface { + // error should be visible + error + } + } + diff --git a/libgo/go/go/doc/testdata/error1.2.golden b/libgo/go/go/doc/testdata/error1.2.golden new file mode 100644 index 00000000000..6c6fe5d49bd --- /dev/null +++ b/libgo/go/go/doc/testdata/error1.2.golden @@ -0,0 +1,30 @@ +// +PACKAGE error1 + +IMPORTPATH + testdata/error1 + +FILENAMES + testdata/error1.go + +TYPES + // + type I0 interface { + // When embedded, the predeclared error interface + // must remain visible in interface types. + error + } + + // + type S0 struct { + // contains filtered or unexported fields + } + + // + type T0 struct { + ExportedField interface { + // error should be visible + error + } + } + diff --git a/libgo/go/go/doc/testdata/error1.go b/libgo/go/go/doc/testdata/error1.go new file mode 100644 index 00000000000..3c777a78005 --- /dev/null +++ b/libgo/go/go/doc/testdata/error1.go @@ -0,0 +1,24 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package error1 + +type I0 interface { + // When embedded, the predeclared error interface + // must remain visible in interface types. + error +} + +type T0 struct { + ExportedField interface { + // error should be visible + error + } +} + +type S0 struct { + // In struct types, an embedded error must only be visible + // if AllDecls is set. + error +} diff --git a/libgo/go/go/doc/testdata/error2.0.golden b/libgo/go/go/doc/testdata/error2.0.golden new file mode 100644 index 00000000000..dedfe412a0f --- /dev/null +++ b/libgo/go/go/doc/testdata/error2.0.golden @@ -0,0 +1,27 @@ +// +PACKAGE error2 + +IMPORTPATH + testdata/error2 + +FILENAMES + testdata/error2.go + +TYPES + // + type I0 interface { + // contains filtered or unexported methods + } + + // + type S0 struct { + // contains filtered or unexported fields + } + + // + type T0 struct { + ExportedField interface { + // contains filtered or unexported methods + } + } + diff --git a/libgo/go/go/doc/testdata/error2.1.golden b/libgo/go/go/doc/testdata/error2.1.golden new file mode 100644 index 00000000000..776bd1b3e40 --- /dev/null +++ b/libgo/go/go/doc/testdata/error2.1.golden @@ -0,0 +1,37 @@ +// +PACKAGE error2 + +IMPORTPATH + testdata/error2 + +FILENAMES + testdata/error2.go + +TYPES + // + type I0 interface { + // When embedded, the the locally declared error interface + // is only visible if all declarations are shown. + error + } + + // + type S0 struct { + // In struct types, an embedded error must only be visible + // if AllDecls is set. + error + } + + // + type T0 struct { + ExportedField interface { + // error should not be visible + error + } + } + + // This error declaration shadows the predeclared error type. + type error interface { + Error() string + } + diff --git a/libgo/go/go/doc/testdata/error2.2.golden b/libgo/go/go/doc/testdata/error2.2.golden new file mode 100644 index 00000000000..dedfe412a0f --- /dev/null +++ b/libgo/go/go/doc/testdata/error2.2.golden @@ -0,0 +1,27 @@ +// +PACKAGE error2 + +IMPORTPATH + testdata/error2 + +FILENAMES + testdata/error2.go + +TYPES + // + type I0 interface { + // contains filtered or unexported methods + } + + // + type S0 struct { + // contains filtered or unexported fields + } + + // + type T0 struct { + ExportedField interface { + // contains filtered or unexported methods + } + } + diff --git a/libgo/go/go/doc/testdata/error2.go b/libgo/go/go/doc/testdata/error2.go new file mode 100644 index 00000000000..6cc36feef3e --- /dev/null +++ b/libgo/go/go/doc/testdata/error2.go @@ -0,0 +1,29 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package error2 + +type I0 interface { + // When embedded, the the locally declared error interface + // is only visible if all declarations are shown. + error +} + +type T0 struct { + ExportedField interface { + // error should not be visible + error + } +} + +type S0 struct { + // In struct types, an embedded error must only be visible + // if AllDecls is set. + error +} + +// This error declaration shadows the predeclared error type. +type error interface { + Error() string +} diff --git a/libgo/go/go/doc/testdata/f.go b/libgo/go/go/doc/testdata/f.go index a3051e1fb3b..7e9add90784 100644 --- a/libgo/go/go/doc/testdata/f.go +++ b/libgo/go/go/doc/testdata/f.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/libgo/go/go/doc/testdata/testing.1.golden b/libgo/go/go/doc/testdata/testing.1.golden index 1f92f8fe3e1..d26a4685ca0 100644 --- a/libgo/go/go/doc/testdata/testing.1.golden +++ b/libgo/go/go/doc/testdata/testing.1.golden @@ -27,7 +27,7 @@ VARIABLES // The short flag requests that tests run more quickly, but its functionality // is provided by test writers themselves. The testing package is just its // home. The all.bash installation script sets it to make installation more - // efficient, but by default the flag is off so a plain "gotest" will do a + // efficient, but by default the flag is off so a plain "go test" will do a // full test of the package. short = flag.Bool("test.short", false, "run smaller test suite to save time") diff --git a/libgo/go/go/doc/testdata/testing.go b/libgo/go/go/doc/testdata/testing.go index cfe212dc1d7..71c1d1eaf0e 100644 --- a/libgo/go/go/doc/testdata/testing.go +++ b/libgo/go/go/doc/testdata/testing.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package testing provides support for automated testing of Go packages. -// It is intended to be used in concert with the ``gotest'' utility, which automates +// It is intended to be used in concert with the ``go test'' utility, which automates // execution of any function of the form // func TestXxx(*testing.T) // where Xxx can be any alphanumeric string (but the first letter must not be in @@ -12,7 +12,7 @@ // // Functions of the form // func BenchmarkXxx(*testing.B) -// are considered benchmarks, and are executed by gotest when the -test.bench +// are considered benchmarks, and are executed by go test when the -test.bench // flag is provided. // // A sample benchmark function looks like this: @@ -53,7 +53,7 @@ var ( // The short flag requests that tests run more quickly, but its functionality // is provided by test writers themselves. The testing package is just its // home. The all.bash installation script sets it to make installation more - // efficient, but by default the flag is off so a plain "gotest" will do a + // efficient, but by default the flag is off so a plain "go test" will do a // full test of the package. short = flag.Bool("test.short", false, "run smaller test suite to save time") @@ -205,7 +205,7 @@ func (t *T) Parallel() { } // An internal type but exported because it is cross-package; part of the implementation -// of gotest. +// of go test. type InternalTest struct { Name string F func(*T) @@ -227,7 +227,7 @@ func tRunner(t *T, test *InternalTest) { } // An internal function but exported because it is cross-package; part of the implementation -// of gotest. +// of go test. func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) { flag.Parse() parseCpuList() diff --git a/libgo/go/go/parser/interface.go b/libgo/go/go/parser/interface.go index f1b4ce34d1a..5c203a7846e 100644 --- a/libgo/go/go/parser/interface.go +++ b/libgo/go/go/parser/interface.go @@ -80,13 +80,25 @@ const ( // are returned via a scanner.ErrorList which is sorted by file position. // func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (*ast.File, error) { + // get source text, err := readSource(filename, src) if err != nil { return nil, err } + + // parse source var p parser p.init(fset, filename, text, mode) - return p.parseFile(), p.errors() + f := p.parseFile() + + // sort errors + if p.mode&SpuriousErrors == 0 { + p.errors.RemoveMultiples() + } else { + p.errors.Sort() + } + + return f, p.errors.Err() } // ParseDir calls ParseFile for the files in the directory specified by path and diff --git a/libgo/go/go/parser/parser.go b/libgo/go/go/parser/parser.go index 6bee8de9f65..a122baf0879 100644 --- a/libgo/go/go/parser/parser.go +++ b/libgo/go/go/parser/parser.go @@ -14,12 +14,15 @@ import ( "go/ast" "go/scanner" "go/token" + "strconv" + "strings" + "unicode" ) // The parser structure holds the parser's internal state. type parser struct { - file *token.File - scanner.ErrorVector + file *token.File + errors scanner.ErrorList scanner scanner.Scanner // Tracing/debugging @@ -58,7 +61,8 @@ func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mod if mode&ParseComments != 0 { m = scanner.ScanComments } - p.scanner.Init(p.file, src, p, m) + eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) } + p.scanner.Init(p.file, src, eh, m) p.mode = mode p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently) @@ -74,14 +78,6 @@ func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mod p.openLabelScope() } -func (p *parser) errors() error { - m := scanner.Sorted - if p.mode&SpuriousErrors == 0 { - m = scanner.NoMultiples - } - return p.GetError(m) -} - // ---------------------------------------------------------------------------- // Scoping support @@ -256,7 +252,7 @@ func (p *parser) consumeComment() (comment *ast.Comment, endline int) { } } - comment = &ast.Comment{p.pos, p.lit} + comment = &ast.Comment{Slash: p.pos, Text: p.lit} p.next0() return @@ -277,7 +273,7 @@ func (p *parser) consumeCommentGroup() (comments *ast.CommentGroup, endline int) } // add comment group to the comments list - comments = &ast.CommentGroup{list} + comments = &ast.CommentGroup{List: list} p.comments = append(p.comments, comments) return @@ -334,7 +330,7 @@ func (p *parser) next() { } func (p *parser) error(pos token.Pos, msg string) { - p.Error(p.file.Position(pos), msg) + p.errors.Add(p.file.Position(pos), msg) } func (p *parser) errorExpected(pos token.Pos, msg string) { @@ -342,7 +338,7 @@ func (p *parser) errorExpected(pos token.Pos, msg string) { if pos == p.pos { // the error happened at the current position; // make the error message more specific - if p.tok == token.SEMICOLON && p.lit[0] == '\n' { + if p.tok == token.SEMICOLON && p.lit == "\n" { msg += ", found newline" } else { msg += ", found '" + p.tok.String() + "'" @@ -363,6 +359,17 @@ func (p *parser) expect(tok token.Token) token.Pos { return pos } +// expectClosing is like expect but provides a better error message +// for the common case of a missing comma before a newline. +// +func (p *parser) expectClosing(tok token.Token, construct string) token.Pos { + if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" { + p.error(p.pos, "missing ',' before newline in "+construct) + p.next() + } + return p.expect(tok) +} + func (p *parser) expectSemi() { if p.tok != token.RPAREN && p.tok != token.RBRACE { p.expect(token.SEMICOLON) @@ -387,7 +394,7 @@ func (p *parser) parseIdent() *ast.Ident { } else { p.expect(token.IDENT) // use expect() error handling } - return &ast.Ident{pos, name, nil} + return &ast.Ident{NamePos: pos, Name: name} } func (p *parser) parseIdentList() (list []*ast.Ident) { @@ -465,7 +472,7 @@ func (p *parser) parseType() ast.Expr { pos := p.pos p.errorExpected(pos, "type") p.next() // make progress - return &ast.BadExpr{pos, p.pos} + return &ast.BadExpr{From: pos, To: p.pos} } return typ @@ -485,7 +492,7 @@ func (p *parser) parseTypeName() ast.Expr { p.next() p.resolve(ident) sel := p.parseIdent() - return &ast.SelectorExpr{ident, sel} + return &ast.SelectorExpr{X: ident, Sel: sel} } return ident @@ -499,7 +506,7 @@ func (p *parser) parseArrayType(ellipsisOk bool) ast.Expr { lbrack := p.expect(token.LBRACK) var len ast.Expr if ellipsisOk && p.tok == token.ELLIPSIS { - len = &ast.Ellipsis{p.pos, nil} + len = &ast.Ellipsis{Ellipsis: p.pos} p.next() } else if p.tok != token.RBRACK { len = p.parseRhs() @@ -507,7 +514,7 @@ func (p *parser) parseArrayType(ellipsisOk bool) ast.Expr { p.expect(token.RBRACK) elt := p.parseType() - return &ast.ArrayType{lbrack, len, elt} + return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt} } func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident { @@ -517,7 +524,7 @@ func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident { if !isIdent { pos := x.Pos() p.errorExpected(pos, "identifier") - ident = &ast.Ident{pos, "_", nil} + ident = &ast.Ident{NamePos: pos, Name: "_"} } idents[i] = ident } @@ -537,7 +544,7 @@ func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field { // optional tag var tag *ast.BasicLit if p.tok == token.STRING { - tag = &ast.BasicLit{p.pos, p.tok, p.lit} + tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit} p.next() } @@ -553,13 +560,13 @@ func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field { if n := len(list); n > 1 || !isTypeName(deref(typ)) { pos := typ.Pos() p.errorExpected(pos, "anonymous field") - typ = &ast.BadExpr{pos, list[n-1].End()} + typ = &ast.BadExpr{From: pos, To: list[n-1].End()} } } p.expectSemi() // call before accessing p.linecomment - field := &ast.Field{doc, idents, typ, tag, p.lineComment} + field := &ast.Field{Doc: doc, Names: idents, Type: typ, Tag: tag, Comment: p.lineComment} p.declare(field, nil, scope, ast.Var, idents...) return field @@ -582,7 +589,14 @@ func (p *parser) parseStructType() *ast.StructType { } rbrace := p.expect(token.RBRACE) - return &ast.StructType{pos, &ast.FieldList{lbrace, list, rbrace}, false} + return &ast.StructType{ + Struct: pos, + Fields: &ast.FieldList{ + Opening: lbrace, + List: list, + Closing: rbrace, + }, + } } func (p *parser) parsePointerType() *ast.StarExpr { @@ -593,7 +607,7 @@ func (p *parser) parsePointerType() *ast.StarExpr { star := p.expect(token.MUL) base := p.parseType() - return &ast.StarExpr{star, base} + return &ast.StarExpr{Star: star, X: base} } func (p *parser) tryVarType(isParam bool) ast.Expr { @@ -603,9 +617,9 @@ func (p *parser) tryVarType(isParam bool) ast.Expr { typ := p.tryIdentOrType(isParam) // don't use parseType so we can provide better error message if typ == nil { p.error(pos, "'...' parameter is missing type") - typ = &ast.BadExpr{pos, p.pos} + typ = &ast.BadExpr{From: pos, To: p.pos} } - return &ast.Ellipsis{pos, typ} + return &ast.Ellipsis{Ellipsis: pos, Elt: typ} } return p.tryIdentOrType(false) } @@ -616,7 +630,7 @@ func (p *parser) parseVarType(isParam bool) ast.Expr { pos := p.pos p.errorExpected(pos, "type") p.next() // make progress - typ = &ast.BadExpr{pos, p.pos} + typ = &ast.BadExpr{From: pos, To: p.pos} } return typ } @@ -657,7 +671,7 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ if typ != nil { // IdentifierList Type idents := p.makeIdentList(list) - field := &ast.Field{nil, idents, typ, nil, nil} + field := &ast.Field{Names: idents, Type: typ} params = append(params, field) // Go spec: The scope of an identifier denoting a function // parameter or result variable is the function body. @@ -669,7 +683,7 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ for p.tok != token.RPAREN && p.tok != token.EOF { idents := p.parseIdentList() typ := p.parseVarType(ellipsisOk) - field := &ast.Field{nil, idents, typ, nil, nil} + field := &ast.Field{Names: idents, Type: typ} params = append(params, field) // Go spec: The scope of an identifier denoting a function // parameter or result variable is the function body. @@ -704,7 +718,7 @@ func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldLi } rparen := p.expect(token.RPAREN) - return &ast.FieldList{lparen, params, rparen} + return &ast.FieldList{Opening: lparen, List: params, Closing: rparen} } func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList { @@ -746,7 +760,7 @@ func (p *parser) parseFuncType() (*ast.FuncType, *ast.Scope) { scope := ast.NewScope(p.topScope) // function scope params, results := p.parseSignature(scope) - return &ast.FuncType{pos, params, results}, scope + return &ast.FuncType{Func: pos, Params: params, Results: results}, scope } func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field { @@ -763,7 +777,7 @@ func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field { idents = []*ast.Ident{ident} scope := ast.NewScope(nil) // method scope params, results := p.parseSignature(scope) - typ = &ast.FuncType{token.NoPos, params, results} + typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results} } else { // embedded interface typ = x @@ -771,7 +785,7 @@ func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field { } p.expectSemi() // call before accessing p.linecomment - spec := &ast.Field{doc, idents, typ, nil, p.lineComment} + spec := &ast.Field{Doc: doc, Names: idents, Type: typ, Comment: p.lineComment} p.declare(spec, nil, scope, ast.Fun, idents...) return spec @@ -791,7 +805,14 @@ func (p *parser) parseInterfaceType() *ast.InterfaceType { } rbrace := p.expect(token.RBRACE) - return &ast.InterfaceType{pos, &ast.FieldList{lbrace, list, rbrace}, false} + return &ast.InterfaceType{ + Interface: pos, + Methods: &ast.FieldList{ + Opening: lbrace, + List: list, + Closing: rbrace, + }, + } } func (p *parser) parseMapType() *ast.MapType { @@ -805,7 +826,7 @@ func (p *parser) parseMapType() *ast.MapType { p.expect(token.RBRACK) value := p.parseType() - return &ast.MapType{pos, key, value} + return &ast.MapType{Map: pos, Key: key, Value: value} } func (p *parser) parseChanType() *ast.ChanType { @@ -828,7 +849,7 @@ func (p *parser) parseChanType() *ast.ChanType { } value := p.parseType() - return &ast.ChanType{pos, dir, value} + return &ast.ChanType{Begin: pos, Dir: dir, Value: value} } // If the result is an identifier, it is not resolved. @@ -856,7 +877,7 @@ func (p *parser) tryIdentOrType(ellipsisOk bool) ast.Expr { p.next() typ := p.parseType() rparen := p.expect(token.RPAREN) - return &ast.ParenExpr{lparen, typ, rparen} + return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen} } // no type found @@ -899,7 +920,7 @@ func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt { p.closeScope() rbrace := p.expect(token.RBRACE) - return &ast.BlockStmt{lbrace, list, rbrace} + return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} } func (p *parser) parseBlockStmt() *ast.BlockStmt { @@ -913,7 +934,7 @@ func (p *parser) parseBlockStmt() *ast.BlockStmt { p.closeScope() rbrace := p.expect(token.RBRACE) - return &ast.BlockStmt{lbrace, list, rbrace} + return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} } // ---------------------------------------------------------------------------- @@ -934,7 +955,7 @@ func (p *parser) parseFuncTypeOrLit() ast.Expr { body := p.parseBody(scope) p.exprLev-- - return &ast.FuncLit{typ, body} + return &ast.FuncLit{Type: typ, Body: body} } // parseOperand may return an expression or a raw type (incl. array @@ -955,7 +976,7 @@ func (p *parser) parseOperand(lhs bool) ast.Expr { return x case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING: - x := &ast.BasicLit{p.pos, p.tok, p.lit} + x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit} p.next() return x @@ -966,7 +987,7 @@ func (p *parser) parseOperand(lhs bool) ast.Expr { x := p.parseRhsOrType() // types may be parenthesized: (some type) p.exprLev-- rparen := p.expect(token.RPAREN) - return &ast.ParenExpr{lparen, x, rparen} + return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen} case token.FUNC: return p.parseFuncTypeOrLit() @@ -983,7 +1004,7 @@ func (p *parser) parseOperand(lhs bool) ast.Expr { pos := p.pos p.errorExpected(pos, "operand") p.next() // make progress - return &ast.BadExpr{pos, p.pos} + return &ast.BadExpr{From: pos, To: p.pos} } func (p *parser) parseSelector(x ast.Expr) ast.Expr { @@ -993,7 +1014,7 @@ func (p *parser) parseSelector(x ast.Expr) ast.Expr { sel := p.parseIdent() - return &ast.SelectorExpr{x, sel} + return &ast.SelectorExpr{X: x, Sel: sel} } func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr { @@ -1011,7 +1032,7 @@ func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr { } p.expect(token.RPAREN) - return &ast.TypeAssertExpr{x, typ} + return &ast.TypeAssertExpr{X: x, Type: typ} } func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr { @@ -1037,9 +1058,9 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr { rbrack := p.expect(token.RBRACK) if isSlice { - return &ast.SliceExpr{x, lbrack, low, high, rbrack} + return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: low, High: high, Rbrack: rbrack} } - return &ast.IndexExpr{x, lbrack, low, rbrack} + return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: low, Rbrack: rbrack} } func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr { @@ -1063,9 +1084,9 @@ func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr { p.next() } p.exprLev-- - rparen := p.expect(token.RPAREN) + rparen := p.expectClosing(token.RPAREN, "argument list") - return &ast.CallExpr{fun, lparen, list, ellipsis, rparen} + return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen} } func (p *parser) parseElement(keyOk bool) ast.Expr { @@ -1082,7 +1103,7 @@ func (p *parser) parseElement(keyOk bool) ast.Expr { if p.tok == token.COLON { colon := p.pos p.next() - return &ast.KeyValueExpr{x, colon, p.parseElement(false)} + return &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseElement(false)} } p.resolve(x) // not a map key } @@ -1118,8 +1139,8 @@ func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr { elts = p.parseElementList() } p.exprLev-- - rbrace := p.expect(token.RBRACE) - return &ast.CompositeLit{typ, lbrace, elts, rbrace} + rbrace := p.expectClosing(token.RBRACE, "composite literal") + return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace} } // checkExpr checks that x is an expression (and not a type). @@ -1148,7 +1169,7 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { default: // all other nodes are not proper expressions p.errorExpected(x.Pos(), "expression") - x = &ast.BadExpr{x.Pos(), x.End()} + x = &ast.BadExpr{From: x.Pos(), To: x.End()} } return x } @@ -1211,7 +1232,7 @@ func (p *parser) checkExprOrType(x ast.Expr) ast.Expr { case *ast.ArrayType: if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis { p.error(len.Pos(), "expected array length, found '...'") - x = &ast.BadExpr{x.Pos(), x.End()} + x = &ast.BadExpr{From: x.Pos(), To: x.End()} } } @@ -1243,7 +1264,7 @@ L: pos := p.pos p.next() // make progress p.errorExpected(pos, "selector or type assertion") - x = &ast.BadExpr{pos, p.pos} + x = &ast.BadExpr{From: pos, To: p.pos} } case token.LBRACK: if lhs { @@ -1284,7 +1305,7 @@ func (p *parser) parseUnaryExpr(lhs bool) ast.Expr { pos, op := p.pos, p.tok p.next() x := p.parseUnaryExpr(false) - return &ast.UnaryExpr{pos, op, p.checkExpr(x)} + return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)} case token.ARROW: // channel type or receive expression @@ -1293,18 +1314,18 @@ func (p *parser) parseUnaryExpr(lhs bool) ast.Expr { if p.tok == token.CHAN { p.next() value := p.parseType() - return &ast.ChanType{pos, ast.RECV, value} + return &ast.ChanType{Begin: pos, Dir: ast.RECV, Value: value} } x := p.parseUnaryExpr(false) - return &ast.UnaryExpr{pos, token.ARROW, p.checkExpr(x)} + return &ast.UnaryExpr{OpPos: pos, Op: token.ARROW, X: p.checkExpr(x)} case token.MUL: // pointer type or unary "*" expression pos := p.pos p.next() x := p.parseUnaryExpr(false) - return &ast.StarExpr{pos, p.checkExprOrType(x)} + return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)} } return p.parsePrimaryExpr(lhs) @@ -1326,7 +1347,7 @@ func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr { lhs = false } y := p.parseBinaryExpr(false, prec+1) - x = &ast.BinaryExpr{p.checkExpr(x), pos, op, p.checkExpr(y)} + x = &ast.BinaryExpr{X: p.checkExpr(x), OpPos: pos, Op: op, Y: p.checkExpr(y)} } } @@ -1388,12 +1409,12 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) { if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) { pos := p.pos p.next() - y = []ast.Expr{&ast.UnaryExpr{pos, token.RANGE, p.parseRhs()}} + y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}} isRange = true } else { y = p.parseRhsList() } - as := &ast.AssignStmt{x, pos, tok, y} + as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y} if tok == token.DEFINE { p.shortVarDecl(as, x) } @@ -1414,7 +1435,7 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) { // Go spec: The scope of a label is the body of the function // in which it is declared and excludes the body of any nested // function. - stmt := &ast.LabeledStmt{label, colon, p.parseStmt()} + stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()} p.declare(stmt, nil, p.labelScope, ast.Lbl, label) return stmt, false } @@ -1425,24 +1446,24 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) { // before the ':' that caused the problem. Thus, use the (latest) colon // position for error reporting. p.error(colon, "illegal label declaration") - return &ast.BadStmt{x[0].Pos(), colon + 1}, false + return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false case token.ARROW: // send statement arrow := p.pos p.next() y := p.parseRhs() - return &ast.SendStmt{x[0], arrow, y}, false + return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false case token.INC, token.DEC: // increment or decrement - s := &ast.IncDecStmt{x[0], p.pos, p.tok} + s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok} p.next() return s, false } // expression - return &ast.ExprStmt{x[0]}, false + return &ast.ExprStmt{X: x[0]}, false } func (p *parser) parseCallExpr() *ast.CallExpr { @@ -1463,10 +1484,10 @@ func (p *parser) parseGoStmt() ast.Stmt { call := p.parseCallExpr() p.expectSemi() if call == nil { - return &ast.BadStmt{pos, pos + 2} // len("go") + return &ast.BadStmt{From: pos, To: pos + 2} // len("go") } - return &ast.GoStmt{pos, call} + return &ast.GoStmt{Go: pos, Call: call} } func (p *parser) parseDeferStmt() ast.Stmt { @@ -1478,10 +1499,10 @@ func (p *parser) parseDeferStmt() ast.Stmt { call := p.parseCallExpr() p.expectSemi() if call == nil { - return &ast.BadStmt{pos, pos + 5} // len("defer") + return &ast.BadStmt{From: pos, To: pos + 5} // len("defer") } - return &ast.DeferStmt{pos, call} + return &ast.DeferStmt{Defer: pos, Call: call} } func (p *parser) parseReturnStmt() *ast.ReturnStmt { @@ -1497,7 +1518,7 @@ func (p *parser) parseReturnStmt() *ast.ReturnStmt { } p.expectSemi() - return &ast.ReturnStmt{pos, x} + return &ast.ReturnStmt{Return: pos, Results: x} } func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt { @@ -1515,7 +1536,7 @@ func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt { } p.expectSemi() - return &ast.BranchStmt{pos, tok, label} + return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label} } func (p *parser) makeExpr(s ast.Stmt) ast.Expr { @@ -1526,7 +1547,7 @@ func (p *parser) makeExpr(s ast.Stmt) ast.Expr { return p.checkExpr(es.X) } p.error(s.Pos(), "expected condition, found simple statement") - return &ast.BadExpr{s.Pos(), s.End()} + return &ast.BadExpr{From: s.Pos(), To: s.End()} } func (p *parser) parseIfStmt() *ast.IfStmt { @@ -1568,7 +1589,7 @@ func (p *parser) parseIfStmt() *ast.IfStmt { p.expectSemi() } - return &ast.IfStmt{pos, s, x, body, else_} + return &ast.IfStmt{If: pos, Init: s, Cond: x, Body: body, Else: else_} } func (p *parser) parseTypeList() (list []ast.Expr) { @@ -1608,7 +1629,7 @@ func (p *parser) parseCaseClause(typeSwitch bool) *ast.CaseClause { body := p.parseStmtList() p.closeScope() - return &ast.CaseClause{pos, list, colon, body} + return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body} } func isTypeSwitchAssert(x ast.Expr) bool { @@ -1677,13 +1698,13 @@ func (p *parser) parseSwitchStmt() ast.Stmt { } rbrace := p.expect(token.RBRACE) p.expectSemi() - body := &ast.BlockStmt{lbrace, list, rbrace} + body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} if typeSwitch { - return &ast.TypeSwitchStmt{pos, s1, s2, body} + return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body} } - return &ast.SwitchStmt{pos, s1, p.makeExpr(s2), body} + return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2), Body: body} } func (p *parser) parseCommClause() *ast.CommClause { @@ -1706,7 +1727,7 @@ func (p *parser) parseCommClause() *ast.CommClause { arrow := p.pos p.next() rhs := p.parseRhs() - comm = &ast.SendStmt{lhs[0], arrow, rhs} + comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs} } else { // RecvStmt if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE { @@ -1719,7 +1740,7 @@ func (p *parser) parseCommClause() *ast.CommClause { pos := p.pos p.next() rhs := p.parseRhs() - as := &ast.AssignStmt{lhs, pos, tok, []ast.Expr{rhs}} + as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}} if tok == token.DEFINE { p.shortVarDecl(as, lhs) } @@ -1730,7 +1751,7 @@ func (p *parser) parseCommClause() *ast.CommClause { p.errorExpected(lhs[0].Pos(), "1 expression") // continue with first expression } - comm = &ast.ExprStmt{lhs[0]} + comm = &ast.ExprStmt{X: lhs[0]} } } } else { @@ -1741,7 +1762,7 @@ func (p *parser) parseCommClause() *ast.CommClause { body := p.parseStmtList() p.closeScope() - return &ast.CommClause{pos, comm, colon, body} + return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body} } func (p *parser) parseSelectStmt() *ast.SelectStmt { @@ -1757,9 +1778,9 @@ func (p *parser) parseSelectStmt() *ast.SelectStmt { } rbrace := p.expect(token.RBRACE) p.expectSemi() - body := &ast.BlockStmt{lbrace, list, rbrace} + body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} - return &ast.SelectStmt{pos, body} + return &ast.SelectStmt{Select: pos, Body: body} } func (p *parser) parseForStmt() ast.Stmt { @@ -1808,16 +1829,30 @@ func (p *parser) parseForStmt() ast.Stmt { key = as.Lhs[0] default: p.errorExpected(as.Lhs[0].Pos(), "1 or 2 expressions") - return &ast.BadStmt{pos, body.End()} + return &ast.BadStmt{From: pos, To: body.End()} } // parseSimpleStmt returned a right-hand side that // is a single unary expression of the form "range x" x := as.Rhs[0].(*ast.UnaryExpr).X - return &ast.RangeStmt{pos, key, value, as.TokPos, as.Tok, x, body} + return &ast.RangeStmt{ + For: pos, + Key: key, + Value: value, + TokPos: as.TokPos, + Tok: as.Tok, + X: x, + Body: body, + } } // regular for statement - return &ast.ForStmt{pos, s1, p.makeExpr(s2), s3, body} + return &ast.ForStmt{ + For: pos, + Init: s1, + Cond: p.makeExpr(s2), + Post: s3, + Body: body, + } } func (p *parser) parseStmt() (s ast.Stmt) { @@ -1827,12 +1862,12 @@ func (p *parser) parseStmt() (s ast.Stmt) { switch p.tok { case token.CONST, token.TYPE, token.VAR: - s = &ast.DeclStmt{p.parseDecl()} + s = &ast.DeclStmt{Decl: p.parseDecl()} case - // tokens that may start a top-level expression - token.IDENT, token.INT, token.FLOAT, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operand - token.LBRACK, token.STRUCT, // composite type - token.MUL, token.AND, token.ARROW, token.ADD, token.SUB, token.XOR: // unary operators + // tokens that may start an expression + token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands + token.LBRACK, token.STRUCT, // composite types + token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators s, _ = p.parseSimpleStmt(labelOk) // because of the required look-ahead, labeled statements are // parsed by parseSimpleStmt - don't expect a semicolon after @@ -1860,17 +1895,17 @@ func (p *parser) parseStmt() (s ast.Stmt) { case token.FOR: s = p.parseForStmt() case token.SEMICOLON: - s = &ast.EmptyStmt{p.pos} + s = &ast.EmptyStmt{Semicolon: p.pos} p.next() case token.RBRACE: // a semicolon may be omitted before a closing "}" - s = &ast.EmptyStmt{p.pos} + s = &ast.EmptyStmt{Semicolon: p.pos} default: // no statement found pos := p.pos p.errorExpected(pos, "statement") p.next() // make progress - s = &ast.BadStmt{pos, p.pos} + s = &ast.BadStmt{From: pos, To: p.pos} } return @@ -1881,6 +1916,17 @@ func (p *parser) parseStmt() (s ast.Stmt) { type parseSpecFunction func(p *parser, doc *ast.CommentGroup, iota int) ast.Spec +func isValidImport(lit string) bool { + const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" + s, _ := strconv.Unquote(lit) // go/scanner returns a legal string literal + for _, r := range s { + if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { + return false + } + } + return s != "" +} + func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { if p.trace { defer un(trace(p, "ImportSpec")) @@ -1889,7 +1935,7 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { var ident *ast.Ident switch p.tok { case token.PERIOD: - ident = &ast.Ident{p.pos, ".", nil} + ident = &ast.Ident{NamePos: p.pos, Name: "."} p.next() case token.IDENT: ident = p.parseIdent() @@ -1897,7 +1943,10 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { var path *ast.BasicLit if p.tok == token.STRING { - path = &ast.BasicLit{p.pos, p.tok, p.lit} + if !isValidImport(p.lit) { + p.error(p.pos, "invalid import path: "+p.lit) + } + path = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit} p.next() } else { p.expect(token.STRING) // use expect() error handling @@ -1905,7 +1954,12 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { p.expectSemi() // call before accessing p.linecomment // collect imports - spec := &ast.ImportSpec{doc, ident, path, p.lineComment, token.NoPos} + spec := &ast.ImportSpec{ + Doc: doc, + Name: ident, + Path: path, + Comment: p.lineComment, + } p.imports = append(p.imports, spec) return spec @@ -1929,7 +1983,13 @@ func parseConstSpec(p *parser, doc *ast.CommentGroup, iota int) ast.Spec { // a function begins at the end of the ConstSpec or VarSpec and ends at // the end of the innermost containing block. // (Global identifiers are resolved in a separate phase after parsing.) - spec := &ast.ValueSpec{doc, idents, typ, values, p.lineComment} + spec := &ast.ValueSpec{ + Doc: doc, + Names: idents, + Type: typ, + Values: values, + Comment: p.lineComment, + } p.declare(spec, iota, p.topScope, ast.Con, idents...) return spec @@ -1946,7 +2006,7 @@ func parseTypeSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { // at the identifier in the TypeSpec and ends at the end of the innermost // containing block. // (Global identifiers are resolved in a separate phase after parsing.) - spec := &ast.TypeSpec{doc, ident, nil, nil} + spec := &ast.TypeSpec{Doc: doc, Name: ident} p.declare(spec, nil, p.topScope, ast.Typ, ident) spec.Type = p.parseType() @@ -1974,7 +2034,13 @@ func parseVarSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec { // a function begins at the end of the ConstSpec or VarSpec and ends at // the end of the innermost containing block. // (Global identifiers are resolved in a separate phase after parsing.) - spec := &ast.ValueSpec{doc, idents, typ, values, p.lineComment} + spec := &ast.ValueSpec{ + Doc: doc, + Names: idents, + Type: typ, + Values: values, + Comment: p.lineComment, + } p.declare(spec, nil, p.topScope, ast.Var, idents...) return spec @@ -2001,7 +2067,14 @@ func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.Gen list = append(list, f(p, nil, 0)) } - return &ast.GenDecl{doc, pos, keyword, lparen, list, rparen} + return &ast.GenDecl{ + Doc: doc, + TokPos: pos, + Tok: keyword, + Lparen: lparen, + Specs: list, + Rparen: rparen, + } } func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { @@ -2014,7 +2087,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { // must have exactly one receiver if par.NumFields() != 1 { p.errorExpected(par.Opening, "exactly one receiver") - par.List = []*ast.Field{{Type: &ast.BadExpr{par.Opening, par.Closing + 1}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{From: par.Opening, To: par.Closing + 1}}} return par } @@ -2023,7 +2096,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { base := deref(recv.Type) if _, isIdent := base.(*ast.Ident); !isIdent { p.errorExpected(base.Pos(), "(unqualified) identifier") - par.List = []*ast.Field{{Type: &ast.BadExpr{recv.Pos(), recv.End()}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{From: recv.Pos(), To: recv.End()}}} } return par @@ -2053,7 +2126,17 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl { } p.expectSemi() - decl := &ast.FuncDecl{doc, recv, ident, &ast.FuncType{pos, params, results}, body} + decl := &ast.FuncDecl{ + Doc: doc, + Recv: recv, + Name: ident, + Type: &ast.FuncType{ + Func: pos, + Params: params, + Results: results, + }, + Body: body, + } if recv == nil { // Go spec: The scope of an identifier denoting a constant, type, // variable, or function (but not method) declared at top level @@ -2092,7 +2175,7 @@ func (p *parser) parseDecl() ast.Decl { pos := p.pos p.errorExpected(pos, "declaration") p.next() // make progress - decl := &ast.BadDecl{pos, p.pos} + decl := &ast.BadDecl{From: pos, To: p.pos} return decl } @@ -2123,7 +2206,7 @@ func (p *parser) parseFile() *ast.File { // Don't bother parsing the rest if we had errors already. // Likely not a Go source file at all. - if p.ErrorCount() == 0 && p.mode&PackageClauseOnly == 0 { + if p.errors.Len() == 0 && p.mode&PackageClauseOnly == 0 { // import decls for p.tok == token.IMPORT { decls = append(decls, p.parseGenDecl(token.IMPORT, parseImportSpec)) @@ -2151,5 +2234,14 @@ func (p *parser) parseFile() *ast.File { } } - return &ast.File{doc, pos, ident, decls, p.pkgScope, p.imports, p.unresolved[0:i], p.comments} + return &ast.File{ + Doc: doc, + Package: pos, + Name: ident, + Decls: decls, + Scope: p.pkgScope, + Imports: p.imports, + Unresolved: p.unresolved[0:i], + Comments: p.comments, + } } diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go index a3ee8525de2..93ca3d6aa39 100644 --- a/libgo/go/go/parser/parser_test.go +++ b/libgo/go/go/parser/parser_test.go @@ -5,6 +5,7 @@ package parser import ( + "fmt" "go/ast" "go/token" "os" @@ -204,3 +205,48 @@ func TestVarScope(t *testing.T) { } } } + +var imports = map[string]bool{ + `"a"`: true, + "`a`": true, + `"a/b"`: true, + `"a.b"`: true, + `"m\x61th"`: true, + `"greek/αβ"`: true, + `""`: false, + + // Each of these pairs tests both `` vs "" strings + // and also use of invalid characters spelled out as + // escape sequences and written directly. + // For example `"\x00"` tests import "\x00" + // while "`\x00`" tests import `<actual-NUL-byte>`. + `"\x00"`: false, + "`\x00`": false, + `"\x7f"`: false, + "`\x7f`": false, + `"a!"`: false, + "`a!`": false, + `"a b"`: false, + "`a b`": false, + `"a\\b"`: false, + "`a\\b`": false, + "\"`a`\"": false, + "`\"a\"`": false, + `"\x80\x80"`: false, + "`\x80\x80`": false, + `"\xFFFD"`: false, + "`\xFFFD`": false, +} + +func TestImports(t *testing.T) { + for path, isValid := range imports { + src := fmt.Sprintf("package p; import %s", path) + _, err := ParseFile(fset, "", src, 0) + switch { + case err != nil && isValid: + t.Errorf("ParseFile(%s): got %v; expected no error", src, err) + case err == nil && !isValid: + t.Errorf("ParseFile(%s): got no error; expected one", src) + } + } +} diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go index 25935fb42bb..05b4ef59a2d 100644 --- a/libgo/go/go/printer/nodes.go +++ b/libgo/go/go/printer/nodes.go @@ -12,6 +12,7 @@ import ( "bytes" "go/ast" "go/token" + "unicode/utf8" ) // Other formatting issues: @@ -82,47 +83,37 @@ func (p *printer) setComment(g *ast.CommentGroup) { type exprListMode uint const ( - blankStart exprListMode = 1 << iota // print a blank before a non-empty list - blankEnd // print a blank after a non-empty list - commaSep // elements are separated by commas - commaTerm // list is optionally terminated by a comma - noIndent // no extra indentation in multi-line lists - periodSep // elements are separated by periods + commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma + noIndent // no extra indentation in multi-line lists ) -// Sets multiLine to true if the identifier list spans multiple lines. // If indent is set, a multi-line identifier list is indented after the // first linebreak encountered. -func (p *printer) identList(list []*ast.Ident, indent bool, multiLine *bool) { +func (p *printer) identList(list []*ast.Ident, indent bool) { // convert into an expression list so we can re-use exprList formatting xlist := make([]ast.Expr, len(list)) for i, x := range list { xlist[i] = x } - mode := commaSep + var mode exprListMode if !indent { - mode |= noIndent + mode = noIndent } - p.exprList(token.NoPos, xlist, 1, mode, multiLine, token.NoPos) + p.exprList(token.NoPos, xlist, 1, mode, token.NoPos) } // Print a list of expressions. If the list spans multiple // source lines, the original line breaks are respected between -// expressions. Sets multiLine to true if the list spans multiple -// lines. +// expressions. // // TODO(gri) Consider rewriting this to be independent of []ast.Expr // so that we can use the algorithm for any kind of list // (e.g., pass list via a channel over which to range). -func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, multiLine *bool, next0 token.Pos) { +func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos) { if len(list) == 0 { return } - if mode&blankStart != 0 { - p.print(blank) - } - prev := p.posFor(prev0) next := p.posFor(next0) line := p.lineFor(list[0].Pos()) @@ -132,15 +123,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp // all list entries on a single line for i, x := range list { if i > 0 { - if mode&commaSep != 0 { - p.print(token.COMMA) - } - p.print(blank) + // use position of expression following the comma as + // comma position for correct comment placement + p.print(x.Pos(), token.COMMA, blank) } - p.expr0(x, depth, multiLine) - } - if mode&blankEnd != 0 { - p.print(blank) + p.expr0(x, depth) } return } @@ -160,7 +147,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp prevBreak := -1 // index of last expression that was followed by a linebreak if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) { ws = ignore - *multiLine = true prevBreak = 0 } @@ -213,20 +199,21 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp } if i > 0 { - switch { - case mode&commaSep != 0: - p.print(token.COMMA) - case mode&periodSep != 0: - p.print(token.PERIOD) + needsLinebreak := prevLine < line && prevLine > 0 && line > 0 + // use position of expression following the comma as + // comma position for correct comment placement, but + // only if the expression is on the same line + if !needsLinebreak { + p.print(x.Pos()) } - needsBlank := mode&periodSep == 0 // period-separated list elements don't need a blank - if prevLine < line && prevLine > 0 && line > 0 { + p.print(token.COMMA) + needsBlank := true + if needsLinebreak { // lines are broken using newlines so comments remain aligned // unless forceFF is set or there are multiple expressions on // the same line in which case formfeed is used if p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) { ws = ignore - *multiLine = true prevBreak = i needsBlank = false // we got a line break instead } @@ -240,11 +227,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp // we have a key:value expression that fits onto one line and // is in a list with more then one entry: use a column for the // key such that consecutive entries can align if possible - p.expr(pair.Key, multiLine) + p.expr(pair.Key) p.print(pair.Colon, token.COLON, vtab) - p.expr(pair.Value, multiLine) + p.expr(pair.Value) } else { - p.expr0(x, depth, multiLine) + p.expr0(x, depth) } } @@ -259,18 +246,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp return } - if mode&blankEnd != 0 { - p.print(blank) - } - if ws == ignore && mode&noIndent == 0 { // unindent if we indented p.print(unindent) } } -// Sets multiLine to true if the the parameter list spans multiple lines. -func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) { +func (p *printer) parameters(fields *ast.FieldList) { p.print(fields.Opening, token.LPAREN) if len(fields.List) > 0 { prevLine := p.lineFor(fields.Opening) @@ -287,14 +269,20 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) { parLineBeg = parLineEnd } // separating "," if needed + needsLinebreak := 0 < prevLine && prevLine < parLineBeg if i > 0 { + // use position of parameter following the comma as + // comma position for correct comma placement, but + // only if the next parameter is on the same line + if !needsLinebreak { + p.print(par.Pos()) + } p.print(token.COMMA) } // separator if needed (linebreak or blank) - if 0 < prevLine && prevLine < parLineBeg && p.linebreak(parLineBeg, 0, ws, true) { + if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) { // break line if the opening "(" or previous parameter ended on a different line ws = ignore - *multiLine = true } else if i > 0 { p.print(blank) } @@ -306,17 +294,17 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) { // again at the end (and still ws == indent). Thus, a subsequent indent // by a linebreak call after a type, or in the next multi-line identList // will do the right thing. - p.identList(par.Names, ws == indent, multiLine) + p.identList(par.Names, ws == indent) p.print(blank) } // parameter type - p.expr(par.Type, multiLine) + p.expr(par.Type) prevLine = parLineEnd } // if the closing ")" is on a separate line from the last parameter, // print an additional "," and line break if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing { - p.print(",") + p.print(token.COMMA) p.linebreak(closing, 0, ignore, true) } // unindent if we indented @@ -327,27 +315,26 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) { p.print(fields.Closing, token.RPAREN) } -// Sets multiLine to true if the signature spans multiple lines. -func (p *printer) signature(params, result *ast.FieldList, multiLine *bool) { - p.parameters(params, multiLine) +func (p *printer) signature(params, result *ast.FieldList) { + p.parameters(params) n := result.NumFields() if n > 0 { p.print(blank) if n == 1 && result.List[0].Names == nil { // single anonymous result; no ()'s - p.expr(result.List[0].Type, multiLine) + p.expr(result.List[0].Type) return } - p.parameters(result, multiLine) + p.parameters(result) } } func identListSize(list []*ast.Ident, maxSize int) (size int) { for i, x := range list { if i > 0 { - size += 2 // ", " + size += len(", ") } - size += len(x.Name) + size += utf8.RuneCountInString(x.Name) if size >= maxSize { break } @@ -374,7 +361,11 @@ func (p *printer) isOneLineFieldList(list []*ast.Field) bool { } func (p *printer) setLineComment(text string) { - p.setComment(&ast.CommentGroup{[]*ast.Comment{{token.NoPos, text}}}) + p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}}) +} + +func (p *printer) isMultiLine(n ast.Node) bool { + return p.lineFor(n.End())-p.lineFor(n.Pos()) > 1 } func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) { @@ -397,14 +388,15 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) f := list[0] for i, x := range f.Names { if i > 0 { + // no comments so no need for comma position p.print(token.COMMA, blank) } - p.expr(x, ignoreMultiLine) + p.expr(x) } if len(f.Names) > 0 { p.print(blank) } - p.expr(f.Type, ignoreMultiLine) + p.expr(f.Type) p.print(blank, rbrace, token.RBRACE) return } @@ -422,23 +414,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) if len(list) == 1 { sep = blank } - var ml bool + newSection := false for i, f := range list { if i > 0 { - p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml) + p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection) } - ml = false extraTabs := 0 p.setComment(f.Doc) if len(f.Names) > 0 { // named fields - p.identList(f.Names, false, &ml) + p.identList(f.Names, false) p.print(sep) - p.expr(f.Type, &ml) + p.expr(f.Type) extraTabs = 1 } else { // anonymous field - p.expr(f.Type, &ml) + p.expr(f.Type) extraTabs = 2 } if f.Tag != nil { @@ -446,7 +437,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) p.print(sep) } p.print(sep) - p.expr(f.Tag, &ml) + p.expr(f.Tag) extraTabs = 0 } if f.Comment != nil { @@ -455,6 +446,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) } p.setComment(f.Comment) } + newSection = p.isMultiLine(f) } if isIncomplete { if len(list) > 0 { @@ -466,22 +458,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) } else { // interface - var ml bool + newSection := false for i, f := range list { if i > 0 { - p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml) + p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection) } - ml = false p.setComment(f.Doc) if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp { // method - p.expr(f.Names[0], &ml) - p.signature(ftyp.Params, ftyp.Results, &ml) + p.expr(f.Names[0]) + p.signature(ftyp.Params, ftyp.Results) } else { // embedded interface - p.expr(f.Type, &ml) + p.expr(f.Type) } p.setComment(f.Comment) + newSection = p.isMultiLine(f) } if isIncomplete { if len(list) > 0 { @@ -622,15 +614,14 @@ func reduceDepth(depth int) int { // cutoff is 6 (always use spaces) in Normal mode // and 4 (never use spaces) in Compact mode. // -// Sets multiLine to true if the binary expression spans multiple lines. -func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiLine *bool) { +func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) { prec := x.Op.Precedence() if prec < prec1 { // parenthesis needed // Note: The parser inserts an ast.ParenExpr node; thus this case // can only occur if the AST is created in a different way. p.print(token.LPAREN) - p.expr0(x, reduceDepth(depth), multiLine) // parentheses undo one level of depth + p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth p.print(token.RPAREN) return } @@ -638,7 +629,7 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL printBlank := prec < cutoff ws := indent - p.expr1(x.X, prec, depth+diffPrec(x.X, prec), multiLine) + p.expr1(x.X, prec, depth+diffPrec(x.X, prec)) if printBlank { p.print(blank) } @@ -650,14 +641,13 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL // in the source if p.linebreak(yline, 1, ws, true) { ws = ignore - *multiLine = true printBlank = false // no blank after line break } } if printBlank { p.print(blank) } - p.expr1(x.Y, prec+1, depth+1, multiLine) + p.expr1(x.Y, prec+1, depth+1) if ws == ignore { p.print(unindent) } @@ -668,65 +658,7 @@ func isBinary(expr ast.Expr) bool { return ok } -// If the expression contains one or more selector expressions, splits it into -// two expressions at the rightmost period. Writes entire expr to suffix when -// selector isn't found. Rewrites AST nodes for calls, index expressions and -// type assertions, all of which may be found in selector chains, to make them -// parts of the chain. -func splitSelector(expr ast.Expr) (body, suffix ast.Expr) { - switch x := expr.(type) { - case *ast.SelectorExpr: - body, suffix = x.X, x.Sel - return - case *ast.CallExpr: - body, suffix = splitSelector(x.Fun) - if body != nil { - suffix = &ast.CallExpr{suffix, x.Lparen, x.Args, x.Ellipsis, x.Rparen} - return - } - case *ast.IndexExpr: - body, suffix = splitSelector(x.X) - if body != nil { - suffix = &ast.IndexExpr{suffix, x.Lbrack, x.Index, x.Rbrack} - return - } - case *ast.SliceExpr: - body, suffix = splitSelector(x.X) - if body != nil { - suffix = &ast.SliceExpr{suffix, x.Lbrack, x.Low, x.High, x.Rbrack} - return - } - case *ast.TypeAssertExpr: - body, suffix = splitSelector(x.X) - if body != nil { - suffix = &ast.TypeAssertExpr{suffix, x.Type} - return - } - } - suffix = expr - return -} - -// Convert an expression into an expression list split at the periods of -// selector expressions. -func selectorExprList(expr ast.Expr) (list []ast.Expr) { - // split expression - for expr != nil { - var suffix ast.Expr - expr, suffix = splitSelector(expr) - list = append(list, suffix) - } - - // reverse list - for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 { - list[i], list[j] = list[j], list[i] - } - - return -} - -// Sets multiLine to true if the expression spans multiple lines. -func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { +func (p *printer) expr1(expr ast.Expr, prec1, depth int) { p.print(expr.Pos()) switch x := expr.(type) { @@ -741,12 +673,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { p.internalError("depth < 1:", depth) depth = 1 } - p.binaryExpr(x, prec1, cutoff(x, depth), depth, multiLine) + p.binaryExpr(x, prec1, cutoff(x, depth), depth) case *ast.KeyValueExpr: - p.expr(x.Key, multiLine) + p.expr(x.Key) p.print(x.Colon, token.COLON, blank) - p.expr(x.Value, multiLine) + p.expr(x.Value) case *ast.StarExpr: const prec = token.UnaryPrec @@ -754,12 +686,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { // parenthesis needed p.print(token.LPAREN) p.print(token.MUL) - p.expr(x.X, multiLine) + p.expr(x.X) p.print(token.RPAREN) } else { // no parenthesis needed p.print(token.MUL) - p.expr(x.X, multiLine) + p.expr(x.X) } case *ast.UnaryExpr: @@ -767,7 +699,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { if prec < prec1 { // parenthesis needed p.print(token.LPAREN) - p.expr(x, multiLine) + p.expr(x) p.print(token.RPAREN) } else { // no parenthesis needed @@ -776,36 +708,41 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { // TODO(gri) Remove this code if it cannot be reached. p.print(blank) } - p.expr1(x.X, prec, depth, multiLine) + p.expr1(x.X, prec, depth) } case *ast.BasicLit: p.print(x) case *ast.FuncLit: - p.expr(x.Type, multiLine) - p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true, multiLine) + p.expr(x.Type) + p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true) case *ast.ParenExpr: if _, hasParens := x.X.(*ast.ParenExpr); hasParens { // don't print parentheses around an already parenthesized expression // TODO(gri) consider making this more general and incorporate precedence levels - p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth + p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth } else { p.print(token.LPAREN) - p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth + p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth p.print(x.Rparen, token.RPAREN) } case *ast.SelectorExpr: - parts := selectorExprList(expr) - p.exprList(token.NoPos, parts, depth, periodSep, multiLine, token.NoPos) + p.expr1(x.X, token.HighestPrec, depth) + p.print(token.PERIOD) + if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line { + p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent) + } else { + p.print(x.Sel.Pos(), x.Sel) + } case *ast.TypeAssertExpr: - p.expr1(x.X, token.HighestPrec, depth, multiLine) + p.expr1(x.X, token.HighestPrec, depth) p.print(token.PERIOD, token.LPAREN) if x.Type != nil { - p.expr(x.Type, multiLine) + p.expr(x.Type) } else { p.print(token.TYPE) } @@ -813,17 +750,17 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { case *ast.IndexExpr: // TODO(gri): should treat[] like parentheses and undo one level of depth - p.expr1(x.X, token.HighestPrec, 1, multiLine) + p.expr1(x.X, token.HighestPrec, 1) p.print(x.Lbrack, token.LBRACK) - p.expr0(x.Index, depth+1, multiLine) + p.expr0(x.Index, depth+1) p.print(x.Rbrack, token.RBRACK) case *ast.SliceExpr: // TODO(gri): should treat[] like parentheses and undo one level of depth - p.expr1(x.X, token.HighestPrec, 1, multiLine) + p.expr1(x.X, token.HighestPrec, 1) p.print(x.Lbrack, token.LBRACK) if x.Low != nil { - p.expr0(x.Low, depth+1, multiLine) + p.expr0(x.Low, depth+1) } // blanks around ":" if both sides exist and either side is a binary expression if depth <= 1 && x.Low != nil && x.High != nil && (isBinary(x.Low) || isBinary(x.High)) { @@ -832,7 +769,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { p.print(token.COLON) } if x.High != nil { - p.expr0(x.High, depth+1, multiLine) + p.expr0(x.High, depth+1) } p.print(x.Rbrack, token.RBRACK) @@ -840,21 +777,26 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { if len(x.Args) > 1 { depth++ } - p.expr1(x.Fun, token.HighestPrec, depth, multiLine) + p.expr1(x.Fun, token.HighestPrec, depth) p.print(x.Lparen, token.LPAREN) - p.exprList(x.Lparen, x.Args, depth, commaSep|commaTerm, multiLine, x.Rparen) if x.Ellipsis.IsValid() { + p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis) p.print(x.Ellipsis, token.ELLIPSIS) + if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) { + p.print(token.COMMA, formfeed) + } + } else { + p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen) } p.print(x.Rparen, token.RPAREN) case *ast.CompositeLit: // composite literal elements that are composite literals themselves may have the type omitted if x.Type != nil { - p.expr1(x.Type, token.HighestPrec, depth, multiLine) + p.expr1(x.Type, token.HighestPrec, depth) } p.print(x.Lbrace, token.LBRACE) - p.exprList(x.Lbrace, x.Elts, 1, commaSep|commaTerm, multiLine, x.Rbrace) + p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace) // do not insert extra line breaks because of comments before // the closing '}' as it might break the code if there is no // trailing ',' @@ -863,16 +805,16 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { case *ast.Ellipsis: p.print(token.ELLIPSIS) if x.Elt != nil { - p.expr(x.Elt, multiLine) + p.expr(x.Elt) } case *ast.ArrayType: p.print(token.LBRACK) if x.Len != nil { - p.expr(x.Len, multiLine) + p.expr(x.Len) } p.print(token.RBRACK) - p.expr(x.Elt, multiLine) + p.expr(x.Elt) case *ast.StructType: p.print(token.STRUCT) @@ -880,7 +822,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { case *ast.FuncType: p.print(token.FUNC) - p.signature(x.Params, x.Results, multiLine) + p.signature(x.Params, x.Results) case *ast.InterfaceType: p.print(token.INTERFACE) @@ -888,9 +830,9 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { case *ast.MapType: p.print(token.MAP, token.LBRACK) - p.expr(x.Key, multiLine) + p.expr(x.Key) p.print(token.RBRACK) - p.expr(x.Value, multiLine) + p.expr(x.Value) case *ast.ChanType: switch x.Dir { @@ -902,7 +844,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { p.print(token.CHAN, token.ARROW) } p.print(blank) - p.expr(x.Value, multiLine) + p.expr(x.Value) default: panic("unreachable") @@ -911,14 +853,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) { return } -func (p *printer) expr0(x ast.Expr, depth int, multiLine *bool) { - p.expr1(x, token.LowestPrec, depth, multiLine) +func (p *printer) expr0(x ast.Expr, depth int) { + p.expr1(x, token.LowestPrec, depth) } -// Sets multiLine to true if the expression spans multiple lines. -func (p *printer) expr(x ast.Expr, multiLine *bool) { +func (p *printer) expr(x ast.Expr) { const depth = 1 - p.expr1(x, token.LowestPrec, depth, multiLine) + p.expr1(x, token.LowestPrec, depth) } // ---------------------------------------------------------------------------- @@ -932,13 +873,13 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) { if _indent > 0 { p.print(indent) } - var multiLine bool + multiLine := false for i, s := range list { // _indent == 0 only for lists of switch/select case clauses; // in those cases each clause is a new section p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || _indent == 0 || multiLine) - multiLine = false - p.stmt(s, nextIsRBrace && i == len(list)-1, &multiLine) + p.stmt(s, nextIsRBrace && i == len(list)-1) + multiLine = p.isMultiLine(s) } if _indent > 0 { p.print(unindent) @@ -995,25 +936,25 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po if init == nil && post == nil { // no semicolons required if expr != nil { - p.expr(stripParens(expr), ignoreMultiLine) + p.expr(stripParens(expr)) needsBlank = true } } else { // all semicolons required // (they are not separators, print them explicitly) if init != nil { - p.stmt(init, false, ignoreMultiLine) + p.stmt(init, false) } p.print(token.SEMICOLON, blank) if expr != nil { - p.expr(stripParens(expr), ignoreMultiLine) + p.expr(stripParens(expr)) needsBlank = true } if isForStmt { p.print(token.SEMICOLON, blank) needsBlank = false if post != nil { - p.stmt(post, false, ignoreMultiLine) + p.stmt(post, false) needsBlank = true } } @@ -1023,8 +964,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po } } -// Sets multiLine to true if the statements spans multiple lines. -func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { +func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { p.print(stmt.Pos()) switch s := stmt.(type) { @@ -1032,7 +972,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { p.print("BadStmt") case *ast.DeclStmt: - p.decl(s.Decl, multiLine) + p.decl(s.Decl) case *ast.EmptyStmt: // nothing to do @@ -1042,7 +982,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { // is applied before the line break if there is no comment // between (see writeWhitespace) p.print(unindent) - p.expr(s.Label, multiLine) + p.expr(s.Label) p.print(s.Colon, token.COLON, indent) if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty { if !nextIsRBrace { @@ -1052,21 +992,21 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { } else { p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true) } - p.stmt(s.Stmt, nextIsRBrace, multiLine) + p.stmt(s.Stmt, nextIsRBrace) case *ast.ExprStmt: const depth = 1 - p.expr0(s.X, depth, multiLine) + p.expr0(s.X, depth) case *ast.SendStmt: const depth = 1 - p.expr0(s.Chan, depth, multiLine) + p.expr0(s.Chan, depth) p.print(blank, s.Arrow, token.ARROW, blank) - p.expr0(s.Value, depth, multiLine) + p.expr0(s.Value, depth) case *ast.IncDecStmt: const depth = 1 - p.expr0(s.X, depth+1, multiLine) + p.expr0(s.X, depth+1) p.print(s.TokPos, s.Tok) case *ast.AssignStmt: @@ -1074,56 +1014,55 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { if len(s.Lhs) > 1 && len(s.Rhs) > 1 { depth++ } - p.exprList(s.Pos(), s.Lhs, depth, commaSep, multiLine, s.TokPos) - p.print(blank, s.TokPos, s.Tok) - p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, multiLine, token.NoPos) + p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos) + p.print(blank, s.TokPos, s.Tok, blank) + p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos) case *ast.GoStmt: p.print(token.GO, blank) - p.expr(s.Call, multiLine) + p.expr(s.Call) case *ast.DeferStmt: p.print(token.DEFER, blank) - p.expr(s.Call, multiLine) + p.expr(s.Call) case *ast.ReturnStmt: p.print(token.RETURN) if s.Results != nil { - p.exprList(s.Pos(), s.Results, 1, blankStart|commaSep, multiLine, token.NoPos) + p.print(blank) + p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos) } case *ast.BranchStmt: p.print(s.Tok) if s.Label != nil { p.print(blank) - p.expr(s.Label, multiLine) + p.expr(s.Label) } case *ast.BlockStmt: p.block(s, 1) - *multiLine = true case *ast.IfStmt: p.print(token.IF) p.controlClause(false, s.Init, s.Cond, nil) p.block(s.Body, 1) - *multiLine = true if s.Else != nil { p.print(blank, token.ELSE, blank) switch s.Else.(type) { case *ast.BlockStmt, *ast.IfStmt: - p.stmt(s.Else, nextIsRBrace, ignoreMultiLine) + p.stmt(s.Else, nextIsRBrace) default: p.print(token.LBRACE, indent, formfeed) - p.stmt(s.Else, true, ignoreMultiLine) + p.stmt(s.Else, true) p.print(unindent, formfeed, token.RBRACE) } } case *ast.CaseClause: if s.List != nil { - p.print(token.CASE) - p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, multiLine, s.Colon) + p.print(token.CASE, blank) + p.exprList(s.Pos(), s.List, 1, 0, s.Colon) } else { p.print(token.DEFAULT) } @@ -1134,25 +1073,23 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { p.print(token.SWITCH) p.controlClause(false, s.Init, s.Tag, nil) p.block(s.Body, 0) - *multiLine = true case *ast.TypeSwitchStmt: p.print(token.SWITCH) if s.Init != nil { p.print(blank) - p.stmt(s.Init, false, ignoreMultiLine) + p.stmt(s.Init, false) p.print(token.SEMICOLON) } p.print(blank) - p.stmt(s.Assign, false, ignoreMultiLine) + p.stmt(s.Assign, false) p.print(blank) p.block(s.Body, 0) - *multiLine = true case *ast.CommClause: if s.Comm != nil { p.print(token.CASE, blank) - p.stmt(s.Comm, false, ignoreMultiLine) + p.stmt(s.Comm, false) } else { p.print(token.DEFAULT) } @@ -1167,27 +1104,26 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE) } else { p.block(body, 0) - *multiLine = true } case *ast.ForStmt: p.print(token.FOR) p.controlClause(true, s.Init, s.Cond, s.Post) p.block(s.Body, 1) - *multiLine = true case *ast.RangeStmt: p.print(token.FOR, blank) - p.expr(s.Key, multiLine) + p.expr(s.Key) if s.Value != nil { - p.print(token.COMMA, blank) - p.expr(s.Value, multiLine) + // use position of value following the comma as + // comma position for correct comment placement + p.print(s.Value.Pos(), token.COMMA, blank) + p.expr(s.Value) } p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank) - p.expr(stripParens(s.X), multiLine) + p.expr(stripParens(s.X)) p.print(blank) p.block(s.Body, 1) - *multiLine = true default: panic("unreachable") @@ -1264,20 +1200,20 @@ func keepTypeColumn(specs []ast.Spec) []bool { return m } -func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine *bool) { +func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) { p.setComment(s.Doc) - p.identList(s.Names, doIndent, multiLine) // always present + p.identList(s.Names, doIndent) // always present extraTabs := 3 if s.Type != nil || keepType { p.print(vtab) extraTabs-- } if s.Type != nil { - p.expr(s.Type, multiLine) + p.expr(s.Type) } if s.Values != nil { - p.print(vtab, token.ASSIGN) - p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos) + p.print(vtab, token.ASSIGN, blank) + p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos) extraTabs-- } if s.Comment != nil { @@ -1291,17 +1227,16 @@ func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine // The parameter n is the number of specs in the group. If doIndent is set, // multi-line identifier lists in the spec are indented when the first // linebreak is encountered. -// Sets multiLine to true if the spec spans multiple lines. // -func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) { +func (p *printer) spec(spec ast.Spec, n int, doIndent bool) { switch s := spec.(type) { case *ast.ImportSpec: p.setComment(s.Doc) if s.Name != nil { - p.expr(s.Name, multiLine) + p.expr(s.Name) p.print(blank) } - p.expr(s.Path, multiLine) + p.expr(s.Path) p.setComment(s.Comment) p.print(s.EndPos) @@ -1310,26 +1245,26 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) { p.internalError("expected n = 1; got", n) } p.setComment(s.Doc) - p.identList(s.Names, doIndent, multiLine) // always present + p.identList(s.Names, doIndent) // always present if s.Type != nil { p.print(blank) - p.expr(s.Type, multiLine) + p.expr(s.Type) } if s.Values != nil { - p.print(blank, token.ASSIGN) - p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos) + p.print(blank, token.ASSIGN, blank) + p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos) } p.setComment(s.Comment) case *ast.TypeSpec: p.setComment(s.Doc) - p.expr(s.Name, multiLine) + p.expr(s.Name) if n == 1 { p.print(blank) } else { p.print(vtab) } - p.expr(s.Type, multiLine) + p.expr(s.Type) p.setComment(s.Comment) default: @@ -1337,8 +1272,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) { } } -// Sets multiLine to true if the declaration spans multiple lines. -func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) { +func (p *printer) genDecl(d *ast.GenDecl) { p.setComment(d.Doc) p.print(d.Pos(), d.Tok, blank) @@ -1351,32 +1285,31 @@ func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) { // two or more grouped const/var declarations: // determine if the type column must be kept keepType := keepTypeColumn(d.Specs) - var ml bool + newSection := false for i, s := range d.Specs { if i > 0 { - p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml) + p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection) } - ml = false - p.valueSpec(s.(*ast.ValueSpec), keepType[i], false, &ml) + p.valueSpec(s.(*ast.ValueSpec), keepType[i], false) + newSection = p.isMultiLine(s) } } else { - var ml bool + newSection := false for i, s := range d.Specs { if i > 0 { - p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml) + p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection) } - ml = false - p.spec(s, n, false, &ml) + p.spec(s, n, false) + newSection = p.isMultiLine(s) } } p.print(unindent, formfeed) - *multiLine = true } p.print(d.Rparen, token.RPAREN) } else { // single declaration - p.spec(d.Specs[0], 1, true, multiLine) + p.spec(d.Specs[0], 1, true) } } @@ -1440,8 +1373,7 @@ func (p *printer) isOneLineFunc(b *ast.BlockStmt, headerSize int) bool { return headerSize+bodySize <= maxSize } -// Sets multiLine to true if the function body spans multiple lines. -func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLine *bool) { +func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool) { if b == nil { return } @@ -1458,7 +1390,7 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi if i > 0 { p.print(token.SEMICOLON, blank) } - p.stmt(s, i == len(b.List)-1, ignoreMultiLine) + p.stmt(s, i == len(b.List)-1) } p.print(blank) } @@ -1468,7 +1400,6 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi p.print(blank) p.block(b, 1) - *multiLine = true } // distance returns the column difference between from and to if both @@ -1482,28 +1413,26 @@ func (p *printer) distance(from0 token.Pos, to token.Position) int { return infinity } -// Sets multiLine to true if the declaration spans multiple lines. -func (p *printer) funcDecl(d *ast.FuncDecl, multiLine *bool) { +func (p *printer) funcDecl(d *ast.FuncDecl) { p.setComment(d.Doc) p.print(d.Pos(), token.FUNC, blank) if d.Recv != nil { - p.parameters(d.Recv, multiLine) // method: print receiver + p.parameters(d.Recv) // method: print receiver p.print(blank) } - p.expr(d.Name, multiLine) - p.signature(d.Type.Params, d.Type.Results, multiLine) - p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false, multiLine) + p.expr(d.Name) + p.signature(d.Type.Params, d.Type.Results) + p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false) } -// Sets multiLine to true if the declaration spans multiple lines. -func (p *printer) decl(decl ast.Decl, multiLine *bool) { +func (p *printer) decl(decl ast.Decl) { switch d := decl.(type) { case *ast.BadDecl: p.print(d.Pos(), "BadDecl") case *ast.GenDecl: - p.genDecl(d, multiLine) + p.genDecl(d) case *ast.FuncDecl: - p.funcDecl(d, multiLine) + p.funcDecl(d) default: panic("unreachable") } @@ -1526,7 +1455,7 @@ func declToken(decl ast.Decl) (tok token.Token) { func (p *printer) file(src *ast.File) { p.setComment(src.Doc) p.print(src.Pos(), token.PACKAGE, blank) - p.expr(src.Name, ignoreMultiLine) + p.expr(src.Name) if len(src.Decls) > 0 { tok := token.ILLEGAL @@ -1545,7 +1474,7 @@ func (p *printer) file(src *ast.File) { min = 2 } p.linebreak(p.lineFor(d.Pos()), min, ignore, false) - p.decl(d, ignoreMultiLine) + p.decl(d) } } diff --git a/libgo/go/go/printer/performance_test.go b/libgo/go/go/printer/performance_test.go index dbd942292b5..0c6a4e71f13 100644 --- a/libgo/go/go/printer/performance_test.go +++ b/libgo/go/go/printer/performance_test.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // This file implements a simple printer performance benchmark: -// gotest -bench=BenchmarkPrint +// go test -bench=BenchmarkPrint package printer diff --git a/libgo/go/go/printer/printer.go b/libgo/go/go/printer/printer.go index fe99e675eb0..a027d32da89 100644 --- a/libgo/go/go/printer/printer.go +++ b/libgo/go/go/printer/printer.go @@ -6,7 +6,6 @@ package printer import ( - "bytes" "fmt" "go/ast" "go/token" @@ -35,9 +34,6 @@ const ( unindent = whiteSpace('<') ) -// Use ignoreMultiLine if the multiLine information is not important. -var ignoreMultiLine = new(bool) - // A pmode value represents the current printer mode. type pmode int @@ -51,22 +47,22 @@ type printer struct { fset *token.FileSet // Current state - output bytes.Buffer // raw printer result + output []byte // raw printer result indent int // current indentation mode pmode // current printer mode impliedSemi bool // if set, a linebreak implies a semicolon lastTok token.Token // the last token printed (token.ILLEGAL if it's whitespace) wsbuf []whiteSpace // delayed white space - // The (possibly estimated) position in the generated output; - // in AST space (i.e., pos is set whenever a token position is - // known accurately, and updated dependending on what has been - // written). - pos token.Position - - // The value of pos immediately after the last item has been - // written using writeItem. - last token.Position + // Positions + // The out position differs from the pos position when the result + // formatting differs from the source formatting (in the amount of + // white space). If there's a difference and SourcePos is set in + // ConfigMode, //line comments are used in the output to restore + // original source positions for a reader. + pos token.Position // current position in AST (source) space + out token.Position // current position in output space + last token.Position // value of pos after calling writeString // The list of all source comments, in order of appearance. comments []*ast.CommentGroup // may be nil @@ -89,6 +85,8 @@ type printer struct { func (p *printer) init(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) { p.Config = *cfg p.fset = fset + p.pos = token.Position{Line: 1, Column: 1} + p.out = token.Position{Line: 1, Column: 1} p.wsbuf = make([]whiteSpace, 0, 16) // whitespace sequences are short p.nodeSizes = nodeSizes p.cachedPos = -1 @@ -151,41 +149,57 @@ func (p *printer) lineFor(pos token.Pos) int { return p.cachedLine } -// writeByte writes ch to p.output and updates p.pos. -func (p *printer) writeByte(ch byte) { - p.output.WriteByte(ch) - p.pos.Offset++ - p.pos.Column++ - - if ch == '\n' || ch == '\f' { - // write indentation - // use "hard" htabs - indentation columns - // must not be discarded by the tabwriter - const htabs = "\t\t\t\t\t\t\t\t" - j := p.indent - for j > len(htabs) { - p.output.WriteString(htabs) - j -= len(htabs) - } - p.output.WriteString(htabs[0:j]) +// atLineBegin emits a //line comment if necessary and prints indentation. +func (p *printer) atLineBegin(pos token.Position) { + // write a //line comment if necessary + if p.Config.Mode&SourcePos != 0 && pos.IsValid() && (p.out.Line != pos.Line || p.out.Filename != pos.Filename) { + p.output = append(p.output, tabwriter.Escape) // protect '\n' in //line from tabwriter interpretation + p.output = append(p.output, fmt.Sprintf("//line %s:%d\n", pos.Filename, pos.Line)...) + p.output = append(p.output, tabwriter.Escape) + // p.out must match the //line comment + p.out.Filename = pos.Filename + p.out.Line = pos.Line + } - // update p.pos - p.pos.Line++ - p.pos.Offset += p.indent - p.pos.Column = 1 + p.indent + // write indentation + // use "hard" htabs - indentation columns + // must not be discarded by the tabwriter + for i := 0; i < p.indent; i++ { + p.output = append(p.output, '\t') } + + // update positions + i := p.indent + p.pos.Offset += i + p.pos.Column += i + p.out.Column += i } -// writeByteN writes ch n times to p.output and updates p.pos. -func (p *printer) writeByteN(ch byte, n int) { - for n > 0 { - p.writeByte(ch) - n-- +// writeByte writes ch n times to p.output and updates p.pos. +func (p *printer) writeByte(ch byte, n int) { + if p.out.Column == 1 { + p.atLineBegin(p.pos) } + + for i := 0; i < n; i++ { + p.output = append(p.output, ch) + } + + // update positions + p.pos.Offset += n + if ch == '\n' || ch == '\f' { + p.pos.Line += n + p.out.Line += n + p.pos.Column = 1 + p.out.Column = 1 + return + } + p.pos.Column += n + p.out.Column += n } -// writeString writes the string s to p.output and updates p.pos. -// If isLit is set, s is escaped w/ tabwriter.Escape characters +// writeString writes the string s to p.output and updates p.pos, p.out, +// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters // to protect s from being interpreted by the tabwriter. // // Note: writeString is only used to write Go tokens, literals, and @@ -195,81 +209,85 @@ func (p *printer) writeByteN(ch byte, n int) { // avoids processing extra escape characters and reduces run time of the // printer benchmark by up to 10%. // -func (p *printer) writeString(s string, isLit bool) { +func (p *printer) writeString(pos token.Position, s string, isLit bool) { + if p.out.Column == 1 { + p.atLineBegin(pos) + } + + if pos.IsValid() { + // update p.pos (if pos is invalid, continue with existing p.pos) + // Note: Must do this after handling line beginnings because + // atLineBegin updates p.pos if there's indentation, but p.pos + // is the position of s. + p.pos = pos + // reset state if the file changed + // (used when printing merged ASTs of different files + // e.g., the result of ast.MergePackageFiles) + if p.last.IsValid() && p.last.Filename != pos.Filename { + p.indent = 0 + p.mode = 0 + p.wsbuf = p.wsbuf[0:0] + } + } + if isLit { // Protect s such that is passes through the tabwriter // unchanged. Note that valid Go programs cannot contain // tabwriter.Escape bytes since they do not appear in legal // UTF-8 sequences. - p.output.WriteByte(tabwriter.Escape) + p.output = append(p.output, tabwriter.Escape) } - p.output.WriteString(s) + if debug { + p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos! + } + p.output = append(p.output, s...) - // update p.pos + // update positions nlines := 0 - column := p.pos.Column + len(s) + var li int // index of last newline; valid if nlines > 0 for i := 0; i < len(s); i++ { + // Go tokens cannot contain '\f' - no need to look for it if s[i] == '\n' { nlines++ - column = len(s) - i + li = i } } p.pos.Offset += len(s) - p.pos.Line += nlines - p.pos.Column = column + if nlines > 0 { + p.pos.Line += nlines + p.out.Line += nlines + c := len(s) - li + p.pos.Column = c + p.out.Column = c + } else { + p.pos.Column += len(s) + p.out.Column += len(s) + } if isLit { - p.output.WriteByte(tabwriter.Escape) + p.output = append(p.output, tabwriter.Escape) } -} -// writeItem writes data at position pos. data is the text corresponding to -// a single lexical token, but may also be comment text. pos is the actual -// (or at least very accurately estimated) position of the data in the original -// source text. writeItem updates p.last to the position immediately following -// the data. -// -func (p *printer) writeItem(pos token.Position, data string, isLit bool) { - if pos.IsValid() { - // continue with previous position if we don't have a valid pos - if p.last.IsValid() && p.last.Filename != pos.Filename { - // the file has changed - reset state - // (used when printing merged ASTs of different files - // e.g., the result of ast.MergePackageFiles) - p.indent = 0 - p.mode = 0 - p.wsbuf = p.wsbuf[0:0] - } - p.pos = pos - } - if debug { - // do not update p.pos - use write0 - fmt.Fprintf(&p.output, "/*%s*/", pos) - } - p.writeString(data, isLit) p.last = p.pos } -const linePrefix = "//line " - // writeCommentPrefix writes the whitespace before a comment. // If there is any pending whitespace, it consumes as much of // it as is likely to help position the comment nicely. // pos is the comment position, next the position of the item // after all pending comments, prev is the previous comment in -// a group of comments (or nil), and isKeyword indicates if the -// next item is a keyword. +// a group of comments (or nil), and tok is the next token. // -func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, isKeyword bool) { - if p.output.Len() == 0 { +func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, tok token.Token) { + if len(p.output) == 0 { // the comment is the first item to be printed - don't write any whitespace return } if pos.IsValid() && pos.Filename != p.last.Filename { // comment in a different file - separate with newlines - p.writeByteN('\f', maxNewlines) + p.writeByte('\f', maxNewlines) return } @@ -309,45 +327,48 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *as // with a blank instead of a tab sep = ' ' } - p.writeByte(sep) + p.writeByte(sep, 1) } } else { // comment on a different line: // separate with at least one line break droppedLinebreak := false - if prev == nil { - // first comment of a comment group - j := 0 - for i, ch := range p.wsbuf { - switch ch { - case blank, vtab: - // ignore any horizontal whitespace before line breaks - p.wsbuf[i] = ignore + j := 0 + for i, ch := range p.wsbuf { + switch ch { + case blank, vtab: + // ignore any horizontal whitespace before line breaks + p.wsbuf[i] = ignore + continue + case indent: + // apply pending indentation + continue + case unindent: + // if this is not the last unindent, apply it + // as it is (likely) belonging to the last + // construct (e.g., a multi-line expression list) + // and is not part of closing a block + if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent { continue - case indent: - // apply pending indentation + } + // if the next token is not a closing }, apply the unindent + // if it appears that the comment is aligned with the + // token; otherwise assume the unindent is part of a + // closing block and stop (this scenario appears with + // comments before a case label where the comments + // apply to the next case instead of the current one) + if tok != token.RBRACE && pos.Column == next.Column { continue - case unindent: - // if the next token is a keyword, apply the outdent - // if it appears that the comment is aligned with the - // keyword; otherwise assume the outdent is part of a - // closing block and stop (this scenario appears with - // comments before a case label where the comments - // apply to the next case instead of the current one) - if isKeyword && pos.Column == next.Column { - continue - } - case newline, formfeed: - // TODO(gri): may want to keep formfeed info in some cases - p.wsbuf[i] = ignore - droppedLinebreak = true } - j = i - break + case newline, formfeed: + p.wsbuf[i] = ignore + droppedLinebreak = prev == nil // record only if first comment of a group } - p.writeWhitespace(j) + j = i + break } + p.writeWhitespace(j) // determine number of linebreaks before the comment n := 0 @@ -373,23 +394,17 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *as } if n > 0 { - // turn off indent if we're about to print a line directive - indent := p.indent - if strings.HasPrefix(comment.Text, linePrefix) { - p.indent = 0 - } // use formfeeds to break columns before a comment; // this is analogous to using formfeeds to separate // individual lines of /*-style comments - p.writeByteN('\f', nlimit(n)) - p.indent = indent // restore indent + p.writeByte('\f', nlimit(n)) } } } // Split comment text into lines // (using strings.Split(text, "\n") is significantly slower for -// this specific purpose, as measured with: gotest -bench=Print) +// this specific purpose, as measured with: go test -bench=Print) func split(text string) []string { // count lines (comment text never ends in a newline) n := 1 @@ -564,30 +579,33 @@ func stripCommonPrefix(lines []string) { func (p *printer) writeComment(comment *ast.Comment) { text := comment.Text + pos := p.posFor(comment.Pos()) - if strings.HasPrefix(text, linePrefix) { - pos := strings.TrimSpace(text[len(linePrefix):]) - i := strings.LastIndex(pos, ":") - if i >= 0 { - // The line directive we are about to print changed - // the Filename and Line number used by go/token - // as it was reading the input originally. - // In order to match the original input, we have to - // update our own idea of the file and line number - // accordingly, after printing the directive. - file := pos[:i] - line, _ := strconv.Atoi(pos[i+1:]) - defer func() { - p.pos.Filename = file - p.pos.Line = line - p.pos.Column = 1 - }() + const linePrefix = "//line " + if strings.HasPrefix(text, linePrefix) && (!pos.IsValid() || pos.Column == 1) { + // possibly a line directive + ldir := strings.TrimSpace(text[len(linePrefix):]) + if i := strings.LastIndex(ldir, ":"); i >= 0 { + if line, err := strconv.Atoi(ldir[i+1:]); err == nil && line > 0 { + // The line directive we are about to print changed + // the Filename and Line number used for subsequent + // tokens. We have to update our AST-space position + // accordingly and suspend indentation temporarily. + indent := p.indent + p.indent = 0 + defer func() { + p.pos.Filename = ldir[:i] + p.pos.Line = line + p.pos.Column = 1 + p.indent = indent + }() + } } } // shortcut common case of //-style comments if text[1] == '/' { - p.writeItem(p.posFor(comment.Pos()), text, true) + p.writeString(pos, text, true) return } @@ -598,14 +616,13 @@ func (p *printer) writeComment(comment *ast.Comment) { // write comment lines, separated by formfeed, // without a line break after the last line - pos := p.posFor(comment.Pos()) for i, line := range lines { if i > 0 { - p.writeByte('\f') + p.writeByte('\f', 1) pos = p.pos } if len(line) > 0 { - p.writeItem(pos, line, true) + p.writeString(pos, line, true) } } } @@ -643,7 +660,7 @@ func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, dropped // make sure we have a line break if needsLinebreak { - p.writeByte('\n') + p.writeByte('\n', 1) wroteNewline = true } @@ -660,7 +677,7 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro var last *ast.Comment for p.commentBefore(next) { for _, c := range p.comment.List { - p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok.IsKeyword()) + p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok) p.writeComment(c) last = c } @@ -668,10 +685,12 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro } if last != nil { - if last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line { - // the last comment is a /*-style comment and the next item - // follows on the same line: separate with an extra blank - p.writeByte(' ') + // if the last comment is a /*-style comment and the next item + // follows on the same line but is not a comma or a "closing" + // token, add an extra blank for separation + if last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line && tok != token.COMMA && + tok != token.RPAREN && tok != token.RBRACK && tok != token.RBRACE { + p.writeByte(' ', 1) } // ensure that there is a line break after a //-style comment, // before a closing '}' unless explicitly disabled, or at eof @@ -722,7 +741,7 @@ func (p *printer) writeWhitespace(n int) { } fallthrough default: - p.writeByte(byte(ch)) + p.writeByte(byte(ch), 1) } } @@ -886,12 +905,12 @@ func (p *printer) print(args ...interface{}) { if droppedFF { ch = '\f' // use formfeed since we dropped one before } - p.writeByteN(ch, n) + p.writeByte(ch, n) impliedSemi = false } } - p.writeItem(next, data, isLit) + p.writeString(next, data, isLit) p.impliedSemi = impliedSemi } } @@ -991,18 +1010,18 @@ func (p *printer) printNode(node interface{}) error { // format node switch n := node.(type) { case ast.Expr: - p.expr(n, ignoreMultiLine) + p.expr(n) case ast.Stmt: // A labeled statement will un-indent to position the // label. Set indent to 1 so we don't get indent "underflow". if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt { p.indent = 1 } - p.stmt(n, false, ignoreMultiLine) + p.stmt(n, false) case ast.Decl: - p.decl(n, ignoreMultiLine) + p.decl(n) case ast.Spec: - p.spec(n, 1, false, ignoreMultiLine) + p.spec(n, 1, false) case *ast.File: p.file(n) default: @@ -1027,7 +1046,7 @@ unsupported: type trimmer struct { output io.Writer state int - space bytes.Buffer + space []byte } // trimmer is implemented as a state machine. @@ -1038,6 +1057,11 @@ const ( inText // inside text ) +func (p *trimmer) resetSpace() { + p.state = inSpace + p.space = p.space[0:0] +} + // Design note: It is tempting to eliminate extra blanks occurring in // whitespace in this function as it could simplify some // of the blanks logic in the node printing functions. @@ -1062,36 +1086,33 @@ func (p *trimmer) Write(data []byte) (n int, err error) { case inSpace: switch b { case '\t', ' ': - p.space.WriteByte(b) // WriteByte returns no errors + p.space = append(p.space, b) case '\n', '\f': - p.space.Reset() // discard trailing space + p.resetSpace() // discard trailing space _, err = p.output.Write(aNewline) case tabwriter.Escape: - _, err = p.output.Write(p.space.Bytes()) + _, err = p.output.Write(p.space) p.state = inEscape m = n + 1 // +1: skip tabwriter.Escape default: - _, err = p.output.Write(p.space.Bytes()) + _, err = p.output.Write(p.space) p.state = inText m = n } case inEscape: if b == tabwriter.Escape { _, err = p.output.Write(data[m:n]) - p.state = inSpace - p.space.Reset() + p.resetSpace() } case inText: switch b { case '\t', ' ': _, err = p.output.Write(data[m:n]) - p.state = inSpace - p.space.Reset() - p.space.WriteByte(b) // WriteByte returns no errors + p.resetSpace() + p.space = append(p.space, b) case '\n', '\f': _, err = p.output.Write(data[m:n]) - p.state = inSpace - p.space.Reset() + p.resetSpace() _, err = p.output.Write(aNewline) case tabwriter.Escape: _, err = p.output.Write(data[m:n]) @@ -1110,8 +1131,7 @@ func (p *trimmer) Write(data []byte) (n int, err error) { switch p.state { case inEscape, inText: _, err = p.output.Write(data[m:n]) - p.state = inSpace - p.space.Reset() + p.resetSpace() } return @@ -1120,16 +1140,19 @@ func (p *trimmer) Write(data []byte) (n int, err error) { // ---------------------------------------------------------------------------- // Public interface -// General printing is controlled with these Config.Mode flags. +// A Mode value is a set of flags (or 0). They coontrol printing. +type Mode uint + const ( - RawFormat uint = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored + RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored TabIndent // use tabs for indentation independent of UseSpaces UseSpaces // use spaces instead of tabs for alignment + SourcePos // emit //line comments to preserve original source positions ) // A Config node controls the output of Fprint. type Config struct { - Mode uint // default: 0 + Mode Mode // default: 0 Tabwidth int // default: 8 } @@ -1170,7 +1193,7 @@ func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node interface{ } // write printer result via tabwriter/trimmer to output - if _, err = output.Write(p.output.Bytes()); err != nil { + if _, err = output.Write(p.output); err != nil { return } diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go index 9adf48cda61..497d671f240 100644 --- a/libgo/go/go/printer/printer_test.go +++ b/libgo/go/go/printer/printer_test.go @@ -67,6 +67,13 @@ func runcheck(t *testing.T, source, golden string, mode checkMode) { } res := buf.Bytes() + // formatted source must be valid + if _, err := parser.ParseFile(fset, "", res, 0); err != nil { + t.Error(err) + t.Logf("\n%s", res) + return + } + // update golden files if necessary if *update { if err := ioutil.WriteFile(golden, res, 0644); err != nil { @@ -133,7 +140,7 @@ type entry struct { mode checkMode } -// Use gotest -update to create/update the respective golden files. +// Use go test -update to create/update the respective golden files. var data = []entry{ {"empty.input", "empty.golden", 0}, {"comments.input", "comments.golden", 0}, @@ -147,15 +154,12 @@ var data = []entry{ } func TestFiles(t *testing.T) { - for i, e := range data { + for _, e := range data { source := filepath.Join(dataDir, e.source) golden := filepath.Join(dataDir, e.golden) check(t, source, golden, e.mode) // TODO(gri) check that golden is idempotent //check(t, golden, golden, e.mode) - if testing.Short() && i >= 3 { - break - } } } @@ -223,7 +227,8 @@ func TestBadNodes(t *testing.T) { } } -// Print and parse f with +// testComment verifies that f can be parsed again after printing it +// with its first comment set to comment at any possible source offset. func testComment(t *testing.T, f *ast.File, srclen int, comment *ast.Comment) { f.Comments[0].List[0] = comment var buf bytes.Buffer @@ -275,8 +280,133 @@ func fibo(n int) { t.Error("expected offset 1") // error in test } - testComment(t, f, len(src), &ast.Comment{pos, "//-style comment"}) - testComment(t, f, len(src), &ast.Comment{pos, "/*-style comment */"}) - testComment(t, f, len(src), &ast.Comment{pos, "/*-style \n comment */"}) - testComment(t, f, len(src), &ast.Comment{pos, "/*-style comment \n\n\n */"}) + testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "//-style comment"}) + testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment */"}) + testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style \n comment */"}) + testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment \n\n\n */"}) +} + +type visitor chan *ast.Ident + +func (v visitor) Visit(n ast.Node) (w ast.Visitor) { + if ident, ok := n.(*ast.Ident); ok { + v <- ident + } + return v +} + +// idents is an iterator that returns all idents in f via the result channel. +func idents(f *ast.File) <-chan *ast.Ident { + v := make(visitor) + go func() { + ast.Walk(v, f) + close(v) + }() + return v +} + +// identCount returns the number of identifiers found in f. +func identCount(f *ast.File) int { + n := 0 + for _ = range idents(f) { + n++ + } + return n +} + +// Verify that the SourcePos mode emits correct //line comments +// by testing that position information for matching identifiers +// is maintained. +func TestSourcePos(t *testing.T) { + const src = ` +package p +import ( "go/printer"; "math" ) +const pi = 3.14; var x = 0 +type t struct{ x, y, z int; u, v, w float32 } +func (t *t) foo(a, b, c int) int { + return a*t.x + b*t.y + + // two extra lines here + // ... + c*t.z +} +` + + // parse original + f1, err := parser.ParseFile(fset, "src", src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + // pretty-print original + var buf bytes.Buffer + err = (&Config{Mode: UseSpaces | SourcePos, Tabwidth: 8}).Fprint(&buf, fset, f1) + if err != nil { + t.Fatal(err) + } + + // parse pretty printed original + // (//line comments must be interpreted even w/o parser.ParseComments set) + f2, err := parser.ParseFile(fset, "", buf.Bytes(), 0) + if err != nil { + t.Fatalf("%s\n%s", err, buf.Bytes()) + } + + // At this point the position information of identifiers in f2 should + // match the position information of corresponding identifiers in f1. + + // number of identifiers must be > 0 (test should run) and must match + n1 := identCount(f1) + n2 := identCount(f2) + if n1 == 0 { + t.Fatal("got no idents") + } + if n2 != n1 { + t.Errorf("got %d idents; want %d", n2, n1) + } + + // verify that all identifiers have correct line information + i2range := idents(f2) + for i1 := range idents(f1) { + i2 := <-i2range + + if i2.Name != i1.Name { + t.Errorf("got ident %s; want %s", i2.Name, i1.Name) + } + + l1 := fset.Position(i1.Pos()).Line + l2 := fset.Position(i2.Pos()).Line + if l2 != l1 { + t.Errorf("got line %d; want %d for %s", l2, l1, i1.Name) + } + } + + if t.Failed() { + t.Logf("\n%s", buf.Bytes()) + } +} + +// TextX is a skeleton test that can be filled in for debugging one-off cases. +// Do not remove. +func TestX(t *testing.T) { + const src = ` +package p +func _() {} +` + // parse original + f, err := parser.ParseFile(fset, "src", src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + // pretty-print original + var buf bytes.Buffer + if err = (&Config{Mode: UseSpaces, Tabwidth: 8}).Fprint(&buf, fset, f); err != nil { + t.Fatal(err) + } + + // parse pretty printed original + if _, err := parser.ParseFile(fset, "", buf.Bytes(), 0); err != nil { + t.Fatalf("%s\n%s", err, buf.Bytes()) + } + } diff --git a/libgo/go/go/printer/testdata/comments.golden b/libgo/go/go/printer/testdata/comments.golden index d2ad9e3a2ff..d9aa2d82f7d 100644 --- a/libgo/go/go/printer/testdata/comments.golden +++ b/libgo/go/go/printer/testdata/comments.golden @@ -168,6 +168,91 @@ func typeswitch(x interface{}) { // this comment should not be indented } +// +// Indentation of comments after possibly indented multi-line constructs +// (test cases for issue 3147). +// + +func _() { + s := 1 + + 2 + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + + // should be indented like s + _ = 0 +} + +// Test case from issue 3147. +func f() { + templateText := "a" + // A + "b" + // B + "c" // C + + // should be aligned with f() + f() +} + +// Modified test case from issue 3147. +func f() { + templateText := "a" + // A + "b" + // B + "c" // C + + // may not be aligned with f() (source is not aligned) + f() +} + +// +// Test cases for alignment of lines in general comments. +// + func _() { /* freestanding comment aligned line @@ -404,17 +489,18 @@ func _() { */ } -// Some interesting interspersed comments +// Some interesting interspersed comments. +// See below for more common cases. func _( /* this */ x /* is */ /* an */ int) { } -func _( /* no params */ ) {} +func _( /* no params */) {} func _() { - f( /* no args */ ) + f( /* no args */) } -func ( /* comment1 */ T /* comment2 */ ) _() {} +func ( /* comment1 */ T /* comment2 */) _() {} func _() { /* one-line functions with comments are formatted as multi-line functions */ } @@ -425,11 +511,32 @@ func _() { } func _() { - _ = []int{0, 1 /* don't introduce a newline after this comment - was issue 1365 */ } + _ = []int{0, 1 /* don't introduce a newline after this comment - was issue 1365 */} } -// Comments immediately adjacent to punctuation (for which the go/printer -// may only have estimated position information) must remain after the punctuation. +// Test cases from issue 1542: +// Comments must not be placed before commas and cause invalid programs. +func _() { + var a = []int{1, 2 /*jasldf*/} + _ = a +} + +func _() { + var a = []int{1, 2}/*jasldf + */ + + _ = a +} + +func _() { + var a = []int{1, 2}// jasldf + + _ = a +} + +// Comments immediately adjacent to punctuation followed by a newline +// remain after the punctuation (looks better and permits alignment of +// comments). func _() { _ = T{ 1, // comment after comma @@ -459,6 +566,54 @@ func _() { } } +// If there is no newline following punctuation, commas move before the punctuation. +// This way, commas interspersed in lists stay with the respective expression. +func f(x /* comment */, y int, z int /* comment */, u, v, w int /* comment */) { + f(x /* comment */, y) + f(x, /* comment */ + y) + f( + x, /* comment */ + ) +} + +func g( + x int, /* comment */ +) { +} + +type _ struct { + a, b /* comment */, c int +} + +type _ struct { + a, b /* comment */, c int +} + +func _() { + for a /* comment */, b := range x { + } +} + +// Print line directives correctly. + +// The following is a legal line directive. +//line foo:1 +func _() { + _ = 0 + // The following is a legal line directive. It must not be indented: +//line foo:2 + _ = 1 + + // The following is not a legal line directive (it doesn't start in column 1): + //line foo:2 + _ = 2 + + // The following is not a legal line directive (negative line number): + //line foo:-3 + _ = 3 +} + // Line comments with tabs func _() { var finput *bufio.Reader // input file diff --git a/libgo/go/go/printer/testdata/comments.input b/libgo/go/go/printer/testdata/comments.input index 222e0a713d4..6084b3fe450 100644 --- a/libgo/go/go/printer/testdata/comments.input +++ b/libgo/go/go/printer/testdata/comments.input @@ -171,6 +171,91 @@ func typeswitch(x interface{}) { // this comment should not be indented } +// +// Indentation of comments after possibly indented multi-line constructs +// (test cases for issue 3147). +// + +func _() { + s := 1 + + 2 +// should be indented like s +} + +func _() { + s := 1 + + 2 // comment + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + +// should be indented like s +} + +func _() { + s := 1 + + 2 // comment + + // should be indented like s +} + +func _() { + s := 1 + + 2 // comment + + // should be indented like s + _ = 0 +} + +func _() { + s := 1 + + 2 + + // should be indented like s + _ = 0 +} + +// Test case from issue 3147. +func f() { + templateText := "a" + // A + "b" + // B + "c" // C + + // should be aligned with f() + f() +} + +// Modified test case from issue 3147. +func f() { + templateText := "a" + // A + "b" + // B + "c" // C + + // may not be aligned with f() (source is not aligned) + f() +} + +// +// Test cases for alignment of lines in general comments. +// + func _() { /* freestanding comment aligned line @@ -410,7 +495,8 @@ func _() { } -// Some interesting interspersed comments +// Some interesting interspersed comments. +// See below for more common cases. func _(/* this */x/* is *//* an */ int) { } @@ -432,9 +518,30 @@ func _() { _ = []int{0, 1 /* don't introduce a newline after this comment - was issue 1365 */} } +// Test cases from issue 1542: +// Comments must not be placed before commas and cause invalid programs. +func _() { + var a = []int{1, 2, /*jasldf*/ + } + _ = a +} + +func _() { + var a = []int{1, 2, /*jasldf + */ + } + _ = a +} -// Comments immediately adjacent to punctuation (for which the go/printer -// may only have estimated position information) must remain after the punctuation. +func _() { + var a = []int{1, 2, // jasldf + } + _ = a +} + +// Comments immediately adjacent to punctuation followed by a newline +// remain after the punctuation (looks better and permits alignment of +// comments). func _() { _ = T{ 1, // comment after comma @@ -466,6 +573,50 @@ func _() { } } +// If there is no newline following punctuation, commas move before the punctuation. +// This way, commas interspersed in lists stay with the respective expression. +func f(x/* comment */, y int, z int /* comment */, u, v, w int /* comment */) { + f(x /* comment */, y) + f(x /* comment */, + y) + f( + x /* comment */, + ) +} + +func g( + x int /* comment */, +) {} + +type _ struct { + a, b /* comment */, c int +} + +type _ struct { a, b /* comment */, c int } + +func _() { + for a /* comment */, b := range x { + } +} + +// Print line directives correctly. + +// The following is a legal line directive. +//line foo:1 +func _() { + _ = 0 +// The following is a legal line directive. It must not be indented: +//line foo:2 + _ = 1 + +// The following is not a legal line directive (it doesn't start in column 1): + //line foo:2 + _ = 2 + +// The following is not a legal line directive (negative line number): +//line foo:-3 + _ = 3 +} // Line comments with tabs func _() { diff --git a/libgo/go/go/printer/testdata/declarations.golden b/libgo/go/go/printer/testdata/declarations.golden index 928b8ce0a9f..7ed7cb61ae5 100644 --- a/libgo/go/go/printer/testdata/declarations.golden +++ b/libgo/go/go/printer/testdata/declarations.golden @@ -83,13 +83,13 @@ import ( // more import examples import ( "xxx" - "much longer name" // comment - "short name" // comment + "much_longer_name" // comment + "short_name" // comment ) import ( _ "xxx" - "much longer name" // comment + "much_longer_name" // comment ) import ( @@ -500,7 +500,7 @@ type _ struct { type _ struct { a, b, - c, d int // this line should be indented + c, d int // this line should be indented u, v, w, x float // this line should be indented p, q, r, s float // this line should be indented @@ -562,7 +562,7 @@ var a2, b2, var ( a3, b3, - c3, d3 int // this line should be indented + c3, d3 int // this line should be indented a4, b4, c4 int // this line should be indented ) diff --git a/libgo/go/go/printer/testdata/declarations.input b/libgo/go/go/printer/testdata/declarations.input index 68f90308a36..df8c2b167e1 100644 --- a/libgo/go/go/printer/testdata/declarations.input +++ b/libgo/go/go/printer/testdata/declarations.input @@ -84,13 +84,13 @@ import ( // more import examples import ( "xxx" - "much longer name" // comment - "short name" // comment + "much_longer_name" // comment + "short_name" // comment ) import ( _ "xxx" - "much longer name" // comment + "much_longer_name" // comment ) import ( diff --git a/libgo/go/go/printer/testdata/expressions.golden b/libgo/go/go/printer/testdata/expressions.golden index d0cf24ad6f6..45fa4d97a4a 100644 --- a/libgo/go/go/printer/testdata/expressions.golden +++ b/libgo/go/go/printer/testdata/expressions.golden @@ -545,7 +545,7 @@ func _() { // handle multiline argument list correctly _ = new(T). foo( - 1). + 1). foo(2) _ = new(T).foo( @@ -587,12 +587,12 @@ func _() { _ = new(T). Field. Array[3+ - 4]. + 4]. Table["foo"]. Blob.(*Type). Slices[1:4]. Method(1, 2, - 3). + 3). Thingy _ = a.b.c @@ -625,3 +625,25 @@ func f() { log.Fatal(err) } } + +// Handle multi-line argument lists ending in ... correctly. +// Was issue 3130. +func _() { + _ = append(s, a...) + _ = append( + s, a...) + _ = append(s, + a...) + _ = append( + s, + a...) + _ = append(s, a..., + ) + _ = append(s, + a..., + ) + _ = append( + s, + a..., + ) +} diff --git a/libgo/go/go/printer/testdata/expressions.input b/libgo/go/go/printer/testdata/expressions.input index d1131498352..f545c66057c 100644 --- a/libgo/go/go/printer/testdata/expressions.input +++ b/libgo/go/go/printer/testdata/expressions.input @@ -654,3 +654,25 @@ func f() { log.Fatal(err) } } + +// Handle multi-line argument lists ending in ... correctly. +// Was issue 3130. +func _() { + _ = append(s, a...) + _ = append( + s, a...) + _ = append(s, + a...) + _ = append( + s, + a...) + _ = append(s, a..., + ) + _ = append(s, + a..., + ) + _ = append( + s, + a..., + ) +} diff --git a/libgo/go/go/printer/testdata/expressions.raw b/libgo/go/go/printer/testdata/expressions.raw index d7819a3baad..87a4b00836d 100644 --- a/libgo/go/go/printer/testdata/expressions.raw +++ b/libgo/go/go/printer/testdata/expressions.raw @@ -545,7 +545,7 @@ func _() { // handle multiline argument list correctly _ = new(T). foo( - 1). + 1). foo(2) _ = new(T).foo( @@ -587,12 +587,12 @@ func _() { _ = new(T). Field. Array[3+ - 4]. + 4]. Table["foo"]. Blob.(*Type). Slices[1:4]. Method(1, 2, - 3). + 3). Thingy _ = a.b.c @@ -625,3 +625,25 @@ func f() { log.Fatal(err) } } + +// Handle multi-line argument lists ending in ... correctly. +// Was issue 3130. +func _() { + _ = append(s, a...) + _ = append( + s, a...) + _ = append(s, + a...) + _ = append( + s, + a...) + _ = append(s, a..., + ) + _ = append(s, + a..., + ) + _ = append( + s, + a..., + ) +} diff --git a/libgo/go/go/printer/testdata/parser.go b/libgo/go/go/printer/testdata/parser.go index c85297f5831..dba8bbd4351 100644 --- a/libgo/go/go/printer/testdata/parser.go +++ b/libgo/go/go/printer/testdata/parser.go @@ -52,7 +52,7 @@ type parser struct { // Non-syntactic parser control exprLev int // < 0: in control clause, >= 0: in expression - // Ordinary identifer scopes + // Ordinary identifier scopes pkgScope *ast.Scope // pkgScope.Outer == nil topScope *ast.Scope // top-most scope; may be pkgScope unresolved []*ast.Ident // unresolved identifiers diff --git a/libgo/go/go/printer/testdata/statements.golden b/libgo/go/go/printer/testdata/statements.golden index 90e1743557d..ffca21edba9 100644 --- a/libgo/go/go/printer/testdata/statements.golden +++ b/libgo/go/go/printer/testdata/statements.golden @@ -8,6 +8,82 @@ var expr bool func use(x interface{}) {} +// Formatting of multi-line return statements. +func _f() { + return + return x, y, z + return T{} + return T{1, 2, 3}, + x, y, z + return T{1, 2, 3}, + x, y, + z + return T{1, + 2, + 3} + return T{1, + 2, + 3, + } + return T{ + 1, + 2, + 3} + return T{ + 1, + 2, + 3, + } + return T{ + 1, + T{1, 2, 3}, + 3, + } + return T{ + 1, + T{1, + 2, 3}, + 3, + } + return T{ + 1, + T{1, + 2, + 3}, + 3, + } + return T{ + 1, + 2, + }, + nil + return T{ + 1, + 2, + }, + T{ + x: 3, + y: 4, + }, + nil + return x + y + + z + return func() {} + return func() { + _ = 0 + }, T{ + 1, 2, + } + return func() { + _ = 0 + } + return func() T { + return T{ + 1, 2, + } + } +} + // Formatting of if-statement headers. func _() { if true { diff --git a/libgo/go/go/printer/testdata/statements.input b/libgo/go/go/printer/testdata/statements.input index 86a753c5ad9..99945e9551a 100644 --- a/libgo/go/go/printer/testdata/statements.input +++ b/libgo/go/go/printer/testdata/statements.input @@ -8,6 +8,82 @@ var expr bool func use(x interface{}) {} +// Formatting of multi-line return statements. +func _f() { + return + return x, y, z + return T{} + return T{1, 2, 3}, + x, y, z + return T{1, 2, 3}, + x, y, + z + return T{1, + 2, + 3} + return T{1, + 2, + 3, + } + return T{ + 1, + 2, + 3} + return T{ + 1, + 2, + 3, + } + return T{ + 1, + T{1, 2, 3}, + 3, + } + return T{ + 1, + T{1, + 2, 3}, + 3, + } + return T{ + 1, + T{1, + 2, + 3}, + 3, + } + return T{ + 1, + 2, + }, + nil + return T{ + 1, + 2, + }, + T{ + x: 3, + y: 4, + }, + nil + return x + y + + z + return func() {} + return func() { + _ = 0 + }, T{ + 1, 2, + } + return func() { + _ = 0 + } + return func() T { + return T { + 1, 2, + } + } +} + // Formatting of if-statement headers. func _() { if true {} diff --git a/libgo/go/go/scanner/errors.go b/libgo/go/go/scanner/errors.go index cd9620b878b..8a75a96508e 100644 --- a/libgo/go/go/scanner/errors.go +++ b/libgo/go/go/scanner/errors.go @@ -11,44 +11,18 @@ import ( "sort" ) -// An implementation of an ErrorHandler may be provided to the Scanner. -// If a syntax error is encountered and a handler was installed, Error -// is called with a position and an error message. The position points -// to the beginning of the offending token. -// -type ErrorHandler interface { - Error(pos token.Position, msg string) -} - -// ErrorVector implements the ErrorHandler interface. It maintains a list -// of errors which can be retrieved with GetErrorList and GetError. The -// zero value for an ErrorVector is an empty ErrorVector ready to use. -// -// A common usage pattern is to embed an ErrorVector alongside a -// scanner in a data structure that uses the scanner. By passing a -// reference to an ErrorVector to the scanner's Init call, default -// error handling is obtained. -// -type ErrorVector struct { - errors []*Error -} - -// Reset resets an ErrorVector to no errors. -func (h *ErrorVector) Reset() { h.errors = h.errors[:0] } - -// ErrorCount returns the number of errors collected. -func (h *ErrorVector) ErrorCount() int { return len(h.errors) } - -// Within ErrorVector, an error is represented by an Error node. The -// position Pos, if valid, points to the beginning of the offending -// token, and the error condition is described by Msg. +// In an ErrorList, an error is represented by an *Error. +// The position Pos, if valid, points to the beginning of +// the offending token, and the error condition is described +// by Msg. // type Error struct { Pos token.Position Msg string } -func (e *Error) Error() string { +// Error implements the error interface. +func (e Error) Error() string { if e.Pos.Filename != "" || e.Pos.IsValid() { // don't print "<unknown position>" // TODO(gri) reconsider the semantics of Position.IsValid @@ -57,9 +31,19 @@ func (e *Error) Error() string { return e.Msg } -// An ErrorList is a (possibly sorted) list of Errors. +// ErrorList is a list of *Errors. +// The zero value for an ErrorList is an empty ErrorList ready to use. +// type ErrorList []*Error +// Add adds an Error with given position and error message to an ErrorList. +func (p *ErrorList) Add(pos token.Position, msg string) { + *p = append(*p, &Error{pos, msg}) +} + +// Reset resets an ErrorList to no errors. +func (p *ErrorList) Reset() { *p = (*p)[0:0] } + // ErrorList implements the sort Interface. func (p ErrorList) Len() int { return len(p) } func (p ErrorList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } @@ -84,72 +68,47 @@ func (p ErrorList) Less(i, j int) bool { return false } +// Sort sorts an ErrorList. *Error entries are sorted by position, +// other errors are sorted by error message, and before any *Error +// entry. +// +func (p ErrorList) Sort() { + sort.Sort(p) +} + +// RemoveMultiples sorts an ErrorList and removes all but the first error per line. +func (p *ErrorList) RemoveMultiples() { + sort.Sort(p) + var last token.Position // initial last.Line is != any legal error line + i := 0 + for _, e := range *p { + if e.Pos.Filename != last.Filename || e.Pos.Line != last.Line { + last = e.Pos + (*p)[i] = e + i++ + } + } + (*p) = (*p)[0:i] +} + +// An ErrorList implements the error interface. func (p ErrorList) Error() string { switch len(p) { case 0: - return "unspecified error" + return "no errors" case 1: return p[0].Error() } return fmt.Sprintf("%s (and %d more errors)", p[0], len(p)-1) } -// These constants control the construction of the ErrorList -// returned by GetErrors. -// -const ( - Raw = iota // leave error list unchanged - Sorted // sort error list by file, line, and column number - NoMultiples // sort error list and leave only the first error per line -) - -// GetErrorList returns the list of errors collected by an ErrorVector. -// The construction of the ErrorList returned is controlled by the mode -// parameter. If there are no errors, the result is nil. -// -func (h *ErrorVector) GetErrorList(mode int) ErrorList { - if len(h.errors) == 0 { - return nil - } - - list := make(ErrorList, len(h.errors)) - copy(list, h.errors) - - if mode >= Sorted { - sort.Sort(list) - } - - if mode >= NoMultiples { - var last token.Position // initial last.Line is != any legal error line - i := 0 - for _, e := range list { - if e.Pos.Filename != last.Filename || e.Pos.Line != last.Line { - last = e.Pos - list[i] = e - i++ - } - } - list = list[0:i] - } - - return list -} - -// GetError is like GetErrorList, but it returns an error instead -// so that a nil result can be assigned to an error variable and -// remains nil. -// -func (h *ErrorVector) GetError(mode int) error { - if len(h.errors) == 0 { +// Err returns an error equivalent to this error list. +// If the list is empty, Err returns nil. +func (p ErrorList) Err() error { + if len(p) == 0 { return nil } - - return h.GetErrorList(mode) -} - -// ErrorVector implements the ErrorHandler interface. -func (h *ErrorVector) Error(pos token.Position, msg string) { - h.errors = append(h.errors, &Error{pos, msg}) + return p } // PrintError is a utility function that prints a list of errors to w, diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go index 0aabfe34c41..2395363b0ec 100644 --- a/libgo/go/go/scanner/scanner.go +++ b/libgo/go/go/scanner/scanner.go @@ -2,21 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package scanner implements a scanner for Go source text. Takes a []byte as -// source which can then be tokenized through repeated calls to the Scan -// function. Typical use: -// -// var s scanner.Scanner -// fset := token.NewFileSet() // position information is relative to fset -// file := fset.AddFile(filename, fset.Base(), len(src)) // register file -// s.Init(file, src, nil /* no error handler */, 0) -// for { -// pos, tok, lit := s.Scan() -// if tok == token.EOF { -// break -// } -// // do something here with pos, tok, and lit -// } +// Package scanner implements a scanner for Go source text. +// It takes a []byte as source which can then be tokenized +// through repeated calls to the Scan method. // package scanner @@ -30,6 +18,13 @@ import ( "unicode/utf8" ) +// An ErrorHandler may be provided to Scanner.Init. If a syntax error is +// encountered and a handler was installed, the handler is called with a +// position and an error message. The position points to the beginning of +// the offending token. +// +type ErrorHandler func(pos token.Position, msg string) + // A Scanner holds the scanner's internal state while processing // a given text. It can be allocated as part of another data // structure but must be initialized via Init before use. @@ -103,7 +98,7 @@ const ( // line information which is already present is ignored. Init causes a // panic if the file size does not match the src size. // -// Calls to Scan will use the error handler err if they encounter a +// Calls to Scan will invoke the error handler err if they encounter a // syntax error and err is not nil. Also, for each error encountered, // the Scanner field ErrorCount is incremented by one. The mode parameter // determines how comments are handled. @@ -134,7 +129,7 @@ func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode func (s *Scanner) error(offs int, msg string) { if s.err != nil { - s.err.Error(s.file.Position(s.file.Pos(offs)), msg) + s.err(s.file.Position(s.file.Pos(offs)), msg) } s.ErrorCount++ } diff --git a/libgo/go/go/scanner/scanner_test.go b/libgo/go/go/scanner/scanner_test.go index e7f7cd1c1e9..06223e23bd8 100644 --- a/libgo/go/go/scanner/scanner_test.go +++ b/libgo/go/go/scanner/scanner_test.go @@ -186,14 +186,6 @@ var source = func() []byte { return src }() -type testErrorHandler struct { - t *testing.T -} - -func (h *testErrorHandler) Error(pos token.Position, msg string) { - h.t.Errorf("Error() called (msg = %s)", msg) -} - func newlineCount(s string) int { n := 0 for i := 0; i < len(s); i++ { @@ -226,9 +218,14 @@ func TestScan(t *testing.T) { src_linecount := newlineCount(string(source)) whitespace_linecount := newlineCount(whitespace) + // error handler + eh := func(_ token.Position, msg string) { + t.Errorf("error handler called (msg = %s)", msg) + } + // verify scan var s Scanner - s.Init(fset.AddFile("", fset.Base(), len(source)), source, &testErrorHandler{t}, ScanComments|dontInsertSemis) + s.Init(fset.AddFile("", fset.Base(), len(source)), source, eh, ScanComments|dontInsertSemis) index := 0 // epos is the expected position epos := token.Position{ @@ -569,36 +566,37 @@ func TestStdErrorHander(t *testing.T) { "//line File1:1\n" + "@ @ @" // original file, line 1 again - v := new(ErrorVector) + var list ErrorList + eh := func(pos token.Position, msg string) { list.Add(pos, msg) } + var s Scanner - s.Init(fset.AddFile("File1", fset.Base(), len(src)), []byte(src), v, dontInsertSemis) + s.Init(fset.AddFile("File1", fset.Base(), len(src)), []byte(src), eh, dontInsertSemis) for { if _, tok, _ := s.Scan(); tok == token.EOF { break } } - list := v.GetErrorList(Raw) + if len(list) != s.ErrorCount { + t.Errorf("found %d errors, expected %d", len(list), s.ErrorCount) + } + if len(list) != 9 { t.Errorf("found %d raw errors, expected 9", len(list)) PrintError(os.Stderr, list) } - list = v.GetErrorList(Sorted) + list.Sort() if len(list) != 9 { t.Errorf("found %d sorted errors, expected 9", len(list)) PrintError(os.Stderr, list) } - list = v.GetErrorList(NoMultiples) + list.RemoveMultiples() if len(list) != 4 { t.Errorf("found %d one-per-line errors, expected 4", len(list)) PrintError(os.Stderr, list) } - - if v.ErrorCount() != s.ErrorCount { - t.Errorf("found %d errors, expected %d", v.ErrorCount(), s.ErrorCount) - } } type errorCollector struct { @@ -607,16 +605,15 @@ type errorCollector struct { pos token.Position // last error position encountered } -func (h *errorCollector) Error(pos token.Position, msg string) { - h.cnt++ - h.msg = msg - h.pos = pos -} - func checkError(t *testing.T, src string, tok token.Token, pos int, err string) { var s Scanner var h errorCollector - s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), &h, ScanComments|dontInsertSemis) + eh := func(pos token.Position, msg string) { + h.cnt++ + h.msg = msg + h.pos = pos + } + s.Init(fset.AddFile("", fset.Base(), len(src)), []byte(src), eh, ScanComments|dontInsertSemis) _, tok0, _ := s.Scan() _, tok1, _ := s.Scan() if tok0 != tok { diff --git a/libgo/go/html/template/clone.go b/libgo/go/html/template/clone.go deleted file mode 100644 index d0d8ea46733..00000000000 --- a/libgo/go/html/template/clone.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package template - -import ( - "text/template/parse" -) - -// clone clones a template Node. -func clone(n parse.Node) parse.Node { - switch t := n.(type) { - case *parse.ActionNode: - return cloneAction(t) - case *parse.IfNode: - b := new(parse.IfNode) - copyBranch(&b.BranchNode, &t.BranchNode) - return b - case *parse.ListNode: - return cloneList(t) - case *parse.RangeNode: - b := new(parse.RangeNode) - copyBranch(&b.BranchNode, &t.BranchNode) - return b - case *parse.TemplateNode: - return cloneTemplate(t) - case *parse.TextNode: - return cloneText(t) - case *parse.WithNode: - b := new(parse.WithNode) - copyBranch(&b.BranchNode, &t.BranchNode) - return b - } - panic("cloning " + n.String() + " is unimplemented") -} - -// cloneAction returns a deep clone of n. -func cloneAction(n *parse.ActionNode) *parse.ActionNode { - // We use keyless fields because they won't compile if a field is added. - return &parse.ActionNode{n.NodeType, n.Line, clonePipe(n.Pipe)} -} - -// cloneList returns a deep clone of n. -func cloneList(n *parse.ListNode) *parse.ListNode { - if n == nil { - return nil - } - // We use keyless fields because they won't compile if a field is added. - c := parse.ListNode{n.NodeType, make([]parse.Node, len(n.Nodes))} - for i, child := range n.Nodes { - c.Nodes[i] = clone(child) - } - return &c -} - -// clonePipe returns a shallow clone of n. -// The escaper does not modify pipe descendants in place so there's no need to -// clone deeply. -func clonePipe(n *parse.PipeNode) *parse.PipeNode { - if n == nil { - return nil - } - // We use keyless fields because they won't compile if a field is added. - return &parse.PipeNode{n.NodeType, n.Line, n.Decl, n.Cmds} -} - -// cloneTemplate returns a deep clone of n. -func cloneTemplate(n *parse.TemplateNode) *parse.TemplateNode { - // We use keyless fields because they won't compile if a field is added. - return &parse.TemplateNode{n.NodeType, n.Line, n.Name, clonePipe(n.Pipe)} -} - -// cloneText clones the given node sharing its []byte. -func cloneText(n *parse.TextNode) *parse.TextNode { - // We use keyless fields because they won't compile if a field is added. - return &parse.TextNode{n.NodeType, n.Text} -} - -// copyBranch clones src into dst. -func copyBranch(dst, src *parse.BranchNode) { - // We use keyless fields because they won't compile if a field is added. - *dst = parse.BranchNode{ - src.NodeType, - src.Line, - clonePipe(src.Pipe), - cloneList(src.List), - cloneList(src.ElseList), - } -} diff --git a/libgo/go/html/template/clone_test.go b/libgo/go/html/template/clone_test.go index 39788173b99..c612775d4f0 100644 --- a/libgo/go/html/template/clone_test.go +++ b/libgo/go/html/template/clone_test.go @@ -7,86 +7,109 @@ package template import ( "bytes" "testing" + "text/template/parse" ) +func TestAddParseTree(t *testing.T) { + root := Must(New("root").Parse(`{{define "a"}} {{.}} {{template "b"}} {{.}} "></a>{{end}}`)) + tree, err := parse.Parse("t", `{{define "b"}}<a href="{{end}}`, "", "", nil, nil) + if err != nil { + t.Fatal(err) + } + added := Must(root.AddParseTree("b", tree["b"])) + b := new(bytes.Buffer) + err = added.ExecuteTemplate(b, "a", "1>0") + if err != nil { + t.Fatal(err) + } + if got, want := b.String(), ` 1>0 <a href=" 1%3e0 "></a>`; got != want { + t.Errorf("got %q want %q", got, want) + } +} + func TestClone(t *testing.T) { - tests := []struct { - input, want, wantClone string - }{ - { - `Hello, {{if true}}{{"<World>"}}{{end}}!`, - "Hello, <World>!", - "Hello, <World>!", - }, - { - `Hello, {{if false}}{{.X}}{{else}}{{"<World>"}}{{end}}!`, - "Hello, <World>!", - "Hello, <World>!", - }, - { - `Hello, {{with "<World>"}}{{.}}{{end}}!`, - "Hello, <World>!", - "Hello, <World>!", - }, - { - `{{range .}}<p>{{.}}</p>{{end}}`, - "<p>foo</p><p><bar></p><p>baz</p>", - "<p>foo</p><p><bar></p><p>baz</p>", - }, - { - `Hello, {{"<World>" | html}}!`, - "Hello, <World>!", - "Hello, <World>!", - }, - { - `Hello{{if 1}}, World{{else}}{{template "d"}}{{end}}!`, - "Hello, World!", - "Hello, World!", - }, + // The {{.}} will be executed with data "<i>*/" in different contexts. + // In the t0 template, it will be in a text context. + // In the t1 template, it will be in a URL context. + // In the t2 template, it will be in a JavaScript context. + // In the t3 template, it will be in a CSS context. + const tmpl = `{{define "a"}}{{template "lhs"}}{{.}}{{template "rhs"}}{{end}}` + b := new(bytes.Buffer) + + // Create an incomplete template t0. + t0 := Must(New("t0").Parse(tmpl)) + + // Clone t0 as t1. + t1 := Must(t0.Clone()) + Must(t1.Parse(`{{define "lhs"}} <a href=" {{end}}`)) + Must(t1.Parse(`{{define "rhs"}} "></a> {{end}}`)) + + // Execute t1. + b.Reset() + if err := t1.ExecuteTemplate(b, "a", "<i>*/"); err != nil { + t.Fatal(err) + } + if got, want := b.String(), ` <a href=" %3ci%3e*/ "></a> `; got != want { + t.Errorf("t1: got %q want %q", got, want) + } + + // Clone t0 as t2. + t2 := Must(t0.Clone()) + Must(t2.Parse(`{{define "lhs"}} <p onclick="javascript: {{end}}`)) + Must(t2.Parse(`{{define "rhs"}} "></p> {{end}}`)) + + // Execute t2. + b.Reset() + if err := t2.ExecuteTemplate(b, "a", "<i>*/"); err != nil { + t.Fatal(err) + } + if got, want := b.String(), ` <p onclick="javascript: "\u003ci\u003e*/" "></p> `; got != want { + t.Errorf("t2: got %q want %q", got, want) } - for _, test := range tests { - s, err := New("s").Parse(test.input) - if err != nil { - t.Errorf("input=%q: unexpected parse error %v", test.input, err) - } - - d, _ := New("d").Parse(test.input) - // Hack: just replace the root of the tree. - d.text.Root = cloneList(s.text.Root) - - if want, got := s.text.Root.String(), d.text.Root.String(); want != got { - t.Errorf("want %q, got %q", want, got) - } - - err = escapeTemplates(d, "d") - if err != nil { - t.Errorf("%q: failed to escape: %s", test.input, err) - continue - } - - if want, got := "s", s.Name(); want != got { - t.Errorf("want %q, got %q", want, got) - continue - } - if want, got := "d", d.Name(); want != got { - t.Errorf("want %q, got %q", want, got) - continue - } - - data := []string{"foo", "<bar>", "baz"} - - var b bytes.Buffer - d.Execute(&b, data) - if got := b.String(); got != test.wantClone { - t.Errorf("input=%q: want %q, got %q", test.input, test.wantClone, got) - } - - // Make sure escaping d did not affect s. - b.Reset() - s.text.Execute(&b, data) - if got := b.String(); got != test.want { - t.Errorf("input=%q: want %q, got %q", test.input, test.want, got) - } + // Clone t0 as t3, but do not execute t3 yet. + t3 := Must(t0.Clone()) + Must(t3.Parse(`{{define "lhs"}} <style> {{end}}`)) + Must(t3.Parse(`{{define "rhs"}} </style> {{end}}`)) + + // Complete t0. + Must(t0.Parse(`{{define "lhs"}} ( {{end}}`)) + Must(t0.Parse(`{{define "rhs"}} ) {{end}}`)) + + // Clone t0 as t4. Redefining the "lhs" template should fail. + t4 := Must(t0.Clone()) + if _, err := t4.Parse(`{{define "lhs"}} FAIL {{end}}`); err == nil { + t.Error(`redefine "lhs": got nil err want non-nil`) + } + + // Execute t0. + b.Reset() + if err := t0.ExecuteTemplate(b, "a", "<i>*/"); err != nil { + t.Fatal(err) + } + if got, want := b.String(), ` ( <i>*/ ) `; got != want { + t.Errorf("t0: got %q want %q", got, want) + } + + // Clone t0. This should fail, as t0 has already executed. + if _, err := t0.Clone(); err == nil { + t.Error(`t0.Clone(): got nil err want non-nil`) + } + + // Similarly, cloning sub-templates should fail. + if _, err := t0.Lookup("a").Clone(); err == nil { + t.Error(`t0.Lookup("a").Clone(): got nil err want non-nil`) + } + if _, err := t0.Lookup("lhs").Clone(); err == nil { + t.Error(`t0.Lookup("lhs").Clone(): got nil err want non-nil`) + } + + // Execute t3. + b.Reset() + if err := t3.ExecuteTemplate(b, "a", "<i>*/"); err != nil { + t.Fatal(err) + } + if got, want := b.String(), ` <style> ZgotmplZ </style> `; got != want { + t.Errorf("t3: got %q want %q", got, want) } } diff --git a/libgo/go/html/template/content.go b/libgo/go/html/template/content.go index 4de7ccde912..539664f9729 100644 --- a/libgo/go/html/template/content.go +++ b/libgo/go/html/template/content.go @@ -85,6 +85,22 @@ func indirect(a interface{}) interface{} { return v.Interface() } +var ( + errorType = reflect.TypeOf((*error)(nil)).Elem() + fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() +) + +// indirectToStringerOrError returns the value, after dereferencing as many times +// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer +// or error, +func indirectToStringerOrError(a interface{}) interface{} { + v := reflect.ValueOf(a) + for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v.Interface() +} + // stringify converts its arguments to a string and the type of the content. // All pointers are dereferenced, as in the text/template package. func stringify(args ...interface{}) (string, contentType) { @@ -107,7 +123,7 @@ func stringify(args ...interface{}) (string, contentType) { } } for i, arg := range args { - args[i] = indirect(arg) + args[i] = indirectToStringerOrError(arg) } return fmt.Sprint(args...), contentTypePlain } diff --git a/libgo/go/html/template/content_test.go b/libgo/go/html/template/content_test.go index c96a521a59c..3c32e5e89cf 100644 --- a/libgo/go/html/template/content_test.go +++ b/libgo/go/html/template/content_test.go @@ -6,6 +6,7 @@ package template import ( "bytes" + "fmt" "strings" "testing" ) @@ -219,3 +220,42 @@ func TestTypedContent(t *testing.T) { } } } + +// Test that we print using the String method. Was issue 3073. +type stringer struct { + v int +} + +func (s *stringer) String() string { + return fmt.Sprintf("string=%d", s.v) +} + +type errorer struct { + v int +} + +func (s *errorer) Error() string { + return fmt.Sprintf("error=%d", s.v) +} + +func TestStringer(t *testing.T) { + s := &stringer{3} + b := new(bytes.Buffer) + tmpl := Must(New("x").Parse("{{.}}")) + if err := tmpl.Execute(b, s); err != nil { + t.Fatal(err) + } + var expect = "string=3" + if b.String() != expect { + t.Errorf("expected %q got %q", expect, b.String()) + } + e := &errorer{7} + b.Reset() + if err := tmpl.Execute(b, e); err != nil { + t.Fatal(err) + } + expect = "error=7" + if b.String() != expect { + t.Errorf("expected %q got %q", expect, b.String()) + } +} diff --git a/libgo/go/html/template/doc.go b/libgo/go/html/template/doc.go index 77a9bf2e225..3699ea1a91c 100644 --- a/libgo/go/html/template/doc.go +++ b/libgo/go/html/template/doc.go @@ -3,21 +3,25 @@ // license that can be found in the LICENSE file. /* -Package template (html/template) is a specialization of package text/template -that automates the construction of HTML output that is safe against code -injection. +Package template (html/template) implements data-driven templates for +generating HTML output safe against code injection. It provides the +same interface as package text/template and should be used instead of +text/template whenever the output is HTML. +The documentation here focuses on the security features of the package. +For information about how to program the templates themselves, see the +documentation for text/template. Introduction -This package wraps package template so you can use the standard template API -to parse and execute templates. +This package wraps package text/template so you can share its template API +to parse and execute HTML templates safely. - set, err := new(template.Set).Parse(...) + tmpl, err := template.New("name").Parse(...) // Error checking elided - err = set.Execute(out, "Foo", data) + err = tmpl.Execute(out, data) -If successful, set will now be injection-safe. Otherwise, err is an error +If successful, tmpl will now be injection-safe. Otherwise, err is an error defined in the docs for ErrorCode. HTML templates treat data values as plain text which should be encoded so they @@ -25,7 +29,8 @@ can be safely embedded in an HTML document. The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts. The security model used by this package assumes that template authors are -trusted, while Execute's data parameter is not. More details are provided below. +trusted, while text/template Execute's data parameter is not. More details are +provided below. Example @@ -38,7 +43,7 @@ produces Hello, <script>alert('you have been pwned')</script>! -but with contextual autoescaping, +but the contextual autoescaping in html/template import "html/template" ... @@ -167,18 +172,18 @@ This package assumes that template authors are trusted, that Execute's data parameter is not, and seeks to preserve the properties below in the face of untrusted data: -Structure Preservation Property +Structure Preservation Property: "... when a template author writes an HTML tag in a safe templating language, the browser will interpret the corresponding portion of the output as a tag regardless of the values of untrusted data, and similarly for other structures such as attribute boundaries and JS and CSS string boundaries." -Code Effect Property +Code Effect Property: "... only code specified by the template author should run as a result of injecting the template output into a page and all code specified by the template author should run as a result of the same." -Least Surprise Property +Least Surprise Property: "A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who knows that contextual autoescaping happens should be able to look at a {{.}} and correctly infer what sanitization happens." diff --git a/libgo/go/html/template/escape.go b/libgo/go/html/template/escape.go index c6f723ae4a4..a058e20d7b3 100644 --- a/libgo/go/html/template/escape.go +++ b/libgo/go/html/template/escape.go @@ -46,30 +46,30 @@ func escapeTemplates(tmpl *Template, names ...string) error { // funcMap maps command names to functions that render their inputs safe. var funcMap = template.FuncMap{ - "exp_template_html_attrescaper": attrEscaper, - "exp_template_html_commentescaper": commentEscaper, - "exp_template_html_cssescaper": cssEscaper, - "exp_template_html_cssvaluefilter": cssValueFilter, - "exp_template_html_htmlnamefilter": htmlNameFilter, - "exp_template_html_htmlescaper": htmlEscaper, - "exp_template_html_jsregexpescaper": jsRegexpEscaper, - "exp_template_html_jsstrescaper": jsStrEscaper, - "exp_template_html_jsvalescaper": jsValEscaper, - "exp_template_html_nospaceescaper": htmlNospaceEscaper, - "exp_template_html_rcdataescaper": rcdataEscaper, - "exp_template_html_urlescaper": urlEscaper, - "exp_template_html_urlfilter": urlFilter, - "exp_template_html_urlnormalizer": urlNormalizer, + "html_template_attrescaper": attrEscaper, + "html_template_commentescaper": commentEscaper, + "html_template_cssescaper": cssEscaper, + "html_template_cssvaluefilter": cssValueFilter, + "html_template_htmlnamefilter": htmlNameFilter, + "html_template_htmlescaper": htmlEscaper, + "html_template_jsregexpescaper": jsRegexpEscaper, + "html_template_jsstrescaper": jsStrEscaper, + "html_template_jsvalescaper": jsValEscaper, + "html_template_nospaceescaper": htmlNospaceEscaper, + "html_template_rcdataescaper": rcdataEscaper, + "html_template_urlescaper": urlEscaper, + "html_template_urlfilter": urlFilter, + "html_template_urlnormalizer": urlNormalizer, } // equivEscapers matches contextual escapers to equivalent template builtins. var equivEscapers = map[string]string{ - "exp_template_html_attrescaper": "html", - "exp_template_html_htmlescaper": "html", - "exp_template_html_nospaceescaper": "html", - "exp_template_html_rcdataescaper": "html", - "exp_template_html_urlescaper": "urlquery", - "exp_template_html_urlnormalizer": "urlquery", + "html_template_attrescaper": "html", + "html_template_htmlescaper": "html", + "html_template_nospaceescaper": "html", + "html_template_rcdataescaper": "html", + "html_template_urlescaper": "urlquery", + "html_template_urlnormalizer": "urlquery", } // escaper collects type inferences about templates and changes needed to make @@ -147,17 +147,17 @@ func (e *escaper) escapeAction(c context, n *parse.ActionNode) context { case stateURL, stateCSSDqStr, stateCSSSqStr, stateCSSDqURL, stateCSSSqURL, stateCSSURL: switch c.urlPart { case urlPartNone: - s = append(s, "exp_template_html_urlfilter") + s = append(s, "html_template_urlfilter") fallthrough case urlPartPreQuery: switch c.state { case stateCSSDqStr, stateCSSSqStr: - s = append(s, "exp_template_html_cssescaper") + s = append(s, "html_template_cssescaper") default: - s = append(s, "exp_template_html_urlnormalizer") + s = append(s, "html_template_urlnormalizer") } case urlPartQueryOrFrag: - s = append(s, "exp_template_html_urlescaper") + s = append(s, "html_template_urlescaper") case urlPartUnknown: return context{ state: stateError, @@ -167,27 +167,27 @@ func (e *escaper) escapeAction(c context, n *parse.ActionNode) context { panic(c.urlPart.String()) } case stateJS: - s = append(s, "exp_template_html_jsvalescaper") + s = append(s, "html_template_jsvalescaper") // A slash after a value starts a div operator. c.jsCtx = jsCtxDivOp case stateJSDqStr, stateJSSqStr: - s = append(s, "exp_template_html_jsstrescaper") + s = append(s, "html_template_jsstrescaper") case stateJSRegexp: - s = append(s, "exp_template_html_jsregexpescaper") + s = append(s, "html_template_jsregexpescaper") case stateCSS: - s = append(s, "exp_template_html_cssvaluefilter") + s = append(s, "html_template_cssvaluefilter") case stateText: - s = append(s, "exp_template_html_htmlescaper") + s = append(s, "html_template_htmlescaper") case stateRCDATA: - s = append(s, "exp_template_html_rcdataescaper") + s = append(s, "html_template_rcdataescaper") case stateAttr: // Handled below in delim check. case stateAttrName, stateTag: c.state = stateAttrName - s = append(s, "exp_template_html_htmlnamefilter") + s = append(s, "html_template_htmlnamefilter") default: if isComment(c.state) { - s = append(s, "exp_template_html_commentescaper") + s = append(s, "html_template_commentescaper") } else { panic("unexpected state " + c.state.String()) } @@ -196,9 +196,9 @@ func (e *escaper) escapeAction(c context, n *parse.ActionNode) context { case delimNone: // No extra-escaping needed for raw text content. case delimSpaceOrTagEnd: - s = append(s, "exp_template_html_nospaceescaper") + s = append(s, "html_template_nospaceescaper") default: - s = append(s, "exp_template_html_attrescaper") + s = append(s, "html_template_attrescaper") } e.editActionNode(n, s) return c @@ -260,22 +260,22 @@ func ensurePipelineContains(p *parse.PipeNode, s []string) { // redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x) // for all x. var redundantFuncs = map[string]map[string]bool{ - "exp_template_html_commentescaper": { - "exp_template_html_attrescaper": true, - "exp_template_html_nospaceescaper": true, - "exp_template_html_htmlescaper": true, + "html_template_commentescaper": { + "html_template_attrescaper": true, + "html_template_nospaceescaper": true, + "html_template_htmlescaper": true, }, - "exp_template_html_cssescaper": { - "exp_template_html_attrescaper": true, + "html_template_cssescaper": { + "html_template_attrescaper": true, }, - "exp_template_html_jsregexpescaper": { - "exp_template_html_attrescaper": true, + "html_template_jsregexpescaper": { + "html_template_attrescaper": true, }, - "exp_template_html_jsstrescaper": { - "exp_template_html_attrescaper": true, + "html_template_jsstrescaper": { + "html_template_attrescaper": true, }, - "exp_template_html_urlescaper": { - "exp_template_html_urlnormalizer": true, + "html_template_urlescaper": { + "html_template_urlnormalizer": true, }, } @@ -505,7 +505,7 @@ func (e *escaper) escapeTree(c context, name string, line int) (context, string) dt := e.template(dname) if dt == nil { dt = template.New(dname) - dt.Tree = &parse.Tree{Name: dname, Root: cloneList(t.Root)} + dt.Tree = &parse.Tree{Name: dname, Root: t.Root.CopyList()} e.derived[dname] = dt } t = dt @@ -593,7 +593,7 @@ func (e *escaper) escapeText(c context, n *parse.TextNode) context { } } for j := i; j < end; j++ { - if s[j] == '<' && !bytes.HasPrefix(s[j:], doctypeBytes) { + if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) { b.Write(s[written:j]) b.WriteString("<") written = j + 1 diff --git a/libgo/go/html/template/escape_test.go b/libgo/go/html/template/escape_test.go index 70cada3f50b..2bbb1b1bc94 100644 --- a/libgo/go/html/template/escape_test.go +++ b/libgo/go/html/template/escape_test.go @@ -223,14 +223,14 @@ func TestEscape(t *testing.T) { `<button onclick='alert("\x3cHello\x3e")'>`, }, { - "badMarshaller", + "badMarshaler", `<button onclick='alert(1/{{.B}}in numbers)'>`, `<button onclick='alert(1/ /* json: error calling MarshalJSON for type *template.badMarshaler: invalid character 'f' looking for beginning of object key string */null in numbers)'>`, }, { - "jsMarshaller", + "jsMarshaler", `<button onclick='alert({{.M}})'>`, - `<button onclick='alert({"<foo>":"O'Reilly"})'>`, + `<button onclick='alert({"\u003cfoo\u003e":"O'Reilly"})'>`, }, { "jsStrNotUnderEscaped", @@ -432,6 +432,11 @@ func TestEscape(t *testing.T) { "<!DOCTYPE html>Hello, World!", }, { + "HTML doctype not case-insensitive", + "<!doCtYPE htMl>Hello, World!", + "<!doCtYPE htMl>Hello, World!", + }, + { "No doctype injection", `<!{{"DOCTYPE"}}`, "<!DOCTYPE", diff --git a/libgo/go/html/template/html.go b/libgo/go/html/template/html.go index 7b77d6531ab..36c88e23e6e 100644 --- a/libgo/go/html/template/html.go +++ b/libgo/go/html/template/html.go @@ -134,7 +134,7 @@ var htmlNospaceNormReplacementTable = []string{ '`': "`", } -// htmlReplacer returns s with runes replaced acccording to replacementTable +// htmlReplacer returns s with runes replaced according to replacementTable // and when badRunes is true, certain bad runes are allowed through unescaped. func htmlReplacer(s string, replacementTable []string, badRunes bool) string { written, b := 0, new(bytes.Buffer) diff --git a/libgo/go/html/template/template.go b/libgo/go/html/template/template.go index 9ffe41413a8..b0bae7a54fb 100644 --- a/libgo/go/html/template/template.go +++ b/libgo/go/html/template/template.go @@ -50,7 +50,7 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { // ExecuteTemplate applies the template associated with t that has the given // name to the specified data object and writes the output to wr. func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { - tmpl, err := t.lookupAndEscapeTemplate(wr, name) + tmpl, err := t.lookupAndEscapeTemplate(name) if err != nil { return err } @@ -60,7 +60,7 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) // lookupAndEscapeTemplate guarantees that the template with the given name // is escaped, or returns an error if it cannot be. It returns the named // template. -func (t *Template) lookupAndEscapeTemplate(wr io.Writer, name string) (tmpl *Template, err error) { +func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) { t.nameSpace.mu.Lock() defer t.nameSpace.mu.Unlock() tmpl = t.set[name] @@ -106,14 +106,71 @@ func (t *Template) Parse(src string) (*Template, error) { return t, nil } -// AddParseTree is unimplemented. -func (t *Template) AddParseTree(name string, tree *parse.Tree) error { - return fmt.Errorf("html/template: AddParseTree unimplemented") +// AddParseTree creates a new template with the name and parse tree +// and associates it with t. +// +// It returns an error if t has already been executed. +func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { + t.nameSpace.mu.Lock() + defer t.nameSpace.mu.Unlock() + if t.escaped { + return nil, fmt.Errorf("html/template: cannot AddParseTree to %q after it has executed", t.Name()) + } + text, err := t.text.AddParseTree(name, tree) + if err != nil { + return nil, err + } + ret := &Template{ + false, + text, + t.nameSpace, + } + t.set[name] = ret + return ret, nil } -// Clone is unimplemented. -func (t *Template) Clone(name string) error { - return fmt.Errorf("html/template: Clone unimplemented") +// Clone returns a duplicate of the template, including all associated +// templates. The actual representation is not copied, but the name space of +// associated templates is, so further calls to Parse in the copy will add +// templates to the copy but not to the original. Clone can be used to prepare +// common templates and use them with variant definitions for other templates +// by adding the variants after the clone is made. +// +// It returns an error if t has already been executed. +func (t *Template) Clone() (*Template, error) { + t.nameSpace.mu.Lock() + defer t.nameSpace.mu.Unlock() + if t.escaped { + return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name()) + } + textClone, err := t.text.Clone() + if err != nil { + return nil, err + } + ret := &Template{ + false, + textClone, + &nameSpace{ + set: make(map[string]*Template), + }, + } + for _, x := range textClone.Templates() { + name := x.Name() + src := t.set[name] + if src == nil || src.escaped { + return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name()) + } + x.Tree = &parse.Tree{ + Name: x.Tree.Name, + Root: x.Tree.Root.CopyList(), + } + ret.set[name] = &Template{ + false, + x, + ret.nameSpace, + } + } + return ret, nil } // New allocates a new HTML template with the given name. diff --git a/libgo/go/image/decode_example_test.go b/libgo/go/image/decode_example_test.go new file mode 100644 index 00000000000..aa5a841c0a5 --- /dev/null +++ b/libgo/go/image/decode_example_test.go @@ -0,0 +1,79 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This example demonstrates decoding a JPEG image and examining its pixels. +package image_test + +import ( + "fmt" + "image" + "log" + "os" + + // Package image/jpeg is not used explicitly in the code below, + // but is imported for its initialization side-effect, which allows + // image.Decode to understand JPEG formatted images. Uncomment these + // two lines to also understand GIF and PNG images: + // _ "image/gif" + // _ "image/png" + _ "image/jpeg" +) + +func Example() { + // Open the file. + file, err := os.Open("testdata/video-001.jpeg") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + // Decode the image. + m, _, err := image.Decode(file) + if err != nil { + log.Fatal(err) + } + bounds := m.Bounds() + + // Calculate a 16-bin histogram for m's red, green, blue and alpha components. + // + // An image's bounds do not necessarily start at (0, 0), so the two loops start + // at bounds.Min.Y and bounds.Min.X. Looping over Y first and X second is more + // likely to result in better memory access patterns than X first and Y second. + var histogram [16][4]int + for y := bounds.Min.Y; y < bounds.Max.Y; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r, g, b, a := m.At(x, y).RGBA() + // A color's RGBA method returns values in the range [0, 65535]. + // Shifting by 12 reduces this to the range [0, 15]. + histogram[r>>12][0]++ + histogram[g>>12][1]++ + histogram[b>>12][2]++ + histogram[a>>12][3]++ + } + } + + // Print the results. + fmt.Printf("%-14s %6s %6s %6s %6s\n", "bin", "red", "green", "blue", "alpha") + for i, x := range histogram { + fmt.Printf("0x%04x-0x%04x: %6d %6d %6d %6d\n", i<<12, (i+1)<<12-1, x[0], x[1], x[2], x[3]) + } + // Output: + // bin red green blue alpha + // 0x0000-0x0fff: 471 819 7596 0 + // 0x1000-0x1fff: 576 2892 726 0 + // 0x2000-0x2fff: 1038 2330 943 0 + // 0x3000-0x3fff: 883 2321 1014 0 + // 0x4000-0x4fff: 501 1295 525 0 + // 0x5000-0x5fff: 302 962 242 0 + // 0x6000-0x6fff: 219 358 150 0 + // 0x7000-0x7fff: 352 281 192 0 + // 0x8000-0x8fff: 3688 216 246 0 + // 0x9000-0x9fff: 2277 237 283 0 + // 0xa000-0xafff: 971 254 357 0 + // 0xb000-0xbfff: 317 306 429 0 + // 0xc000-0xcfff: 203 402 401 0 + // 0xd000-0xdfff: 256 394 241 0 + // 0xe000-0xefff: 378 343 173 0 + // 0xf000-0xffff: 3018 2040 1932 15450 +} diff --git a/libgo/go/image/png/reader_test.go b/libgo/go/image/png/reader_test.go index 7eb1fc21a89..24c4ea44808 100644 --- a/libgo/go/image/png/reader_test.go +++ b/libgo/go/image/png/reader_test.go @@ -246,7 +246,7 @@ var readerErrors = []struct { file string err string }{ - {"invalid-zlib.png", "zlib checksum error"}, + {"invalid-zlib.png", "zlib: invalid checksum"}, {"invalid-crc32.png", "invalid checksum"}, {"invalid-noend.png", "unexpected EOF"}, {"invalid-trunc.png", "unexpected EOF"}, diff --git a/libgo/go/image/png/writer.go b/libgo/go/image/png/writer.go index 286a3bc15db..57c03792b59 100644 --- a/libgo/go/image/png/writer.go +++ b/libgo/go/image/png/writer.go @@ -263,10 +263,7 @@ func filter(cr *[nFilter][]byte, pr []byte, bpp int) int { } func writeImage(w io.Writer, m image.Image, cb int) error { - zw, err := zlib.NewWriter(w) - if err != nil { - return err - } + zw := zlib.NewWriter(w) defer zw.Close() bpp := 0 // Bytes per pixel. @@ -391,8 +388,7 @@ func writeImage(w io.Writer, m image.Image, cb int) error { f := filter(&cr, pr, bpp) // Write the compressed bytes. - _, err = zw.Write(cr[f]) - if err != nil { + if _, err := zw.Write(cr[f]); err != nil { return err } diff --git a/libgo/go/image/ycbcr_test.go b/libgo/go/image/ycbcr_test.go index eb8b1950bfe..b2373f79ba3 100644 --- a/libgo/go/image/ycbcr_test.go +++ b/libgo/go/image/ycbcr_test.go @@ -50,6 +50,9 @@ func TestYCbCr(t *testing.T) { testYCbCr(t, r, subsampleRatio, delta) } } + if testing.Short() { + break + } } } diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go index bbfa6c2b2aa..7074834d613 100644 --- a/libgo/go/io/io.go +++ b/libgo/go/io/io.go @@ -6,6 +6,10 @@ // Its primary job is to wrap existing implementations of such primitives, // such as those in package os, into shared public interfaces that // abstract the functionality, plus some other related primitives. +// +// Because these interfaces and primitives wrap lower-level operations with +// various implementations, unless otherwise informed clients should not +// assume they are safe for parallel execution. package io import ( @@ -156,6 +160,9 @@ type WriterTo interface { // If ReadAt is reading from an input source with a seek offset, // ReadAt should not affect nor be affected by the underlying // seek offset. +// +// Clients of ReadAt can execute parallel ReadAt calls on the +// same input source. type ReaderAt interface { ReadAt(p []byte, off int64) (n int, err error) } diff --git a/libgo/go/io/ioutil/tempfile.go b/libgo/go/io/ioutil/tempfile.go index 645eed6abb8..42d2e675869 100644 --- a/libgo/go/io/ioutil/tempfile.go +++ b/libgo/go/io/ioutil/tempfile.go @@ -49,7 +49,7 @@ func TempFile(dir, prefix string) (f *os.File, err error) { for i := 0; i < 10000; i++ { name := filepath.Join(dir, prefix+nextSuffix()) f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) - if pe, ok := err.(*os.PathError); ok && pe.Err == os.EEXIST { + if os.IsExist(err) { if nconflict++; nconflict > 10 { rand = reseed() } @@ -76,7 +76,7 @@ func TempDir(dir, prefix string) (name string, err error) { for i := 0; i < 10000; i++ { try := filepath.Join(dir, prefix+nextSuffix()) err = os.Mkdir(try, 0700) - if pe, ok := err.(*os.PathError); ok && pe.Err == os.EEXIST { + if os.IsExist(err) { if nconflict++; nconflict > 10 { rand = reseed() } diff --git a/libgo/go/io/pipe.go b/libgo/go/io/pipe.go index cf05e0c1ad7..f3f0f175706 100644 --- a/libgo/go/io/pipe.go +++ b/libgo/go/io/pipe.go @@ -175,6 +175,10 @@ func (w *PipeWriter) CloseWithError(err error) error { // with code expecting an io.Writer. // Reads on one end are matched with writes on the other, // copying data directly between the two; there is no internal buffering. +// It is safe to call Read and Write in parallel with each other or with +// Close. Close will complete once pending I/O is done. Parallel calls to +// Read, and parallel calls to Write, are also safe: +// the individual calls will be gated sequentially. func Pipe() (*PipeReader, *PipeWriter) { p := new(pipe) p.rwait.L = &p.l diff --git a/libgo/go/log/log.go b/libgo/go/log/log.go index a5d88fd9b34..02a407ebc60 100644 --- a/libgo/go/log/log.go +++ b/libgo/go/log/log.go @@ -14,6 +14,7 @@ package log import ( "bytes" + _ "debug/elf" "fmt" "io" "os" diff --git a/libgo/go/log/log_test.go b/libgo/go/log/log_test.go index 72ebf398eda..158c3d93c7e 100644 --- a/libgo/go/log/log_test.go +++ b/libgo/go/log/log_test.go @@ -17,9 +17,9 @@ const ( Rdate = `[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]` Rtime = `[0-9][0-9]:[0-9][0-9]:[0-9][0-9]` Rmicroseconds = `\.[0-9][0-9][0-9][0-9][0-9][0-9]` - Rline = `[0-9]+:` // must update if the calls to l.Printf / l.Print below move - Rlongfile = `.*/[A-Za-z0-9_\-]+\.go:|\?\?\?:` + Rline - Rshortfile = `[A-Za-z0-9_\-]+\.go:|\?\?\?:` + Rline + Rline = `(54|56):` // must update if the calls to l.Printf / l.Print below move + Rlongfile = `.*/[A-Za-z0-9_\-]+\.go:` + Rline + Rshortfile = `[A-Za-z0-9_\-]+\.go:` + Rline ) type tester struct { diff --git a/libgo/go/log/syslog/syslog.go b/libgo/go/log/syslog/syslog.go index aef63480f16..f53310cb0a1 100644 --- a/libgo/go/log/syslog/syslog.go +++ b/libgo/go/log/syslog/syslog.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !windows,!plan9 + // Package syslog provides a simple interface to the system log service. It // can send messages to the syslog daemon using UNIX domain sockets, UDP, or // TCP connections. @@ -136,25 +138,33 @@ func (w *Writer) Debug(m string) (err error) { } func (n netConn) writeBytes(p Priority, prefix string, b []byte) (int, error) { - return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, b) + _, err := fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, b) + if err != nil { + return 0, err + } + return len(b), nil } func (n netConn) writeString(p Priority, prefix string, s string) (int, error) { - return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, s) + _, err := fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, s) + if err != nil { + return 0, err + } + return len(s), nil } func (n netConn) close() error { return n.conn.Close() } -// NewLogger provides an object that implements the full log.Logger interface, -// but sends messages to Syslog instead; flag is passed as is to Logger; -// priority will be used for all messages sent using this interface. -// All messages are logged with priority p. -func NewLogger(p Priority, flag int) *log.Logger { +// NewLogger creates a log.Logger whose output is written to +// the system log service with the specified priority. The logFlag +// argument is the flag set passed through to log.New to create +// the Logger. +func NewLogger(p Priority, logFlag int) (*log.Logger, error) { s, err := New(p, "") if err != nil { - return nil + return nil, err } - return log.New(s, "", flag) + return log.New(s, "", logFlag), nil } diff --git a/libgo/go/log/syslog/syslog_test.go b/libgo/go/log/syslog/syslog_test.go index b9793e91abd..0fd6239059a 100644 --- a/libgo/go/log/syslog/syslog_test.go +++ b/libgo/go/log/syslog/syslog_test.go @@ -1,6 +1,9 @@ // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. + +// +build !windows,!plan9 + package syslog import ( @@ -61,9 +64,9 @@ func TestNewLogger(t *testing.T) { if skipNetTest(t) { return } - f := NewLogger(LOG_INFO, 0) + f, err := NewLogger(LOG_INFO, 0) if f == nil { - t.Error("NewLogger() failed") + t.Error(err) } } diff --git a/libgo/go/log/syslog/syslog_unix.go b/libgo/go/log/syslog/syslog_unix.go index b1c929ad2fe..46a164dd577 100644 --- a/libgo/go/log/syslog/syslog_unix.go +++ b/libgo/go/log/syslog/syslog_unix.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !windows,!plan9 + package syslog import ( diff --git a/libgo/go/math/big/calibrate_test.go b/libgo/go/math/big/calibrate_test.go index 0950eeedbd2..efe1837bba3 100644 --- a/libgo/go/math/big/calibrate_test.go +++ b/libgo/go/math/big/calibrate_test.go @@ -8,7 +8,7 @@ // results are somewhat fragile; use repeated runs to get // a clear picture. -// Usage: gotest -calibrate +// Usage: go test -run=TestCalibrate -calibrate package big diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go index 6e1c7ffde4e..da1ac944c5c 100644 --- a/libgo/go/math/big/nat.go +++ b/libgo/go/math/big/nat.go @@ -897,7 +897,7 @@ func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word } // Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion) -// Benchmark and configure leafSize using: gotest -test.bench="Leaf" +// Benchmark and configure leafSize using: go test -bench="Leaf" // 8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines) // 8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU var leafSize int = 8 // number of Word-size binary values treat as a monolithic block diff --git a/libgo/go/math/big/nat_test.go b/libgo/go/math/big/nat_test.go index 25e39273c0c..7f3f76dc36f 100644 --- a/libgo/go/math/big/nat_test.go +++ b/libgo/go/math/big/nat_test.go @@ -512,6 +512,9 @@ func TestStringPowers(t *testing.T) { t.Errorf("failed at %d ** %d in base %d: %s != %s", b, p, b, xs, xs2) } } + if b >= 3 && testing.Short() { + break + } } } diff --git a/libgo/go/math/const.go b/libgo/go/math/const.go index 282561f98bb..f1247c383fd 100644 --- a/libgo/go/math/const.go +++ b/libgo/go/math/const.go @@ -6,7 +6,7 @@ package math // Mathematical constants. -// Reference: http://www.research.att.com/~njas/sequences/Axxxxxx +// Reference: http://oeis.org/Axxxxxx const ( E = 2.71828182845904523536028747135266249775724709369995957496696763 // A001113 Pi = 3.14159265358979323846264338327950288419716939937510582097494459 // A000796 @@ -27,11 +27,11 @@ const ( // Max is the largest finite value representable by the type. // SmallestNonzero is the smallest positive, non-zero value representable by the type. const ( - MaxFloat32 = 3.40282346638528859811704183484516925440e+38 /* 2**127 * (2**24 - 1) / 2**23 */ - SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 /* 1 / 2**(127 - 1 + 23) */ + MaxFloat32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23 + SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23) - MaxFloat64 = 1.797693134862315708145274237317043567981e+308 /* 2**1023 * (2**53 - 1) / 2**52 */ - SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 /* 1 / 2**(1023 - 1 + 52) */ + MaxFloat64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52 + SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52) ) // Integer limit values. diff --git a/libgo/go/math/gamma.go b/libgo/go/math/gamma.go index 2385a53b8a5..7c6f421bad1 100644 --- a/libgo/go/math/gamma.go +++ b/libgo/go/math/gamma.go @@ -116,7 +116,7 @@ func stirling(x float64) float64 { // Gamma(±Inf) = ±Inf // Gamma(NaN) = NaN // Large values overflow to +Inf. -// Negative integer values equal ±Inf. +// Zero and negative integer arguments return ±Inf. func Gamma(x float64) float64 { const Euler = 0.57721566490153286060651209008240243104215933593992 // A001620 // special cases diff --git a/libgo/go/math/rand/rand.go b/libgo/go/math/rand/rand.go index 89552192030..94f84a85fbe 100644 --- a/libgo/go/math/rand/rand.go +++ b/libgo/go/math/rand/rand.go @@ -49,9 +49,10 @@ func (r *Rand) Int() int { } // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func (r *Rand) Int63n(n int64) int64 { if n <= 0 { - return 0 + panic("invalid argument to Int63n") } max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) v := r.Int63() @@ -62,9 +63,10 @@ func (r *Rand) Int63n(n int64) int64 { } // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func (r *Rand) Int31n(n int32) int32 { if n <= 0 { - return 0 + panic("invalid argument to Int31n") } max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) v := r.Int31() @@ -75,7 +77,11 @@ func (r *Rand) Int31n(n int32) int32 { } // Intn returns, as an int, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func (r *Rand) Intn(n int) int { + if n <= 0 { + panic("invalid argument to Intn") + } if n <= 1<<31-1 { return int(r.Int31n(int32(n))) } @@ -125,12 +131,15 @@ func Int31() int32 { return globalRand.Int31() } func Int() int { return globalRand.Int() } // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func Int63n(n int64) int64 { return globalRand.Int63n(n) } // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func Int31n(n int32) int32 { return globalRand.Int31n(n) } // Intn returns, as an int, a non-negative pseudo-random number in [0,n). +// It panics if n <= 0. func Intn(n int) int { return globalRand.Intn(n) } // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). diff --git a/libgo/go/math/rand/rand_test.go b/libgo/go/math/rand/rand_test.go index 0ba8f98c496..bbd44e3f8b1 100644 --- a/libgo/go/math/rand/rand_test.go +++ b/libgo/go/math/rand/rand_test.go @@ -141,6 +141,9 @@ func TestNonStandardNormalValues(t *testing.T) { for m := 0.5; m < mmax; m *= 2 { for _, seed := range testSeeds { testNormalDistribution(t, numTestSamples, m, sd, seed) + if testing.Short() { + break + } } } } @@ -191,6 +194,9 @@ func TestNonStandardExponentialValues(t *testing.T) { for rate := 0.05; rate < 10; rate *= 2 { for _, seed := range testSeeds { testExponentialDistribution(t, numTestSamples, rate, seed) + if testing.Short() { + break + } } } } diff --git a/libgo/go/mime/grammar.go b/libgo/go/mime/grammar.go index e16a06c86be..83cc411343f 100644 --- a/libgo/go/mime/grammar.go +++ b/libgo/go/mime/grammar.go @@ -14,25 +14,25 @@ func isTSpecial(r rune) bool { return strings.IndexRune(`()<>@,;:\"/[]?=`, r) != -1 } -// IsTokenChar returns true if rune is in 'token' as defined by RFC +// isTokenChar returns true if rune is in 'token' as defined by RFC // 1521 and RFC 2045. -func IsTokenChar(r rune) bool { +func isTokenChar(r rune) bool { // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, // or tspecials> return r > 0x20 && r < 0x7f && !isTSpecial(r) } -// IsToken returns true if s is a 'token' as as defined by RFC 1521 +// isToken returns true if s is a 'token' as as defined by RFC 1521 // and RFC 2045. -func IsToken(s string) bool { +func isToken(s string) bool { if s == "" { return false } return strings.IndexFunc(s, isNotTokenChar) < 0 } -// IsQText returns true if rune is in 'qtext' as defined by RFC 822. -func IsQText(r int) bool { +// isQText returns true if rune is in 'qtext' as defined by RFC 822. +func isQText(r int) bool { // CHAR = <any ASCII character> ; ( 0-177, 0.-127.) // qtext = <any CHAR excepting <">, ; => may be folded // "\" & CR, and including diff --git a/libgo/go/mime/mediatype.go b/libgo/go/mime/mediatype.go index 41844c25f2a..9398dece1d9 100644 --- a/libgo/go/mime/mediatype.go +++ b/libgo/go/mime/mediatype.go @@ -23,7 +23,7 @@ func FormatMediaType(t string, param map[string]string) string { return "" } major, sub := t[:slash], t[slash+1:] - if !IsToken(major) || !IsToken(sub) { + if !isToken(major) || !isToken(sub) { return "" } var b bytes.Buffer @@ -34,12 +34,12 @@ func FormatMediaType(t string, param map[string]string) string { for attribute, value := range param { b.WriteByte(';') b.WriteByte(' ') - if !IsToken(attribute) { + if !isToken(attribute) { return "" } b.WriteString(strings.ToLower(attribute)) b.WriteByte('=') - if IsToken(value) { + if isToken(value) { b.WriteString(value) continue } @@ -205,7 +205,7 @@ func decode2231Enc(v string) string { } func isNotTokenChar(r rune) bool { - return !IsTokenChar(r) + return !isTokenChar(r) } // consumeToken consumes a token from the beginning of provided diff --git a/libgo/go/mime/multipart/formdata.go b/libgo/go/mime/multipart/formdata.go index ec643c1476f..eee53fc8dd0 100644 --- a/libgo/go/mime/multipart/formdata.go +++ b/libgo/go/mime/multipart/formdata.go @@ -130,7 +130,7 @@ type FileHeader struct { // Open opens and returns the FileHeader's associated File. func (fh *FileHeader) Open() (File, error) { if b := fh.content; b != nil { - r := io.NewSectionReader(sliceReaderAt(b), 0, int64(len(b))) + r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))) return sectionReadCloser{r}, nil } return os.Open(fh.tmpfile) @@ -155,13 +155,3 @@ type sectionReadCloser struct { func (rc sectionReadCloser) Close() error { return nil } - -type sliceReaderAt []byte - -func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) { - if int(off) >= len(r) || off < 0 { - return 0, io.ErrUnexpectedEOF - } - n := copy(b, r[int(off):]) - return n, nil -} diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go index 5d596bcb6b4..10ca5faf707 100644 --- a/libgo/go/net/dial.go +++ b/libgo/go/net/dial.go @@ -69,7 +69,7 @@ func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) { // // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" -// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket". +// (IPv4-only), "ip6" (IPv6-only), "unix" and "unixpacket". // // For TCP and UDP networks, addresses have the form host:port. // If host is a literal IPv6 address, it must be enclosed @@ -185,7 +185,7 @@ func Listen(net, laddr string) (Listener, error) { if a != nil { la = a.(*TCPAddr) } - return ListenTCP(afnet, la) + return ListenTCP(net, la) case "unix", "unixpacket": var la *UnixAddr if a != nil { diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go index de35ec9f940..5f5aea146a6 100644 --- a/libgo/go/net/dial_test.go +++ b/libgo/go/net/dial_test.go @@ -5,6 +5,8 @@ package net import ( + "flag" + "regexp" "runtime" "testing" "time" @@ -27,8 +29,7 @@ func TestDialTimeout(t *testing.T) { errc := make(chan error) - const SOMAXCONN = 0x80 // copied from syscall, but not always available - const numConns = SOMAXCONN + 10 + numConns := listenerBacklog + 10 // TODO(bradfitz): It's hard to test this in a portable // way. This is unforunate, but works for now. @@ -43,7 +44,7 @@ func TestDialTimeout(t *testing.T) { errc <- err }() } - case "darwin", "windows": + case "darwin": // At least OS X 10.7 seems to accept any number of // connections, ignoring listen's backlog, so resort // to connecting to a hopefully-dead 127/8 address. @@ -54,8 +55,10 @@ func TestDialTimeout(t *testing.T) { }() default: // TODO(bradfitz): - // OpenBSD may have a reject route to 10/8. - // FreeBSD likely works, but is untested. + // OpenBSD may have a reject route to 127/8 except 127.0.0.1/32 + // by default. FreeBSD likely works, but is untested. + // TODO(rsc): + // The timeout never happens on Windows. Why? Issue 3016. t.Logf("skipping test on %q; untested.", runtime.GOOS) return } @@ -85,3 +88,124 @@ func TestDialTimeout(t *testing.T) { } } } + +func TestSelfConnect(t *testing.T) { + if runtime.GOOS == "windows" { + // TODO(brainman): do not know why it hangs. + t.Logf("skipping known-broken test on windows") + return + } + // Test that Dial does not honor self-connects. + // See the comment in DialTCP. + + // Find a port that would be used as a local address. + l, err := Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + c, err := Dial("tcp", l.Addr().String()) + if err != nil { + t.Fatal(err) + } + addr := c.LocalAddr().String() + c.Close() + l.Close() + + // Try to connect to that address repeatedly. + n := 100000 + if testing.Short() { + n = 1000 + } + switch runtime.GOOS { + case "darwin", "freebsd", "openbsd", "windows": + // Non-Linux systems take a long time to figure + // out that there is nothing listening on localhost. + n = 100 + } + for i := 0; i < n; i++ { + c, err := Dial("tcp", addr) + if err == nil { + c.Close() + t.Errorf("#%d: Dial %q succeeded", i, addr) + } + } +} + +var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors") + +type DialErrorTest struct { + Net string + Raddr string + Pattern string +} + +var dialErrorTests = []DialErrorTest{ + { + "datakit", "mh/astro/r70", + "dial datakit mh/astro/r70: unknown network datakit", + }, + { + "tcp", "127.0.0.1:☺", + "dial tcp 127.0.0.1:☺: unknown port tcp/☺", + }, + { + "tcp", "no-such-name.google.com.:80", + "dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)", + }, + { + "tcp", "no-such-name.no-such-top-level-domain.:80", + "dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)", + }, + { + "tcp", "no-such-name:80", + `dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`, + }, + { + "tcp", "mh/astro/r70:http", + "dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name", + }, + { + "unix", "/etc/file-not-found", + "dial unix /etc/file-not-found: no such file or directory", + }, + { + "unix", "/etc/", + "dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)", + }, + { + "unixpacket", "/etc/file-not-found", + "dial unixpacket /etc/file-not-found: no such file or directory", + }, + { + "unixpacket", "/etc/", + "dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)", + }, +} + +var duplicateErrorPattern = `dial (.*) dial (.*)` + +func TestDialError(t *testing.T) { + if !*runErrorTest { + t.Logf("test disabled; use -run_error_test to enable") + return + } + for i, tt := range dialErrorTests { + c, err := Dial(tt.Net, tt.Raddr) + if c != nil { + c.Close() + } + if err == nil { + t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern) + continue + } + s := err.Error() + match, _ := regexp.MatchString(tt.Pattern, s) + if !match { + t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern) + } + match, _ = regexp.MatchString(duplicateErrorPattern, s) + if match { + t.Errorf("#%d: %q, duplicate error return from Dial", i, s) + } + } +} diff --git a/libgo/go/net/dialgoogle_test.go b/libgo/go/net/dialgoogle_test.go index 81750a3d739..03c4499720f 100644 --- a/libgo/go/net/dialgoogle_test.go +++ b/libgo/go/net/dialgoogle_test.go @@ -14,7 +14,7 @@ import ( ) // If an IPv6 tunnel is running, we can try dialing a real IPv6 address. -var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present") +var testIPv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present") // fd is already connected to the destination, port 80. // Run an HTTP request to fetch the appropriate page. @@ -42,9 +42,8 @@ func doDial(t *testing.T, network, addr string) { } func TestLookupCNAME(t *testing.T) { - if testing.Short() { - // Don't use external network. - t.Logf("skipping external network test during -short") + if testing.Short() || !*testExternal { + t.Logf("skipping test to avoid external network") return } cname, err := LookupCNAME("www.google.com") @@ -67,9 +66,8 @@ var googleaddrsipv4 = []string{ } func TestDialGoogleIPv4(t *testing.T) { - if testing.Short() { - // Don't use external network. - t.Logf("skipping external network test during -short") + if testing.Short() || !*testExternal { + t.Logf("skipping test to avoid external network") return } @@ -124,13 +122,12 @@ var googleaddrsipv6 = []string{ } func TestDialGoogleIPv6(t *testing.T) { - if testing.Short() { - // Don't use external network. - t.Logf("skipping external network test during -short") + if testing.Short() || !*testExternal { + t.Logf("skipping test to avoid external network") return } // Only run tcp6 if the kernel will take it. - if !*ipv6 || !supportsIPv6 { + if !*testIPv6 || !supportsIPv6 { return } diff --git a/libgo/go/net/fd.go b/libgo/go/net/fd.go index 2352d22e115..ae1bf2614a2 100644 --- a/libgo/go/net/fd.go +++ b/libgo/go/net/fd.go @@ -7,6 +7,7 @@ package net import ( + "errors" "io" "os" "sync" @@ -17,8 +18,11 @@ import ( // Network file descriptor. type netFD struct { // locking/lifetime of sysfd - sysmu sync.Mutex - sysref int + sysmu sync.Mutex + sysref int + + // must lock both sysmu and pollserver to write + // can lock either to read closing bool // immutable until Close @@ -27,8 +31,8 @@ type netFD struct { sotype int isConnected bool sysfile *os.File - cr chan bool - cw chan bool + cr chan error + cw chan error net string laddr Addr raddr Addr @@ -86,20 +90,15 @@ type pollServer struct { deadline int64 // next deadline (nsec since 1970) } -func (s *pollServer) AddFD(fd *netFD, mode int) { +func (s *pollServer) AddFD(fd *netFD, mode int) error { + s.Lock() intfd := fd.sysfd - if intfd < 0 { + if intfd < 0 || fd.closing { // fd closed underfoot - if mode == 'r' { - fd.cr <- true - } else { - fd.cw <- true - } - return + s.Unlock() + return errClosing } - s.Lock() - var t int64 key := intfd << 1 if mode == 'r' { @@ -124,12 +123,28 @@ func (s *pollServer) AddFD(fd *netFD, mode int) { if wake { doWakeup = true } - s.Unlock() if doWakeup { s.Wakeup() } + return nil +} + +// Evict evicts fd from the pending list, unblocking +// any I/O running on fd. The caller must have locked +// pollserver. +func (s *pollServer) Evict(fd *netFD) { + if s.pending[fd.sysfd<<1] == fd { + s.WakeFD(fd, 'r', errClosing) + s.poll.DelFD(fd.sysfd, 'r') + delete(s.pending, fd.sysfd<<1) + } + if s.pending[fd.sysfd<<1|1] == fd { + s.WakeFD(fd, 'w', errClosing) + s.poll.DelFD(fd.sysfd, 'w') + delete(s.pending, fd.sysfd<<1|1) + } } var wakeupbuf [1]byte @@ -149,16 +164,16 @@ func (s *pollServer) LookupFD(fd int, mode int) *netFD { return netfd } -func (s *pollServer) WakeFD(fd *netFD, mode int) { +func (s *pollServer) WakeFD(fd *netFD, mode int, err error) { if mode == 'r' { for fd.ncr > 0 { fd.ncr-- - fd.cr <- true + fd.cr <- err } } else { for fd.ncw > 0 { fd.ncw-- - fd.cw <- true + fd.cw <- err } } } @@ -196,7 +211,7 @@ func (s *pollServer) CheckDeadlines() { s.poll.DelFD(fd.sysfd, mode) fd.wdeadline = -1 } - s.WakeFD(fd, mode) + s.WakeFD(fd, mode, nil) } else if next_deadline == 0 || t < next_deadline { next_deadline = t } @@ -228,7 +243,7 @@ func (s *pollServer) Run() { s.CheckDeadlines() continue } - if fd == s.pr.Fd() { + if fd == int(s.pr.Fd()) { // Drain our wakeup pipe (we could loop here, // but it's unlikely that there are more than // len(scratch) wakeup calls). @@ -237,22 +252,30 @@ func (s *pollServer) Run() { } else { netfd := s.LookupFD(fd, mode) if netfd == nil { - print("pollServer: unexpected wakeup for fd=", fd, " mode=", string(mode), "\n") + // This can happen because the WaitFD runs without + // holding s's lock, so there might be a pending wakeup + // for an fd that has been evicted. No harm done. continue } - s.WakeFD(netfd, mode) + s.WakeFD(netfd, mode, nil) } } } -func (s *pollServer) WaitRead(fd *netFD) { - s.AddFD(fd, 'r') - <-fd.cr +func (s *pollServer) WaitRead(fd *netFD) error { + err := s.AddFD(fd, 'r') + if err == nil { + err = <-fd.cr + } + return err } -func (s *pollServer) WaitWrite(fd *netFD) { - s.AddFD(fd, 'w') - <-fd.cw +func (s *pollServer) WaitWrite(fd *netFD) error { + err := s.AddFD(fd, 'w') + if err == nil { + err = <-fd.cw + } + return err } // Network FD methods. @@ -280,8 +303,8 @@ func newFD(fd, family, sotype int, net string) (*netFD, error) { sotype: sotype, net: net, } - netfd.cr = make(chan bool, 1) - netfd.cw = make(chan bool, 1) + netfd.cr = make(chan error, 1) + netfd.cw = make(chan error, 1) return netfd, nil } @@ -295,13 +318,15 @@ func (fd *netFD) setAddr(laddr, raddr Addr) { if raddr != nil { rs = raddr.String() } - fd.sysfile = os.NewFile(fd.sysfd, fd.net+":"+ls+"->"+rs) + fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net+":"+ls+"->"+rs) } func (fd *netFD) connect(ra syscall.Sockaddr) error { err := syscall.Connect(fd.sysfd, ra) if err == syscall.EINPROGRESS { - pollserver.WaitWrite(fd) + if err = pollserver.WaitWrite(fd); err != nil { + return err + } var e int e, err = syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR) if err != nil { @@ -314,24 +339,37 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error { return err } +var errClosing = errors.New("use of closed network connection") + // Add a reference to this fd. -func (fd *netFD) incref() { +// If closing==true, pollserver must be locked; mark the fd as closing. +// Returns an error if the fd cannot be used. +func (fd *netFD) incref(closing bool) error { + if fd == nil { + return errClosing + } fd.sysmu.Lock() + if fd.closing { + fd.sysmu.Unlock() + return errClosing + } fd.sysref++ + if closing { + fd.closing = true + } fd.sysmu.Unlock() + return nil } // Remove a reference to this FD and close if we've been asked to do so (and // there are no references left. func (fd *netFD) decref() { + if fd == nil { + return + } fd.sysmu.Lock() fd.sysref-- - if fd.closing && fd.sysref == 0 && fd.sysfd >= 0 { - // In case the user has set linger, switch to blocking mode so - // the close blocks. As long as this doesn't happen often, we - // can handle the extra OS processes. Otherwise we'll need to - // use the pollserver for Close too. Sigh. - syscall.SetNonblock(fd.sysfd, false) + if fd.closing && fd.sysref == 0 && fd.sysfile != nil { fd.sysfile.Close() fd.sysfile = nil fd.sysfd = -1 @@ -340,21 +378,26 @@ func (fd *netFD) decref() { } func (fd *netFD) Close() error { - if fd == nil || fd.sysfile == nil { - return os.EINVAL - } - - fd.incref() - syscall.Shutdown(fd.sysfd, syscall.SHUT_RDWR) - fd.closing = true + pollserver.Lock() // needed for both fd.incref(true) and pollserver.Evict + defer pollserver.Unlock() + if err := fd.incref(true); err != nil { + return err + } + // Unblock any I/O. Once it all unblocks and returns, + // so that it cannot be referring to fd.sysfd anymore, + // the final decref will close fd.sysfd. This should happen + // fairly quickly, since all the I/O is non-blocking, and any + // attempts to block in the pollserver will return errClosing. + pollserver.Evict(fd) fd.decref() return nil } func (fd *netFD) shutdown(how int) error { - if fd == nil || fd.sysfile == nil { - return os.EINVAL + if err := fd.incref(false); err != nil { + return err } + defer fd.decref() err := syscall.Shutdown(fd.sysfd, how) if err != nil { return &OpError{"shutdown", fd.net, fd.laddr, err} @@ -371,24 +414,21 @@ func (fd *netFD) CloseWrite() error { } func (fd *netFD) Read(p []byte) (n int, err error) { - if fd == nil { - return 0, os.EINVAL - } fd.rio.Lock() defer fd.rio.Unlock() - fd.incref() - defer fd.decref() - if fd.sysfile == nil { - return 0, os.EINVAL + if err := fd.incref(false); err != nil { + return 0, err } + defer fd.decref() for { - n, err = syscall.Read(fd.sysfile.Fd(), p) + n, err = syscall.Read(int(fd.sysfd), p) if err == syscall.EAGAIN { + err = errTimeout if fd.rdeadline >= 0 { - pollserver.WaitRead(fd) - continue + if err = pollserver.WaitRead(fd); err == nil { + continue + } } - err = errTimeout } if err != nil { n = 0 @@ -404,49 +444,49 @@ func (fd *netFD) Read(p []byte) (n int, err error) { } func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { - if fd == nil || fd.sysfile == nil { - return 0, nil, os.EINVAL - } fd.rio.Lock() defer fd.rio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, nil, err + } defer fd.decref() for { n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) if err == syscall.EAGAIN { + err = errTimeout if fd.rdeadline >= 0 { - pollserver.WaitRead(fd) - continue + if err = pollserver.WaitRead(fd); err == nil { + continue + } } - err = errTimeout } if err != nil { n = 0 } break } - if err != nil { + if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.laddr, err} } return } func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { - if fd == nil || fd.sysfile == nil { - return 0, 0, 0, nil, os.EINVAL - } fd.rio.Lock() defer fd.rio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, 0, 0, nil, err + } defer fd.decref() for { n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0) if err == syscall.EAGAIN { + err = errTimeout if fd.rdeadline >= 0 { - pollserver.WaitRead(fd) - continue + if err = pollserver.WaitRead(fd); err == nil { + continue + } } - err = errTimeout } if err == nil && n == 0 { err = io.EOF @@ -461,22 +501,21 @@ func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S } func (fd *netFD) Write(p []byte) (int, error) { - if fd == nil { - return 0, os.EINVAL - } fd.wio.Lock() defer fd.wio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() if fd.sysfile == nil { - return 0, os.EINVAL + return 0, syscall.EINVAL } var err error nn := 0 for { var n int - n, err = syscall.Write(fd.sysfile.Fd(), p[nn:]) + n, err = syscall.Write(int(fd.sysfd), p[nn:]) if n > 0 { nn += n } @@ -484,11 +523,12 @@ func (fd *netFD) Write(p []byte) (int, error) { break } if err == syscall.EAGAIN { + err = errTimeout if fd.wdeadline >= 0 { - pollserver.WaitWrite(fd) - continue + if err = pollserver.WaitWrite(fd); err == nil { + continue + } } - err = errTimeout } if err != nil { n = 0 @@ -506,21 +546,21 @@ func (fd *netFD) Write(p []byte) (int, error) { } func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) { - if fd == nil || fd.sysfile == nil { - return 0, os.EINVAL - } fd.wio.Lock() defer fd.wio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() for { err = syscall.Sendto(fd.sysfd, p, 0, sa) if err == syscall.EAGAIN { + err = errTimeout if fd.wdeadline >= 0 { - pollserver.WaitWrite(fd) - continue + if err = pollserver.WaitWrite(fd); err == nil { + continue + } } - err = errTimeout } break } @@ -533,21 +573,21 @@ func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) { } func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { - if fd == nil || fd.sysfile == nil { - return 0, 0, os.EINVAL - } fd.wio.Lock() defer fd.wio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, 0, err + } defer fd.decref() for { err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0) if err == syscall.EAGAIN { + err = errTimeout if fd.wdeadline >= 0 { - pollserver.WaitWrite(fd) - continue + if err = pollserver.WaitWrite(fd); err == nil { + continue + } } - err = errTimeout } break } @@ -561,11 +601,9 @@ func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob } func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) { - if fd == nil || fd.sysfile == nil { - return nil, os.EINVAL + if err := fd.incref(false); err != nil { + return nil, err } - - fd.incref() defer fd.decref() // See ../syscall/exec.go for description of ForkLock. @@ -574,19 +612,17 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e var s int var rsa syscall.Sockaddr for { - if fd.closing { - return nil, os.EINVAL - } syscall.ForkLock.RLock() s, rsa, err = syscall.Accept(fd.sysfd) if err != nil { syscall.ForkLock.RUnlock() if err == syscall.EAGAIN { + err = errTimeout if fd.rdeadline >= 0 { - pollserver.WaitRead(fd) - continue + if err = pollserver.WaitRead(fd); err == nil { + continue + } } - err = errTimeout } return nil, &OpError{"accept", fd.net, fd.laddr, err} } @@ -615,7 +651,7 @@ func (fd *netFD) dup() (f *os.File, err error) { return nil, &OpError{"setnonblock", fd.net, fd.laddr, err} } - return os.NewFile(ns, fd.sysfile.Name()), nil + return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil } func closesocket(s int) error { diff --git a/libgo/go/net/fd_windows.go b/libgo/go/net/fd_windows.go index 78168eb6c86..45f5c2d882f 100644 --- a/libgo/go/net/fd_windows.go +++ b/libgo/go/net/fd_windows.go @@ -5,6 +5,7 @@ package net import ( + "errors" "io" "os" "runtime" @@ -272,11 +273,27 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error { return syscall.Connect(fd.sysfd, ra) } +var errClosing = errors.New("use of closed network connection") + // Add a reference to this fd. -func (fd *netFD) incref() { +// If closing==true, mark the fd as closing. +// Returns an error if the fd cannot be used. +func (fd *netFD) incref(closing bool) error { + if fd == nil { + return errClosing + } fd.sysmu.Lock() + if fd.closing { + fd.sysmu.Unlock() + return errClosing + } fd.sysref++ + if closing { + fd.closing = true + } + closing = fd.closing fd.sysmu.Unlock() + return nil } // Remove a reference to this FD and close if we've been asked to do so (and @@ -284,7 +301,17 @@ func (fd *netFD) incref() { func (fd *netFD) decref() { fd.sysmu.Lock() fd.sysref-- - if fd.closing && fd.sysref == 0 && fd.sysfd != syscall.InvalidHandle { + // NOTE(rsc): On Unix we check fd.sysref == 0 here before closing, + // but on Windows we have no way to wake up the blocked I/O other + // than closing the socket (or calling Shutdown, which breaks other + // programs that might have a reference to the socket). So there is + // a small race here that we might close fd.sysfd and then some other + // goroutine might start a read of fd.sysfd (having read it before we + // write InvalidHandle to it), which might refer to some other file + // if the specific handle value gets reused. I think handle values on + // Windows are not reused as aggressively as file descriptors on Unix, + // so this might be tolerable. + if fd.closing && fd.sysfd != syscall.InvalidHandle { // In case the user has set linger, switch to blocking mode so // the close blocks. As long as this doesn't happen often, we // can handle the extra OS processes. Otherwise we'll need to @@ -299,20 +326,16 @@ func (fd *netFD) decref() { } func (fd *netFD) Close() error { - if fd == nil || fd.sysfd == syscall.InvalidHandle { - return os.EINVAL + if err := fd.incref(true); err != nil { + return err } - - fd.incref() - syscall.Shutdown(fd.sysfd, syscall.SHUT_RDWR) - fd.closing = true fd.decref() return nil } func (fd *netFD) shutdown(how int) error { if fd == nil || fd.sysfd == syscall.InvalidHandle { - return os.EINVAL + return syscall.EINVAL } err := syscall.Shutdown(fd.sysfd, how) if err != nil { @@ -346,14 +369,16 @@ func (o *readOp) Name() string { func (fd *netFD) Read(buf []byte) (int, error) { if fd == nil { - return 0, os.EINVAL + return 0, syscall.EINVAL } fd.rio.Lock() defer fd.rio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() if fd.sysfd == syscall.InvalidHandle { - return 0, os.EINVAL + return 0, syscall.EINVAL } var o readOp o.Init(fd, buf, 'r') @@ -383,18 +408,17 @@ func (o *readFromOp) Name() string { func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { if fd == nil { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } if len(buf) == 0 { return 0, nil, nil } fd.rio.Lock() defer fd.rio.Unlock() - fd.incref() - defer fd.decref() - if fd.sysfd == syscall.InvalidHandle { - return 0, nil, os.EINVAL + if err := fd.incref(false); err != nil { + return 0, nil, err } + defer fd.decref() var o readFromOp o.Init(fd, buf, 'r') o.rsan = int32(unsafe.Sizeof(o.rsa)) @@ -423,15 +447,14 @@ func (o *writeOp) Name() string { func (fd *netFD) Write(buf []byte) (int, error) { if fd == nil { - return 0, os.EINVAL + return 0, syscall.EINVAL } fd.wio.Lock() defer fd.wio.Unlock() - fd.incref() - defer fd.decref() - if fd.sysfd == syscall.InvalidHandle { - return 0, os.EINVAL + if err := fd.incref(false); err != nil { + return 0, err } + defer fd.decref() var o writeOp o.Init(fd, buf, 'w') return iosrv.ExecIO(&o, fd.wdeadline) @@ -455,17 +478,19 @@ func (o *writeToOp) Name() string { func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { if fd == nil { - return 0, os.EINVAL + return 0, syscall.EINVAL } if len(buf) == 0 { return 0, nil } fd.wio.Lock() defer fd.wio.Unlock() - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() if fd.sysfd == syscall.InvalidHandle { - return 0, os.EINVAL + return 0, syscall.EINVAL } var o writeToOp o.Init(fd, buf, 'w') @@ -493,10 +518,9 @@ func (o *acceptOp) Name() string { } func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) { - if fd == nil || fd.sysfd == syscall.InvalidHandle { - return nil, os.EINVAL + if err := fd.incref(false); err != nil { + return nil, err } - fd.incref() defer fd.decref() // Get new socket. @@ -554,10 +578,12 @@ func (fd *netFD) dup() (*os.File, error) { return nil, os.NewSyscallError("dup", syscall.EWINDOWS) } +var errNoSupport = errors.New("address family not supported") + func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { - return 0, 0, 0, nil, os.EAFNOSUPPORT + return 0, 0, 0, nil, errNoSupport } func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { - return 0, 0, os.EAFNOSUPPORT + return 0, 0, errNoSupport } diff --git a/libgo/go/net/file.go b/libgo/go/net/file.go index 901b8565995..c95d16d64e7 100644 --- a/libgo/go/net/file.go +++ b/libgo/go/net/file.go @@ -12,7 +12,7 @@ import ( ) func newFileFD(f *os.File) (*netFD, error) { - fd, err := syscall.Dup(f.Fd()) + fd, err := syscall.Dup(int(f.Fd())) if err != nil { return nil, os.NewSyscallError("dup", err) } @@ -28,7 +28,7 @@ func newFileFD(f *os.File) (*netFD, error) { switch sa.(type) { default: closesocket(fd) - return nil, os.EINVAL + return nil, syscall.EINVAL case *syscall.SockaddrInet4: family = syscall.AF_INET if proto == syscall.SOCK_DGRAM { @@ -84,7 +84,7 @@ func FileConn(f *os.File) (c Conn, err error) { return newIPConn(fd), nil } fd.Close() - return nil, os.EINVAL + return nil, syscall.EINVAL } // FileListener returns a copy of the network listener corresponding @@ -103,7 +103,7 @@ func FileListener(f *os.File) (l Listener, err error) { return &UnixListener{fd, laddr.Name}, nil } fd.Close() - return nil, os.EINVAL + return nil, syscall.EINVAL } // FilePacketConn returns a copy of the packet network connection @@ -122,5 +122,5 @@ func FilePacketConn(f *os.File) (c PacketConn, err error) { return newUnixConn(fd), nil } fd.Close() - return nil, os.EINVAL + return nil, syscall.EINVAL } diff --git a/libgo/go/net/file_plan9.go b/libgo/go/net/file_plan9.go index 06d7cc89846..04f7ee0401b 100644 --- a/libgo/go/net/file_plan9.go +++ b/libgo/go/net/file_plan9.go @@ -6,6 +6,7 @@ package net import ( "os" + "syscall" ) // FileConn returns a copy of the network connection corresponding to @@ -13,7 +14,7 @@ import ( // finished. Closing c does not affect f, and closing f does not // affect c. func FileConn(f *os.File) (c Conn, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // FileListener returns a copy of the network listener corresponding @@ -21,7 +22,7 @@ func FileConn(f *os.File) (c Conn, err error) { // when finished. Closing c does not affect l, and closing l does not // affect c. func FileListener(f *os.File) (l Listener, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // FilePacketConn returns a copy of the packet network connection @@ -29,5 +30,5 @@ func FileListener(f *os.File) (l Listener, err error) { // responsibility to close f when finished. Closing c does not affect // f, and closing f does not affect c. func FilePacketConn(f *os.File) (c PacketConn, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } diff --git a/libgo/go/net/hosts_test.go b/libgo/go/net/hosts_test.go index 1bd00541c6d..064e7e43282 100644 --- a/libgo/go/net/hosts_test.go +++ b/libgo/go/net/hosts_test.go @@ -34,7 +34,7 @@ var hosttests = []hostTest{ func TestLookupStaticHost(t *testing.T) { p := hostsPath - hostsPath = "hosts_testdata" + hostsPath = "testdata/hosts" for i := 0; i < len(hosttests); i++ { tt := hosttests[i] ips := lookupStaticHost(tt.host) diff --git a/libgo/go/net/http/cgi/child.go b/libgo/go/net/http/cgi/child.go index e6c3ef911ab..1ba7bec5fc5 100644 --- a/libgo/go/net/http/cgi/child.go +++ b/libgo/go/net/http/cgi/child.go @@ -144,6 +144,7 @@ func Serve(handler http.Handler) error { bufw: bufio.NewWriter(os.Stdout), } handler.ServeHTTP(rw, req) + rw.Write(nil) // make sure a response is sent if err = rw.bufw.Flush(); err != nil { return err } diff --git a/libgo/go/net/http/cgi/host_test.go b/libgo/go/net/http/cgi/host_test.go index b8dbdb4edd2..859911f9805 100644 --- a/libgo/go/net/http/cgi/host_test.go +++ b/libgo/go/net/http/cgi/host_test.go @@ -19,6 +19,7 @@ import ( "runtime" "strconv" "strings" + "syscall" "testing" "time" ) @@ -40,6 +41,7 @@ func runCgiTest(t *testing.T, h *Handler, httpreq string, expectedMap map[string // Make a map to hold the test map that the CGI returns. m := make(map[string]string) + m["_body"] = rw.Body.String() linesRead := 0 readlines: for { @@ -355,7 +357,7 @@ func TestCopyError(t *testing.T) { if err != nil { return false } - return p.Signal(os.UnixSignal(0)) == nil + return p.Signal(syscall.Signal(0)) == nil } if !childRunning() { diff --git a/libgo/go/net/http/cgi/matryoshka_test.go b/libgo/go/net/http/cgi/matryoshka_test.go index 1a44df20401..e1a78c8f62f 100644 --- a/libgo/go/net/http/cgi/matryoshka_test.go +++ b/libgo/go/net/http/cgi/matryoshka_test.go @@ -51,6 +51,22 @@ func TestHostingOurselves(t *testing.T) { } } +// Test that a child handler only writing headers works. +func TestChildOnlyHeaders(t *testing.T) { + h := &Handler{ + Path: os.Args[0], + Root: "/test.go", + Args: []string{"-test.run=TestBeChildCGIProcess"}, + } + expectedMap := map[string]string{ + "_body": "", + } + replay := runCgiTest(t, h, "GET /test.go?no-body=1 HTTP/1.0\nHost: example.com\n\n", expectedMap) + if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected { + t.Errorf("got a X-Test-Header of %q; expected %q", got, expected) + } +} + // Note: not actually a test. func TestBeChildCGIProcess(t *testing.T) { if os.Getenv("REQUEST_METHOD") == "" { @@ -59,8 +75,11 @@ func TestBeChildCGIProcess(t *testing.T) { } Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { rw.Header().Set("X-Test-Header", "X-Test-Value") - fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n") req.ParseForm() + if req.FormValue("no-body") == "1" { + return + } + fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n") for k, vv := range req.Form { for _, v := range vv { fmt.Fprintf(rw, "param-%s=%s\n", k, v) diff --git a/libgo/go/net/http/cookie_test.go b/libgo/go/net/http/cookie_test.go index 712350dfcef..1e9186a0581 100644 --- a/libgo/go/net/http/cookie_test.go +++ b/libgo/go/net/http/cookie_test.go @@ -128,6 +128,34 @@ var readSetCookiesTests = []struct { Raw: "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly", }}, }, + { + Header{"Set-Cookie": {".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}}, + []*Cookie{{ + Name: ".ASPXAUTH", + Value: "7E3AA", + Path: "/", + Expires: time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC), + RawExpires: "Wed, 07-Mar-2012 14:25:06 GMT", + HttpOnly: true, + Raw: ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly", + }}, + }, + { + Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly"}}, + []*Cookie{{ + Name: "ASP.NET_SessionId", + Value: "foo", + Path: "/", + HttpOnly: true, + Raw: "ASP.NET_SessionId=foo; path=/; HttpOnly", + }}, + }, + + // TODO(bradfitz): users have reported seeing this in the + // wild, but do browsers handle it? RFC 6265 just says "don't + // do that" (section 3) and then never mentions header folding + // again. + // Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}}, } func toJSON(v interface{}) string { diff --git a/libgo/go/net/http/doc.go b/libgo/go/net/http/doc.go index 8962ed31e6a..b6ae8b87a2f 100644 --- a/libgo/go/net/http/doc.go +++ b/libgo/go/net/http/doc.go @@ -12,7 +12,7 @@ Get, Head, Post, and PostForm make HTTP requests: resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) ... resp, err := http.PostForm("http://example.com/form", - url.Values{"key": {"Value"}, "id": {"123"}}) + url.Values{"key": {"Value"}, "id": {"123"}}) The client must close the response body when finished with it: @@ -60,7 +60,7 @@ Handle and HandleFunc add handlers to DefaultServeMux: http.Handle("/foo", fooHandler) http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath)) + fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) }) log.Fatal(http.ListenAndServe(":8080", nil)) diff --git a/libgo/go/net/http/example_test.go b/libgo/go/net/http/example_test.go new file mode 100644 index 00000000000..2584afc439e --- /dev/null +++ b/libgo/go/net/http/example_test.go @@ -0,0 +1,51 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http_test + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" +) + +func ExampleHijacker() { + http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) { + hj, ok := w.(http.Hijacker) + if !ok { + http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError) + return + } + conn, bufrw, err := hj.Hijack() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + // Don't forget to close the connection: + defer conn.Close() + bufrw.WriteString("Now we're speaking raw TCP. Say hi: ") + bufrw.Flush() + s, err := bufrw.ReadString('\n') + if err != nil { + log.Printf("error reading string: %v", err) + return + } + fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s) + bufrw.Flush() + }) +} + +func ExampleGet() { + res, err := http.Get("http://www.google.com/robots.txt") + if err != nil { + log.Fatal(err) + } + robots, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Fatal(err) + } + res.Body.Close() + fmt.Printf("%s", robots) +} diff --git a/libgo/go/net/http/fcgi/child.go b/libgo/go/net/http/fcgi/child.go index c94b9a7b249..c8b9a33c87b 100644 --- a/libgo/go/net/http/fcgi/child.go +++ b/libgo/go/net/http/fcgi/child.go @@ -243,9 +243,9 @@ func (c *child) serveRequest(req *request, body io.ReadCloser) { } // Serve accepts incoming FastCGI connections on the listener l, creating a new -// service thread for each. The service threads read requests and then call handler +// goroutine for each. The goroutine reads requests and then calls handler // to reply to them. -// If l is nil, Serve accepts connections on stdin. +// If l is nil, Serve accepts connections from os.Stdin. // If handler is nil, http.DefaultServeMux is used. func Serve(l net.Listener, handler http.Handler) error { if l == nil { diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go index 1392ca68ad6..f35dd32c305 100644 --- a/libgo/go/net/http/fs.go +++ b/libgo/go/net/http/fs.go @@ -17,7 +17,6 @@ import ( "strconv" "strings" "time" - "unicode/utf8" ) // A Dir implements http.FileSystem using the native file @@ -58,32 +57,6 @@ type File interface { Seek(offset int64, whence int) (int64, error) } -// Heuristic: b is text if it is valid UTF-8 and doesn't -// contain any unprintable ASCII or Unicode characters. -func isText(b []byte) bool { - for len(b) > 0 && utf8.FullRune(b) { - rune, size := utf8.DecodeRune(b) - if size == 1 && rune == utf8.RuneError { - // decoding error - return false - } - if 0x7F <= rune && rune <= 0x9F { - return false - } - if rune < ' ' { - switch rune { - case '\n', '\r', '\t': - // okay - default: - // binary garbage - return false - } - } - b = b[size:] - } - return true -} - func dirList(w ResponseWriter, f File) { w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, "<pre>\n") @@ -104,6 +77,126 @@ func dirList(w ResponseWriter, f File) { fmt.Fprintf(w, "</pre>\n") } +// ServeContent replies to the request using the content in the +// provided ReadSeeker. The main benefit of ServeContent over io.Copy +// is that it handles Range requests properly, sets the MIME type, and +// handles If-Modified-Since requests. +// +// If the response's Content-Type header is not set, ServeContent +// first tries to deduce the type from name's file extension and, +// if that fails, falls back to reading the first block of the content +// and passing it to DetectContentType. +// The name is otherwise unused; in particular it can be empty and is +// never sent in the response. +// +// If modtime is not the zero time, ServeContent includes it in a +// Last-Modified header in the response. If the request includes an +// If-Modified-Since header, ServeContent uses modtime to decide +// whether the content needs to be sent at all. +// +// The content's Seek method must work: ServeContent uses +// a seek to the end of the content to determine its size. +// +// Note that *os.File implements the io.ReadSeeker interface. +func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker) { + size, err := content.Seek(0, os.SEEK_END) + if err != nil { + Error(w, "seeker can't seek", StatusInternalServerError) + return + } + _, err = content.Seek(0, os.SEEK_SET) + if err != nil { + Error(w, "seeker can't seek", StatusInternalServerError) + return + } + serveContent(w, req, name, modtime, size, content) +} + +// if name is empty, filename is unknown. (used for mime type, before sniffing) +// if modtime.IsZero(), modtime is unknown. +// content must be seeked to the beginning of the file. +func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, size int64, content io.ReadSeeker) { + if checkLastModified(w, r, modtime) { + return + } + + code := StatusOK + + // If Content-Type isn't set, use the file's extension to find it. + if w.Header().Get("Content-Type") == "" { + ctype := mime.TypeByExtension(filepath.Ext(name)) + if ctype == "" { + // read a chunk to decide between utf-8 text and binary + var buf [1024]byte + n, _ := io.ReadFull(content, buf[:]) + b := buf[:n] + ctype = DetectContentType(b) + _, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file + if err != nil { + Error(w, "seeker can't seek", StatusInternalServerError) + return + } + } + w.Header().Set("Content-Type", ctype) + } + + // handle Content-Range header. + // TODO(adg): handle multiple ranges + sendSize := size + if size >= 0 { + ranges, err := parseRange(r.Header.Get("Range"), size) + if err == nil && len(ranges) > 1 { + err = errors.New("multiple ranges not supported") + } + if err != nil { + Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) + return + } + if len(ranges) == 1 { + ra := ranges[0] + if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil { + Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) + return + } + sendSize = ra.length + code = StatusPartialContent + w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", ra.start, ra.start+ra.length-1, size)) + } + + w.Header().Set("Accept-Ranges", "bytes") + if w.Header().Get("Content-Encoding") == "" { + w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10)) + } + } + + w.WriteHeader(code) + + if r.Method != "HEAD" { + if sendSize == -1 { + io.Copy(w, content) + } else { + io.CopyN(w, content, sendSize) + } + } +} + +// modtime is the modification time of the resource to be served, or IsZero(). +// return value is whether this request is now complete. +func checkLastModified(w ResponseWriter, r *Request, modtime time.Time) bool { + if modtime.IsZero() { + return false + } + + // The Date-Modified header truncates sub-second precision, so + // use mtime < t+1s instead of mtime <= t to check for unmodified. + if t, err := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modtime.Before(t.Add(1*time.Second)) { + w.WriteHeader(StatusNotModified) + return true + } + w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat)) + return false +} + // name is '/'-separated, not filepath.Separator. func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) { const indexPage = "/index.html" @@ -148,14 +241,11 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec } } - if t, err := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && !d.ModTime().After(t) { - w.WriteHeader(StatusNotModified) - return - } - w.Header().Set("Last-Modified", d.ModTime().UTC().Format(TimeFormat)) - // use contents of index.html for directory, if present if d.IsDir() { + if checkLastModified(w, r, d.ModTime()) { + return + } index := name + indexPage ff, err := fs.Open(index) if err == nil { @@ -174,60 +264,7 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec return } - // serve file - size := d.Size() - code := StatusOK - - // If Content-Type isn't set, use the file's extension to find it. - if w.Header().Get("Content-Type") == "" { - ctype := mime.TypeByExtension(filepath.Ext(name)) - if ctype == "" { - // read a chunk to decide between utf-8 text and binary - var buf [1024]byte - n, _ := io.ReadFull(f, buf[:]) - b := buf[:n] - if isText(b) { - ctype = "text/plain; charset=utf-8" - } else { - // generic binary - ctype = "application/octet-stream" - } - f.Seek(0, os.SEEK_SET) // rewind to output whole file - } - w.Header().Set("Content-Type", ctype) - } - - // handle Content-Range header. - // TODO(adg): handle multiple ranges - ranges, err := parseRange(r.Header.Get("Range"), size) - if err == nil && len(ranges) > 1 { - err = errors.New("multiple ranges not supported") - } - if err != nil { - Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) - return - } - if len(ranges) == 1 { - ra := ranges[0] - if _, err := f.Seek(ra.start, os.SEEK_SET); err != nil { - Error(w, err.Error(), StatusRequestedRangeNotSatisfiable) - return - } - size = ra.length - code = StatusPartialContent - w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", ra.start, ra.start+ra.length-1, d.Size())) - } - - w.Header().Set("Accept-Ranges", "bytes") - if w.Header().Get("Content-Encoding") == "" { - w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) - } - - w.WriteHeader(code) - - if r.Method != "HEAD" { - io.CopyN(w, f, size) - } + serveContent(w, r, d.Name(), d.ModTime(), d.Size(), f) } // localRedirect gives a Moved Permanently response. diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go index feea9209e6a..5aa93ce5837 100644 --- a/libgo/go/net/http/fs_test.go +++ b/libgo/go/net/http/fs_test.go @@ -5,15 +5,23 @@ package http_test import ( + "bytes" + "errors" "fmt" + "io" "io/ioutil" + "net" . "net/http" "net/http/httptest" "net/url" "os" + "os/exec" "path/filepath" + "regexp" + "runtime" "strings" "testing" + "time" ) const ( @@ -56,18 +64,18 @@ func TestServeFile(t *testing.T) { req.Method = "GET" // straight GET - _, body := getBody(t, req) + _, body := getBody(t, "straight get", req) if !equal(body, file) { t.Fatalf("body mismatch: got %q, want %q", body, file) } // Range tests - for _, rt := range ServeFileRangeTests { + for i, rt := range ServeFileRangeTests { req.Header.Set("Range", "bytes="+rt.r) if rt.r == "" { req.Header["Range"] = nil } - r, body := getBody(t, req) + r, body := getBody(t, fmt.Sprintf("test %d", i), req) if r.StatusCode != rt.code { t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, r.StatusCode, rt.code) } @@ -124,7 +132,7 @@ func TestFileServerCleans(t *testing.T) { ch := make(chan string, 1) fs := FileServer(&testFileSystem{func(name string) (File, error) { ch <- name - return nil, os.ENOENT + return nil, errors.New("file does not exist") }}) tests := []struct { reqPath, openArg string @@ -144,12 +152,19 @@ func TestFileServerCleans(t *testing.T) { } } +func mustRemoveAll(dir string) { + err := os.RemoveAll(dir) + if err != nil { + panic(err) + } +} + func TestFileServerImplicitLeadingSlash(t *testing.T) { tempDir, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("TempDir: %v", err) } - defer os.RemoveAll(tempDir) + defer mustRemoveAll(tempDir) if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil { t.Fatalf("WriteFile: %v", err) } @@ -164,6 +179,7 @@ func TestFileServerImplicitLeadingSlash(t *testing.T) { if err != nil { t.Fatalf("ReadAll %s: %v", suffix, err) } + res.Body.Close() return string(b) } if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") { @@ -298,7 +314,6 @@ func TestServeIndexHtml(t *testing.T) { if err != nil { t.Fatal(err) } - defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatal("reading Body:", err) @@ -306,21 +321,150 @@ func TestServeIndexHtml(t *testing.T) { if s := string(b); s != want { t.Errorf("for path %q got %q, want %q", path, s, want) } + res.Body.Close() } } -func getBody(t *testing.T, req Request) (*Response, []byte) { +func TestServeContent(t *testing.T) { + type req struct { + name string + modtime time.Time + content io.ReadSeeker + } + ch := make(chan req, 1) + ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + p := <-ch + ServeContent(w, r, p.name, p.modtime, p.content) + })) + defer ts.Close() + + css, err := os.Open("testdata/style.css") + if err != nil { + t.Fatal(err) + } + defer css.Close() + + ch <- req{"style.css", time.Time{}, css} + res, err := Get(ts.URL) + if err != nil { + t.Fatal(err) + } + if g, e := res.Header.Get("Content-Type"), "text/css; charset=utf-8"; g != e { + t.Errorf("style.css: content type = %q, want %q", g, e) + } + if g := res.Header.Get("Last-Modified"); g != "" { + t.Errorf("want empty Last-Modified; got %q", g) + } + + fi, err := css.Stat() + if err != nil { + t.Fatal(err) + } + ch <- req{"style.html", fi.ModTime(), css} + res, err = Get(ts.URL) + if err != nil { + t.Fatal(err) + } + if g, e := res.Header.Get("Content-Type"), "text/html; charset=utf-8"; g != e { + t.Errorf("style.html: content type = %q, want %q", g, e) + } + if g := res.Header.Get("Last-Modified"); g == "" { + t.Errorf("want non-empty last-modified") + } +} + +// verifies that sendfile is being used on Linux +func TestLinuxSendfile(t *testing.T) { + if runtime.GOOS != "linux" { + t.Logf("skipping; linux-only test") + return + } + _, err := exec.LookPath("strace") + if err != nil { + t.Logf("skipping; strace not found in path") + return + } + + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + lnf, err := ln.(*net.TCPListener).File() + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + var buf bytes.Buffer + child := exec.Command("strace", "-f", os.Args[0], "-test.run=TestLinuxSendfileChild") + child.ExtraFiles = append(child.ExtraFiles, lnf) + child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...) + child.Stdout = &buf + child.Stderr = &buf + err = child.Start() + if err != nil { + t.Logf("skipping; failed to start straced child: %v", err) + return + } + + res, err := Get(fmt.Sprintf("http://%s/", ln.Addr())) + if err != nil { + t.Fatalf("http client error: %v", err) + } + _, err = io.Copy(ioutil.Discard, res.Body) + if err != nil { + t.Fatalf("client body read error: %v", err) + } + res.Body.Close() + + // Force child to exit cleanly. + Get(fmt.Sprintf("http://%s/quit", ln.Addr())) + child.Wait() + + rx := regexp.MustCompile(`sendfile(64)?\(\d+,\s*\d+,\s*NULL,\s*\d+\)\s*=\s*\d+\s*\n`) + rxResume := regexp.MustCompile(`<\.\.\. sendfile(64)? resumed> \)\s*=\s*\d+\s*\n`) + out := buf.String() + if !rx.MatchString(out) && !rxResume.MatchString(out) { + t.Errorf("no sendfile system call found in:\n%s", out) + } +} + +func getBody(t *testing.T, testName string, req Request) (*Response, []byte) { r, err := DefaultClient.Do(&req) if err != nil { - t.Fatal(req.URL.String(), "send:", err) + t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err) } b, err := ioutil.ReadAll(r.Body) if err != nil { - t.Fatal("reading Body:", err) + t.Fatalf("%s: for URL %q, reading body: %v", testName, req.URL.String(), err) } return r, b } +// TestLinuxSendfileChild isn't a real test. It's used as a helper process +// for TestLinuxSendfile. +func TestLinuxSendfileChild(*testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + defer os.Exit(0) + fd3 := os.NewFile(3, "ephemeral-port-listener") + ln, err := net.FileListener(fd3) + if err != nil { + panic(err) + } + mux := NewServeMux() + mux.Handle("/", FileServer(Dir("testdata"))) + mux.HandleFunc("/quit", func(ResponseWriter, *Request) { + os.Exit(0) + }) + s := &Server{Handler: mux} + err = s.Serve(ln) + if err != nil { + panic(err) + } +} + func equal(a, b []byte) bool { if len(a) != len(b) { return false diff --git a/libgo/go/net/http/httptest/server.go b/libgo/go/net/http/httptest/server.go index 5b02e143d4a..57cf0c9417d 100644 --- a/libgo/go/net/http/httptest/server.go +++ b/libgo/go/net/http/httptest/server.go @@ -13,6 +13,7 @@ import ( "net" "net/http" "os" + "sync" ) // A Server is an HTTP server listening on a system-chosen port on the @@ -25,6 +26,10 @@ type Server struct { // Config may be changed after calling NewUnstartedServer and // before Start or StartTLS. Config *http.Server + + // wg counts the number of outstanding HTTP requests on this server. + // Close blocks until all requests are finished. + wg sync.WaitGroup } // historyListener keeps track of all connections that it's ever @@ -61,7 +66,7 @@ func newLocalListener() net.Listener { // When debugging a particular http server-based test, // this flag lets you run -// gotest -run=BrokenTest -httptest.serve=127.0.0.1:8000 +// go test -run=BrokenTest -httptest.serve=127.0.0.1:8000 // to start the broken server so you can interact with it manually. var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks") @@ -93,9 +98,10 @@ func (s *Server) Start() { } s.Listener = &historyListener{s.Listener, make([]net.Conn, 0)} s.URL = "http://" + s.Listener.Addr().String() + s.wrapHandler() go s.Config.Serve(s.Listener) if *serve != "" { - fmt.Println(os.Stderr, "httptest: serving on", s.URL) + fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL) select {} } } @@ -118,9 +124,21 @@ func (s *Server) StartTLS() { s.Listener = &historyListener{tlsListener, make([]net.Conn, 0)} s.URL = "https://" + s.Listener.Addr().String() + s.wrapHandler() go s.Config.Serve(s.Listener) } +func (s *Server) wrapHandler() { + h := s.Config.Handler + if h == nil { + h = http.DefaultServeMux + } + s.Config.Handler = &waitGroupHandler{ + s: s, + h: h, + } +} + // NewTLSServer starts and returns a new Server using TLS. // The caller should call Close when finished, to shut it down. func NewTLSServer(handler http.Handler) *Server { @@ -129,9 +147,11 @@ func NewTLSServer(handler http.Handler) *Server { return ts } -// Close shuts down the server. +// Close shuts down the server and blocks until all outstanding +// requests on this server have completed. func (s *Server) Close() { s.Listener.Close() + s.wg.Wait() } // CloseClientConnections closes any currently open HTTP connections @@ -146,6 +166,20 @@ func (s *Server) CloseClientConnections() { } } +// waitGroupHandler wraps a handler, incrementing and decrementing a +// sync.WaitGroup on each request, to enable Server.Close to block +// until outstanding requests are finished. +type waitGroupHandler struct { + s *Server + h http.Handler // non-nil +} + +func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.s.wg.Add(1) + defer h.s.wg.Done() // a defer, in case ServeHTTP below panics + h.h.ServeHTTP(w, r) +} + // localhostCert is a PEM-encoded TLS cert with SAN DNS names // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end // of ASN.1 time). diff --git a/libgo/go/net/http/httptest/server_test.go b/libgo/go/net/http/httptest/server_test.go new file mode 100644 index 00000000000..500a9f0b800 --- /dev/null +++ b/libgo/go/net/http/httptest/server_test.go @@ -0,0 +1,29 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package httptest + +import ( + "io/ioutil" + "net/http" + "testing" +) + +func TestServer(t *testing.T) { + ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("hello")) + })) + defer ts.Close() + res, err := http.Get(ts.URL) + if err != nil { + t.Fatal(err) + } + got, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if string(got) != "hello" { + t.Errorf("got %q, want hello", string(got)) + } +} diff --git a/libgo/go/net/http/httputil/dump.go b/libgo/go/net/http/httputil/dump.go index c853066f1cf..892ef4eded0 100644 --- a/libgo/go/net/http/httputil/dump.go +++ b/libgo/go/net/http/httputil/dump.go @@ -12,6 +12,7 @@ import ( "io/ioutil" "net" "net/http" + "net/url" "strings" "time" ) @@ -59,6 +60,19 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { } } + // Since we're using the actual Transport code to write the request, + // switch to http so the Transport doesn't try to do an SSL + // negotiation with our dumpConn and its bytes.Buffer & pipe. + // The wire format for https and http are the same, anyway. + reqSend := req + if req.URL.Scheme == "https" { + reqSend = new(http.Request) + *reqSend = *req + reqSend.URL = new(url.URL) + *reqSend.URL = *req.URL + reqSend.URL.Scheme = "http" + } + // Use the actual Transport code to record what we would send // on the wire, but not using TCP. Use a Transport with a // customer dialer that returns a fake net.Conn that waits @@ -79,7 +93,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { }, } - _, err := t.RoundTrip(req) + _, err := t.RoundTrip(reqSend) req.Body = save if err != nil { diff --git a/libgo/go/net/http/httputil/dump_test.go b/libgo/go/net/http/httputil/dump_test.go index 819efb5847b..5afe9ba74e3 100644 --- a/libgo/go/net/http/httputil/dump_test.go +++ b/libgo/go/net/http/httputil/dump_test.go @@ -71,6 +71,18 @@ var dumpTests = []dumpTest{ "User-Agent: Go http package\r\n" + "Accept-Encoding: gzip\r\n\r\n", }, + + // Test that an https URL doesn't try to do an SSL negotiation + // with a bytes.Buffer and hang with all goroutines not + // runnable. + { + Req: *mustNewRequest("GET", "https://example.com/foo", nil), + + WantDumpOut: "GET /foo HTTP/1.1\r\n" + + "Host: example.com\r\n" + + "User-Agent: Go http package\r\n" + + "Accept-Encoding: gzip\r\n\r\n", + }, } func TestDumpRequest(t *testing.T) { diff --git a/libgo/go/net/http/httputil/persist.go b/libgo/go/net/http/httputil/persist.go index c065ccfb499..507938acac7 100644 --- a/libgo/go/net/http/httputil/persist.go +++ b/libgo/go/net/http/httputil/persist.go @@ -13,12 +13,12 @@ import ( "net" "net/http" "net/textproto" - "os" "sync" ) var ( ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"} + ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"} ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"} ) @@ -191,7 +191,7 @@ func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error { } if sc.c == nil { // connection closed by user in the meantime defer sc.lk.Unlock() - return os.EBADF + return ErrClosed } c := sc.c if sc.nread <= sc.nwritten { @@ -383,7 +383,7 @@ func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error) { // Make sure body is fully consumed, even if user does not call body.Close if lastbody != nil { // body.Close is assumed to be idempotent and multiple calls to - // it should return the error that its first invokation + // it should return the error that its first invocation // returned. err = lastbody.Close() if err != nil { diff --git a/libgo/go/net/http/lex.go b/libgo/go/net/http/lex.go index 93b67e70176..ffb393ccf6a 100644 --- a/libgo/go/net/http/lex.go +++ b/libgo/go/net/http/lex.go @@ -14,14 +14,6 @@ func isSeparator(c byte) bool { return false } -func isSpace(c byte) bool { - switch c { - case ' ', '\t', '\r', '\n': - return true - } - return false -} - func isCtl(c byte) bool { return (0 <= c && c <= 31) || c == 127 } func isChar(c byte) bool { return 0 <= c && c <= 127 } diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go index 21eac4743ac..b8874f35d2f 100644 --- a/libgo/go/net/http/pprof/pprof.go +++ b/libgo/go/net/http/pprof/pprof.go @@ -12,23 +12,34 @@ // The handled paths all begin with /debug/pprof/. // // To use pprof, link this package into your program: -// import _ "http/pprof" +// import _ "net/http/pprof" // // Then use the pprof tool to look at the heap profile: // -// pprof http://localhost:6060/debug/pprof/heap +// go tool pprof http://localhost:6060/debug/pprof/heap // // Or to look at a 30-second CPU profile: // -// pprof http://localhost:6060/debug/pprof/profile +// go tool pprof http://localhost:6060/debug/pprof/profile +// +// Or to view all available profiles: +// +// go tool pprof http://localhost:6060/debug/pprof/ +// +// For a study of the facility in action, visit +// +// http://blog.golang.org/2011/06/profiling-go-programs.html // package pprof import ( "bufio" "bytes" + _ "debug/elf" "fmt" + "html/template" "io" + "log" "net/http" "os" "runtime" @@ -39,9 +50,9 @@ import ( ) func init() { + http.Handle("/debug/pprof/", http.HandlerFunc(Index)) http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline)) http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile)) - http.Handle("/debug/pprof/heap", http.HandlerFunc(Heap)) http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol)) } @@ -53,13 +64,6 @@ func Cmdline(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, strings.Join(os.Args, "\x00")) } -// Heap responds with the pprof-formatted heap profile. -// The package initialization registers it as /debug/pprof/heap. -func Heap(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - pprof.WriteHeapProfile(w) -} - // Profile responds with the pprof-formatted cpu profile. // The package initialization registers it as /debug/pprof/profile. func Profile(w http.ResponseWriter, r *http.Request) { @@ -131,3 +135,61 @@ func Symbol(w http.ResponseWriter, r *http.Request) { w.Write(buf.Bytes()) } + +// Handler returns an HTTP handler that serves the named profile. +func Handler(name string) http.Handler { + return handler(name) +} + +type handler string + +func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + debug, _ := strconv.Atoi(r.FormValue("debug")) + p := pprof.Lookup(string(name)) + if p == nil { + w.WriteHeader(404) + fmt.Fprintf(w, "Unknown profile: %s\n", name) + return + } + p.WriteTo(w, debug) + return +} + +// Index responds with the pprof-formatted profile named by the request. +// For example, "/debug/pprof/heap" serves the "heap" profile. +// Index responds to a request for "/debug/pprof/" with an HTML page +// listing the available profiles. +func Index(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/debug/pprof/") { + name := r.URL.Path[len("/debug/pprof/"):] + if name != "" { + handler(name).ServeHTTP(w, r) + return + } + } + + profiles := pprof.Profiles() + if err := indexTmpl.Execute(w, profiles); err != nil { + log.Print(err) + } +} + +var indexTmpl = template.Must(template.New("index").Parse(`<html> +<head> +<title>/debug/pprof/</title> +</head> +/debug/pprof/<br> +<br> +<body> +profiles:<br> +<table> +{{range .}} +<tr><td align=right>{{.Count}}<td><a href="/debug/pprof/{{.Name}}?debug=1">{{.Name}}</a> +{{end}} +</table> +<br> +<a href="/debug/pprof/goroutine?debug=2">full goroutine stack dump</a><br> +</body> +</html> +`)) diff --git a/libgo/go/net/http/request.go b/libgo/go/net/http/request.go index 0bbec53be71..5277657805d 100644 --- a/libgo/go/net/http/request.go +++ b/libgo/go/net/http/request.go @@ -186,7 +186,7 @@ func (r *Request) Cookies() []*Cookie { return readCookies(r.Header, "") } -var ErrNoCookie = errors.New("http: named cookied not present") +var ErrNoCookie = errors.New("http: named cookie not present") // Cookie returns the named cookie provided in the request or // ErrNoCookie if not found. @@ -486,7 +486,7 @@ func ReadRequest(b *bufio.Reader) (req *Request, err error) { rawurl = "http://" + rawurl } - if req.URL, err = url.ParseRequest(rawurl); err != nil { + if req.URL, err = url.ParseRequestURI(rawurl); err != nil { return nil, err } diff --git a/libgo/go/net/http/response_test.go b/libgo/go/net/http/response_test.go index e5d01698e55..165ec3624a4 100644 --- a/libgo/go/net/http/response_test.go +++ b/libgo/go/net/http/response_test.go @@ -321,9 +321,7 @@ func TestReadResponseCloseInMiddle(t *testing.T) { } if test.compressed { buf.WriteString("Content-Encoding: gzip\r\n") - var err error - wr, err = gzip.NewWriter(wr) - checkErr(err, "gzip.NewWriter") + wr = gzip.NewWriter(wr) } buf.WriteString("\r\n") @@ -337,7 +335,7 @@ func TestReadResponseCloseInMiddle(t *testing.T) { wr.Write(chunk) } if test.compressed { - err := wr.(*gzip.Compressor).Close() + err := wr.(*gzip.Writer).Close() checkErr(err, "compressor close") } if test.chunked { diff --git a/libgo/go/net/http/serve_test.go b/libgo/go/net/http/serve_test.go index e2860c3edcf..b6a6b4c77d1 100644 --- a/libgo/go/net/http/serve_test.go +++ b/libgo/go/net/http/serve_test.go @@ -245,8 +245,7 @@ func TestServerTimeouts(t *testing.T) { fmt.Fprintf(res, "req=%d", reqNum) }) - const second = 1000000000 /* nanos */ - server := &Server{Handler: handler, ReadTimeout: 0.25 * second, WriteTimeout: 0.25 * second} + server := &Server{Handler: handler, ReadTimeout: 250 * time.Millisecond, WriteTimeout: 250 * time.Millisecond} go server.Serve(l) url := fmt.Sprintf("http://%s/", addr) @@ -277,7 +276,7 @@ func TestServerTimeouts(t *testing.T) { if n != 0 || err != io.EOF { t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF) } - if latency < 200*time.Millisecond /* fudge from 0.25 above */ { + if latency < 200*time.Millisecond /* fudge from 250 ms above */ { t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond) } diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go index 288539ba576..fa0df54a236 100644 --- a/libgo/go/net/http/server.go +++ b/libgo/go/net/http/server.go @@ -12,7 +12,6 @@ package http import ( "bufio" "bytes" - "crypto/rand" "crypto/tls" "errors" "fmt" @@ -59,7 +58,9 @@ type ResponseWriter interface { // Write writes the data to the connection as part of an HTTP reply. // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) - // before writing the data. + // before writing the data. If the Header does not contain a + // Content-Type line, Write adds a Content-Type set to the result of passing + // the initial 512 bytes of written data to DetectContentType. Write([]byte) (int, error) // WriteHeader sends an HTTP response header with status code. @@ -833,11 +834,17 @@ func RedirectHandler(url string, code int) Handler { // redirecting any request containing . or .. elements to an // equivalent .- and ..-free URL. type ServeMux struct { - m map[string]Handler + mu sync.RWMutex + m map[string]muxEntry +} + +type muxEntry struct { + explicit bool + h Handler } // NewServeMux allocates and returns a new ServeMux. -func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} } +func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} } // DefaultServeMux is the default ServeMux used by Serve. var DefaultServeMux = NewServeMux() @@ -883,12 +890,28 @@ func (mux *ServeMux) match(path string) Handler { } if h == nil || len(k) > n { n = len(k) - h = v + h = v.h } } return h } +// handler returns the handler to use for the request r. +func (mux *ServeMux) handler(r *Request) Handler { + mux.mu.RLock() + defer mux.mu.RUnlock() + + // Host-specific pattern takes precedence over generic ones + h := mux.match(r.Host + r.URL.Path) + if h == nil { + h = mux.match(r.URL.Path) + } + if h == nil { + h = NotFoundHandler() + } + return h +} + // ServeHTTP dispatches the request to the handler whose // pattern most closely matches the request URL. func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { @@ -898,30 +921,33 @@ func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { w.WriteHeader(StatusMovedPermanently) return } - // Host-specific pattern takes precedence over generic ones - h := mux.match(r.Host + r.URL.Path) - if h == nil { - h = mux.match(r.URL.Path) - } - if h == nil { - h = NotFoundHandler() - } - h.ServeHTTP(w, r) + mux.handler(r).ServeHTTP(w, r) } // Handle registers the handler for the given pattern. +// If a handler already exists for pattern, Handle panics. func (mux *ServeMux) Handle(pattern string, handler Handler) { + mux.mu.Lock() + defer mux.mu.Unlock() + if pattern == "" { panic("http: invalid pattern " + pattern) } + if handler == nil { + panic("http: nil handler") + } + if mux.m[pattern].explicit { + panic("http: multiple registrations for " + pattern) + } - mux.m[pattern] = handler + mux.m[pattern] = muxEntry{explicit: true, h: handler} // Helpful behavior: - // If pattern is /tree/, insert permanent redirect for /tree. + // If pattern is /tree/, insert an implicit permanent redirect for /tree. + // It can be overridden by an explicit registration. n := len(pattern) - if n > 0 && pattern[n-1] == '/' { - mux.m[pattern[0:n-1]] = RedirectHandler(pattern, StatusMovedPermanently) + if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit { + mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(pattern, StatusMovedPermanently)} } } @@ -958,6 +984,7 @@ type Server struct { ReadTimeout time.Duration // maximum duration before timing out read of the request WriteTimeout time.Duration // maximum duration before timing out write of the response MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0 + TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS } // ListenAndServe listens on the TCP network address srv.Addr and then @@ -980,15 +1007,26 @@ func (srv *Server) ListenAndServe() error { // then call srv.Handler to reply to them. func (srv *Server) Serve(l net.Listener) error { defer l.Close() + var tempDelay time.Duration // how long to sleep on accept failure for { rw, e := l.Accept() if e != nil { if ne, ok := e.(net.Error); ok && ne.Temporary() { - log.Printf("http: Accept error: %v", e) + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 + } + if max := 1 * time.Second; tempDelay > max { + tempDelay = max + } + log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay) + time.Sleep(tempDelay) continue } return e } + tempDelay = 0 if srv.ReadTimeout != 0 { rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout)) } @@ -1083,9 +1121,12 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error { if addr == "" { addr = ":https" } - config := &tls.Config{ - Rand: rand.Reader, - NextProtos: []string{"http/1.1"}, + config := &tls.Config{} + if srv.TLSConfig != nil { + *config = *srv.TLSConfig + } + if config.NextProtos == nil { + config.NextProtos = []string{"http/1.1"} } var err error diff --git a/libgo/go/net/http/sniff.go b/libgo/go/net/http/sniff.go index c1c78e2417d..68f519b0542 100644 --- a/libgo/go/net/http/sniff.go +++ b/libgo/go/net/http/sniff.go @@ -9,15 +9,15 @@ import ( "encoding/binary" ) -// Content-type sniffing algorithm. -// References in this file refer to this draft specification: -// http://mimesniff.spec.whatwg.org/ - -// The algorithm prefers to use sniffLen bytes to make its decision. +// The algorithm uses at most sniffLen bytes to make its decision. const sniffLen = 512 -// DetectContentType returns the sniffed Content-Type string -// for the given data. This function always returns a valid MIME type. +// DetectContentType implements the algorithm described +// at http://mimesniff.spec.whatwg.org/ to determine the +// Content-Type of the given data. It considers at most the +// first 512 bytes of data. DetectContentType always returns +// a valid MIME type: if it cannot determine a more specific one, it +// returns "application/octet-stream". func DetectContentType(data []byte) string { if len(data) > sniffLen { data = data[:sniffLen] diff --git a/libgo/go/net/http/sniff_test.go b/libgo/go/net/http/sniff_test.go index 6efa8ce1ca2..8ab72ac23f9 100644 --- a/libgo/go/net/http/sniff_test.go +++ b/libgo/go/net/http/sniff_test.go @@ -129,9 +129,10 @@ func TestSniffWriteSize(t *testing.T) { })) defer ts.Close() for _, size := range []int{0, 1, 200, 600, 999, 1000, 1023, 1024, 512 << 10, 1 << 20} { - _, err := Get(fmt.Sprintf("%s/?size=%d", ts.URL, size)) + res, err := Get(fmt.Sprintf("%s/?size=%d", ts.URL, size)) if err != nil { t.Fatalf("size %d: %v", size, err) } + res.Body.Close() } } diff --git a/libgo/go/net/http/status.go b/libgo/go/net/http/status.go index b6e2d65c6a5..5af0b77c428 100644 --- a/libgo/go/net/http/status.go +++ b/libgo/go/net/http/status.go @@ -43,6 +43,7 @@ const ( StatusUnsupportedMediaType = 415 StatusRequestedRangeNotSatisfiable = 416 StatusExpectationFailed = 417 + StatusTeapot = 418 StatusInternalServerError = 500 StatusNotImplemented = 501 @@ -90,6 +91,7 @@ var statusText = map[int]string{ StatusUnsupportedMediaType: "Unsupported Media Type", StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable", StatusExpectationFailed: "Expectation Failed", + StatusTeapot: "I'm a teapot", StatusInternalServerError: "Internal Server Error", StatusNotImplemented: "Not Implemented", diff --git a/libgo/go/net/http/transfer.go b/libgo/go/net/http/transfer.go index ef9564af9c5..3c8fe7f5b51 100644 --- a/libgo/go/net/http/transfer.go +++ b/libgo/go/net/http/transfer.go @@ -383,7 +383,7 @@ func fixTransferEncoding(requestMethod string, header Header) ([]string, error) // chunked encoding must always come first. for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) - // "identity" encoding is not recored + // "identity" encoding is not recorded if encoding == "identity" { break } diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go index 693215edd4f..09579f8a093 100644 --- a/libgo/go/net/http/transport.go +++ b/libgo/go/net/http/transport.go @@ -76,7 +76,9 @@ type Transport struct { // ProxyFromEnvironment returns the URL of the proxy to use for a // given request, as indicated by the environment variables // $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy). -// Either URL or an error is returned. +// An error is returned if the proxy environment is invalid. +// A nil URL and nil error are returned if no proxy is defined in the +// environment, or a proxy should not be used for the given request. func ProxyFromEnvironment(req *Request) (*url.URL, error) { proxy := getenvEitherCase("HTTP_PROXY") if proxy == "" { @@ -85,16 +87,16 @@ func ProxyFromEnvironment(req *Request) (*url.URL, error) { if !useProxy(canonicalAddr(req.URL)) { return nil, nil } - proxyURL, err := url.ParseRequest(proxy) - if err != nil { - return nil, errors.New("invalid proxy address") - } - if proxyURL.Host == "" { - proxyURL, err = url.ParseRequest("http://" + proxy) - if err != nil { - return nil, errors.New("invalid proxy address") + proxyURL, err := url.Parse(proxy) + if err != nil || proxyURL.Scheme == "" { + if u, err := url.Parse("http://" + proxy); err == nil { + proxyURL = u + err = nil } } + if err != nil { + return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err) + } return proxyURL, nil } @@ -235,15 +237,19 @@ func (cm *connectMethod) proxyAuth() string { return "" } -func (t *Transport) putIdleConn(pconn *persistConn) { +// putIdleConn adds pconn to the list of idle persistent connections awaiting +// a new request. +// If pconn is no longer needed or not in a good state, putIdleConn +// returns false. +func (t *Transport) putIdleConn(pconn *persistConn) bool { t.lk.Lock() defer t.lk.Unlock() if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 { pconn.close() - return + return false } if pconn.isBroken() { - return + return false } key := pconn.cacheKey max := t.MaxIdleConnsPerHost @@ -252,9 +258,10 @@ func (t *Transport) putIdleConn(pconn *persistConn) { } if len(t.idleConn[key]) >= max { pconn.close() - return + return false } t.idleConn[key] = append(t.idleConn[key], pconn) + return true } func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) { @@ -565,7 +572,9 @@ func (pc *persistConn) readLoop() { lastbody = resp.Body waitForBodyRead = make(chan bool) resp.Body.(*bodyEOFSignal).fn = func() { - pc.t.putIdleConn(pc) + if !pc.t.putIdleConn(pc) { + alive = false + } waitForBodyRead <- true } } else { @@ -578,7 +587,9 @@ func (pc *persistConn) readLoop() { // read it (even though it'll just be 0, EOF). lastbody = nil - pc.t.putIdleConn(pc) + if !pc.t.putIdleConn(pc) { + alive = false + } } } diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go index caf81d6e46b..cbb3884f9ea 100644 --- a/libgo/go/net/http/transport_test.go +++ b/libgo/go/net/http/transport_test.go @@ -16,6 +16,8 @@ import ( . "net/http" "net/http/httptest" "net/url" + "os" + "runtime" "strconv" "strings" "testing" @@ -441,11 +443,7 @@ func TestRoundTripGzip(t *testing.T) { } if accept == "gzip" { rw.Header().Set("Content-Encoding", "gzip") - gz, err := gzip.NewWriter(rw) - if err != nil { - t.Errorf("gzip NewWriter: %v", err) - return - } + gz := gzip.NewWriter(rw) gz.Write([]byte(responseBody)) gz.Close() } else { @@ -512,7 +510,7 @@ func TestTransportGzip(t *testing.T) { rw.Header().Set("Content-Length", strconv.Itoa(buf.Len())) }() } - gz, _ := gzip.NewWriter(w) + gz := gzip.NewWriter(w) gz.Write([]byte(testString)) if req.FormValue("body") == "large" { io.CopyN(gz, rand.Reader, nRandBytes) @@ -636,6 +634,70 @@ func TestTransportGzipRecursive(t *testing.T) { } } +// tests that persistent goroutine connections shut down when no longer desired. +func TestTransportPersistConnLeak(t *testing.T) { + gotReqCh := make(chan bool) + unblockCh := make(chan bool) + ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + gotReqCh <- true + <-unblockCh + w.Header().Set("Content-Length", "0") + w.WriteHeader(204) + })) + defer ts.Close() + + tr := &Transport{} + c := &Client{Transport: tr} + + n0 := runtime.NumGoroutine() + + const numReq = 25 + didReqCh := make(chan bool) + for i := 0; i < numReq; i++ { + go func() { + res, err := c.Get(ts.URL) + didReqCh <- true + if err != nil { + t.Errorf("client fetch error: %v", err) + return + } + res.Body.Close() + }() + } + + // Wait for all goroutines to be stuck in the Handler. + for i := 0; i < numReq; i++ { + <-gotReqCh + } + + nhigh := runtime.NumGoroutine() + + // Tell all handlers to unblock and reply. + for i := 0; i < numReq; i++ { + unblockCh <- true + } + + // Wait for all HTTP clients to be done. + for i := 0; i < numReq; i++ { + <-didReqCh + } + + tr.CloseIdleConnections() + time.Sleep(100 * time.Millisecond) + runtime.GC() + runtime.GC() // even more. + nfinal := runtime.NumGoroutine() + + growth := nfinal - n0 + + // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. + // Previously we were leaking one per numReq. + t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) + if int(growth) > 5 { + t.Error("too many new goroutines") + } +} + type fooProto struct{} func (fooProto) RoundTrip(req *Request) (*Response, error) { @@ -666,6 +728,36 @@ func TestTransportAltProto(t *testing.T) { } } +var proxyFromEnvTests = []struct { + env string + wanturl string + wanterr error +}{ + {"127.0.0.1:8080", "http://127.0.0.1:8080", nil}, + {"http://127.0.0.1:8080", "http://127.0.0.1:8080", nil}, + {"https://127.0.0.1:8080", "https://127.0.0.1:8080", nil}, + {"", "<nil>", nil}, +} + +func TestProxyFromEnvironment(t *testing.T) { + os.Setenv("HTTP_PROXY", "") + os.Setenv("http_proxy", "") + os.Setenv("NO_PROXY", "") + os.Setenv("no_proxy", "") + for i, tt := range proxyFromEnvTests { + os.Setenv("HTTP_PROXY", tt.env) + req, _ := NewRequest("GET", "http://example.com", nil) + url, err := ProxyFromEnvironment(req) + if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e { + t.Errorf("%d. got error = %q, want %q", i, g, e) + continue + } + if got := fmt.Sprintf("%s", url); got != tt.wanturl { + t.Errorf("%d. got URL = %q, want %q", i, url, tt.wanturl) + } + } +} + // rgz is a gzip quine that uncompresses to itself. var rgz = []byte{ 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, diff --git a/libgo/go/net/http/triv.go b/libgo/go/net/http/triv.go index 994fc0e32f6..269af0ca3d5 100644 --- a/libgo/go/net/http/triv.go +++ b/libgo/go/net/http/triv.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + package main import ( @@ -106,7 +108,6 @@ func DateServer(rw http.ResponseWriter, req *http.Request) { fmt.Fprintf(rw, "fork/exec: %s\n", err) return } - defer p.Release() io.Copy(rw, r) wait, err := p.Wait(0) if err != nil { diff --git a/libgo/go/net/interface.go b/libgo/go/net/interface.go index 5e7b352ed50..f25d046c171 100644 --- a/libgo/go/net/interface.go +++ b/libgo/go/net/interface.go @@ -6,11 +6,7 @@ package net -import ( - "bytes" - "errors" - "fmt" -) +import "errors" var ( errInvalidInterface = errors.New("net: invalid interface") @@ -20,77 +16,6 @@ var ( errNoSuchMulticastInterface = errors.New("net: no such multicast interface") ) -// A HardwareAddr represents a physical hardware address. -type HardwareAddr []byte - -func (a HardwareAddr) String() string { - var buf bytes.Buffer - for i, b := range a { - if i > 0 { - buf.WriteByte(':') - } - fmt.Fprintf(&buf, "%02x", b) - } - return buf.String() -} - -// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the -// following formats: -// 01:23:45:67:89:ab -// 01:23:45:67:89:ab:cd:ef -// 01-23-45-67-89-ab -// 01-23-45-67-89-ab-cd-ef -// 0123.4567.89ab -// 0123.4567.89ab.cdef -func ParseMAC(s string) (hw HardwareAddr, err error) { - if len(s) < 14 { - goto error - } - - if s[2] == ':' || s[2] == '-' { - if (len(s)+1)%3 != 0 { - goto error - } - n := (len(s) + 1) / 3 - if n != 6 && n != 8 { - goto error - } - hw = make(HardwareAddr, n) - for x, i := 0, 0; i < n; i++ { - var ok bool - if hw[i], ok = xtoi2(s[x:], s[2]); !ok { - goto error - } - x += 3 - } - } else if s[4] == '.' { - if (len(s)+1)%5 != 0 { - goto error - } - n := 2 * (len(s) + 1) / 5 - if n != 6 && n != 8 { - goto error - } - hw = make(HardwareAddr, n) - for x, i := 0, 0; i < n; i += 2 { - var ok bool - if hw[i], ok = xtoi2(s[x:x+2], 0); !ok { - goto error - } - if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok { - goto error - } - x += 5 - } - } else { - goto error - } - return hw, nil - -error: - return nil, errors.New("invalid MAC address: " + s) -} - // Interface represents a mapping between network interface name // and index. It also represents network interface facility // information. diff --git a/libgo/go/net/interface_linux.go b/libgo/go/net/interface_linux.go index 21038c629b1..15c2f3781b1 100644 --- a/libgo/go/net/interface_linux.go +++ b/libgo/go/net/interface_linux.go @@ -166,13 +166,13 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) { return nil, err } } - ifmat4 := parseProcNetIGMP(ifi) - ifmat6 := parseProcNetIGMP6(ifi) + ifmat4 := parseProcNetIGMP("/proc/net/igmp", ifi) + ifmat6 := parseProcNetIGMP6("/proc/net/igmp6", ifi) return append(ifmat4, ifmat6...), nil } -func parseProcNetIGMP(ifi *Interface) []Addr { - fd, err := open("/proc/net/igmp") +func parseProcNetIGMP(path string, ifi *Interface) []Addr { + fd, err := open(path) if err != nil { return nil } @@ -185,23 +185,26 @@ func parseProcNetIGMP(ifi *Interface) []Addr { fd.readLine() // skip first line b := make([]byte, IPv4len) for l, ok := fd.readLine(); ok; l, ok = fd.readLine() { - f := getFields(l) - switch len(f) { - case 4: + f := splitAtBytes(l, " :\r\t\n") + if len(f) < 4 { + continue + } + switch { + case l[0] != ' ' && l[0] != '\t': // new interface line + name = f[1] + case len(f[0]) == 8: if ifi == nil || name == ifi.Name { fmt.Sscanf(f[0], "%08x", &b) ifma := IPAddr{IP: IPv4(b[3], b[2], b[1], b[0])} ifmat = append(ifmat, ifma.toAddr()) } - case 5: - name = f[1] } } return ifmat } -func parseProcNetIGMP6(ifi *Interface) []Addr { - fd, err := open("/proc/net/igmp6") +func parseProcNetIGMP6(path string, ifi *Interface) []Addr { + fd, err := open(path) if err != nil { return nil } @@ -210,7 +213,10 @@ func parseProcNetIGMP6(ifi *Interface) []Addr { var ifmat []Addr b := make([]byte, IPv6len) for l, ok := fd.readLine(); ok; l, ok = fd.readLine() { - f := getFields(l) + f := splitAtBytes(l, " \r\t\n") + if len(f) < 6 { + continue + } if ifi == nil || f[1] == ifi.Name { fmt.Sscanf(f[2], "%32x", &b) ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}} diff --git a/libgo/go/net/interface_test.go b/libgo/go/net/interface_test.go index 4ce01dc9061..0a33bfdb517 100644 --- a/libgo/go/net/interface_test.go +++ b/libgo/go/net/interface_test.go @@ -6,8 +6,6 @@ package net import ( "bytes" - "reflect" - "strings" "testing" ) @@ -31,17 +29,17 @@ func TestInterfaces(t *testing.T) { for _, ifi := range ift { ifxi, err := InterfaceByIndex(ifi.Index) if err != nil { - t.Fatalf("InterfaceByIndex(%#q) failed: %v", ifi.Index, err) + t.Fatalf("InterfaceByIndex(%q) failed: %v", ifi.Index, err) } if !sameInterface(ifxi, &ifi) { - t.Fatalf("InterfaceByIndex(%#q) = %v, want %v", ifi.Index, *ifxi, ifi) + t.Fatalf("InterfaceByIndex(%q) = %v, want %v", ifi.Index, *ifxi, ifi) } ifxn, err := InterfaceByName(ifi.Name) if err != nil { - t.Fatalf("InterfaceByName(%#q) failed: %v", ifi.Name, err) + t.Fatalf("InterfaceByName(%q) failed: %v", ifi.Name, err) } if !sameInterface(ifxn, &ifi) { - t.Fatalf("InterfaceByName(%#q) = %v, want %v", ifi.Name, *ifxn, ifi) + t.Fatalf("InterfaceByName(%q) = %v, want %v", ifi.Name, *ifxn, ifi) } t.Logf("%q: flags %q, ifindex %v, mtu %v\n", ifi.Name, ifi.Flags.String(), ifi.Index, ifi.MTU) t.Logf("\thardware address %q", ifi.HardwareAddr.String()) @@ -96,46 +94,3 @@ func testMulticastAddrs(t *testing.T, ifmat []Addr) { } } } - -var mactests = []struct { - in string - out HardwareAddr - err string -}{ - {"01:23:45:67:89:AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, - {"01-23-45-67-89-AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, - {"0123.4567.89AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, - {"ab:cd:ef:AB:CD:EF", HardwareAddr{0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}, ""}, - {"01.02.03.04.05.06", nil, "invalid MAC address"}, - {"01:02:03:04:05:06:", nil, "invalid MAC address"}, - {"x1:02:03:04:05:06", nil, "invalid MAC address"}, - {"01002:03:04:05:06", nil, "invalid MAC address"}, - {"01:02003:04:05:06", nil, "invalid MAC address"}, - {"01:02:03004:05:06", nil, "invalid MAC address"}, - {"01:02:03:04005:06", nil, "invalid MAC address"}, - {"01:02:03:04:05006", nil, "invalid MAC address"}, - {"01-02:03:04:05:06", nil, "invalid MAC address"}, - {"01:02-03-04-05-06", nil, "invalid MAC address"}, - {"0123:4567:89AF", nil, "invalid MAC address"}, - {"0123-4567-89AF", nil, "invalid MAC address"}, - {"01:23:45:67:89:AB:CD:EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, - {"01-23-45-67-89-AB-CD-EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, - {"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, -} - -func match(err error, s string) bool { - if s == "" { - return err == nil - } - return err != nil && strings.Contains(err.Error(), s) -} - -func TestParseMAC(t *testing.T) { - for _, tt := range mactests { - out, err := ParseMAC(tt.in) - if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) { - t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out, - tt.err) - } - } -} diff --git a/libgo/go/net/ip_test.go b/libgo/go/net/ip_test.go index df647ef73c0..d0e987b85f7 100644 --- a/libgo/go/net/ip_test.go +++ b/libgo/go/net/ip_test.go @@ -6,6 +6,7 @@ package net import ( "bytes" + _ "debug/elf" "reflect" "runtime" "testing" diff --git a/libgo/go/net/ipraw_test.go b/libgo/go/net/ipraw_test.go index f9401c1104e..6136202727c 100644 --- a/libgo/go/net/ipraw_test.go +++ b/libgo/go/net/ipraw_test.go @@ -7,6 +7,7 @@ package net import ( "bytes" "os" + "syscall" "testing" "time" ) @@ -15,7 +16,7 @@ var icmpTests = []struct { net string laddr string raddr string - ipv6 bool + ipv6 bool // test with underlying AF_INET6 socket }{ {"ip4:icmp", "", "127.0.0.1", false}, {"ip6:icmp", "", "::1", true}, @@ -34,15 +35,15 @@ func TestICMP(t *testing.T) { } id := os.Getpid() & 0xffff seqnum++ - echo := newICMPEchoRequest(tt.ipv6, id, seqnum, 128, []byte("Go Go Gadget Ping!!!")) - exchangeICMPEcho(t, tt.net, tt.laddr, tt.raddr, tt.ipv6, echo) + echo := newICMPEchoRequest(tt.net, id, seqnum, 128, []byte("Go Go Gadget Ping!!!")) + exchangeICMPEcho(t, tt.net, tt.laddr, tt.raddr, echo) } } -func exchangeICMPEcho(t *testing.T, net, laddr, raddr string, ipv6 bool, echo []byte) { +func exchangeICMPEcho(t *testing.T, net, laddr, raddr string, echo []byte) { c, err := ListenPacket(net, laddr) if err != nil { - t.Errorf("ListenPacket(%#q, %#q) failed: %v", net, laddr, err) + t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err) return } c.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -50,12 +51,12 @@ func exchangeICMPEcho(t *testing.T, net, laddr, raddr string, ipv6 bool, echo [] ra, err := ResolveIPAddr(net, raddr) if err != nil { - t.Errorf("ResolveIPAddr(%#q, %#q) failed: %v", net, raddr, err) + t.Errorf("ResolveIPAddr(%q, %q) failed: %v", net, raddr, err) return } waitForReady := make(chan bool) - go icmpEchoTransponder(t, net, raddr, ipv6, waitForReady) + go icmpEchoTransponder(t, net, raddr, waitForReady) <-waitForReady _, err = c.WriteTo(echo, ra) @@ -71,11 +72,15 @@ func exchangeICMPEcho(t *testing.T, net, laddr, raddr string, ipv6 bool, echo [] t.Errorf("ReadFrom failed: %v", err) return } - if !ipv6 && reply[0] != ICMP4_ECHO_REPLY { - continue - } - if ipv6 && reply[0] != ICMP6_ECHO_REPLY { - continue + switch c.(*IPConn).fd.family { + case syscall.AF_INET: + if reply[0] != ICMP4_ECHO_REPLY { + continue + } + case syscall.AF_INET6: + if reply[0] != ICMP6_ECHO_REPLY { + continue + } } xid, xseqnum := parseICMPEchoReply(echo) rid, rseqnum := parseICMPEchoReply(reply) @@ -87,11 +92,11 @@ func exchangeICMPEcho(t *testing.T, net, laddr, raddr string, ipv6 bool, echo [] } } -func icmpEchoTransponder(t *testing.T, net, raddr string, ipv6 bool, waitForReady chan bool) { +func icmpEchoTransponder(t *testing.T, net, raddr string, waitForReady chan bool) { c, err := Dial(net, raddr) if err != nil { waitForReady <- true - t.Errorf("Dial(%#q, %#q) failed: %v", net, raddr, err) + t.Errorf("Dial(%q, %q) failed: %v", net, raddr, err) return } c.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -106,18 +111,23 @@ func icmpEchoTransponder(t *testing.T, net, raddr string, ipv6 bool, waitForRead t.Errorf("Read failed: %v", err) return } - if !ipv6 && echo[0] != ICMP4_ECHO_REQUEST { - continue - } - if ipv6 && echo[0] != ICMP6_ECHO_REQUEST { - continue + switch c.(*IPConn).fd.family { + case syscall.AF_INET: + if echo[0] != ICMP4_ECHO_REQUEST { + continue + } + case syscall.AF_INET6: + if echo[0] != ICMP6_ECHO_REQUEST { + continue + } } break } - if !ipv6 { + switch c.(*IPConn).fd.family { + case syscall.AF_INET: echo[0] = ICMP4_ECHO_REPLY - } else { + case syscall.AF_INET6: echo[0] = ICMP6_ECHO_REPLY } @@ -135,11 +145,15 @@ const ( ICMP6_ECHO_REPLY = 129 ) -func newICMPEchoRequest(ipv6 bool, id, seqnum, msglen int, filler []byte) []byte { - if !ipv6 { +func newICMPEchoRequest(net string, id, seqnum, msglen int, filler []byte) []byte { + afnet, _, _ := parseDialNetwork(net) + switch afnet { + case "ip4": return newICMPv4EchoRequest(id, seqnum, msglen, filler) + case "ip6": + return newICMPv6EchoRequest(id, seqnum, msglen, filler) } - return newICMPv6EchoRequest(id, seqnum, msglen, filler) + return nil } func newICMPv4EchoRequest(id, seqnum, msglen int, filler []byte) []byte { diff --git a/libgo/go/net/iprawsock_plan9.go b/libgo/go/net/iprawsock_plan9.go index 382a4402770..43719fc99cd 100644 --- a/libgo/go/net/iprawsock_plan9.go +++ b/libgo/go/net/iprawsock_plan9.go @@ -7,7 +7,7 @@ package net import ( - "os" + "syscall" "time" ) @@ -17,34 +17,34 @@ type IPConn bool // SetDeadline implements the Conn SetDeadline method. func (c *IPConn) SetDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetReadDeadline implements the Conn SetReadDeadline method. func (c *IPConn) SetReadDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *IPConn) SetWriteDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // Implementation of the Conn interface - see Conn for documentation. // Read implements the Conn Read method. func (c *IPConn) Read(b []byte) (int, error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // Write implements the Conn Write method. func (c *IPConn) Write(b []byte) (int, error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // Close closes the IP connection. func (c *IPConn) Close() error { - return os.EPLAN9 + return syscall.EPLAN9 } // LocalAddr returns the local network address. @@ -67,12 +67,12 @@ func (c *IPConn) RemoteAddr() Addr { // Timeout() == true after a fixed time limit; see SetDeadline and // SetReadDeadline. func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { - return 0, nil, os.EPLAN9 + return 0, nil, syscall.EPLAN9 } // ReadFrom implements the PacketConn ReadFrom method. func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { - return 0, nil, os.EPLAN9 + return 0, nil, syscall.EPLAN9 } // WriteToIP writes a IP packet to addr via c, copying the payload from b. @@ -82,18 +82,18 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { // see SetDeadline and SetWriteDeadline. // On packet-oriented connections, write timeouts are rare. func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // WriteTo implements the PacketConn WriteTo method. func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // DialIP connects to the remote address raddr on the network protocol netProto, // which must be "ip", "ip4", or "ip6" followed by a colon and a protocol number or name. func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // ListenIP listens for incoming IP packets addressed to the @@ -101,5 +101,5 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) { // and WriteTo methods can be used to receive and send IP // packets with per-packet addressing. func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go index c34ffeb121d..9caa86985a5 100644 --- a/libgo/go/net/iprawsock_posix.go +++ b/libgo/go/net/iprawsock_posix.go @@ -66,7 +66,7 @@ func (c *IPConn) Read(b []byte) (int, error) { // Write implements the Conn Write method. func (c *IPConn) Write(b []byte) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Write(b) } @@ -74,7 +74,7 @@ func (c *IPConn) Write(b []byte) (int, error) { // Close closes the IP connection. func (c *IPConn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.fd.Close() c.fd = nil @@ -100,7 +100,7 @@ func (c *IPConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *IPConn) SetDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setDeadline(c.fd, t) } @@ -108,7 +108,7 @@ func (c *IPConn) SetDeadline(t time.Time) error { // SetReadDeadline implements the Conn SetReadDeadline method. func (c *IPConn) SetReadDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadDeadline(c.fd, t) } @@ -116,7 +116,7 @@ func (c *IPConn) SetReadDeadline(t time.Time) error { // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *IPConn) SetWriteDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteDeadline(c.fd, t) } @@ -125,7 +125,7 @@ func (c *IPConn) SetWriteDeadline(t time.Time) error { // receive buffer associated with the connection. func (c *IPConn) SetReadBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadBuffer(c.fd, bytes) } @@ -134,7 +134,7 @@ func (c *IPConn) SetReadBuffer(bytes int) error { // transmit buffer associated with the connection. func (c *IPConn) SetWriteBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteBuffer(c.fd, bytes) } @@ -150,7 +150,7 @@ func (c *IPConn) SetWriteBuffer(bytes int) error { // SetReadDeadline. func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } // TODO(cw,rsc): consider using readv if we know the family // type to avoid the header trim/copy @@ -173,7 +173,7 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { // ReadFrom implements the PacketConn ReadFrom method. func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } n, uaddr, err := c.ReadFromIP(b) return n, uaddr.toAddr(), err @@ -187,7 +187,7 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { // On packet-oriented connections, write timeouts are rare. func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } sa, err := addr.sockaddr(c.fd.family) if err != nil { @@ -199,11 +199,11 @@ func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) { // WriteTo implements the PacketConn WriteTo method. func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } a, ok := addr.(*IPAddr) if !ok { - return 0, &OpError{"write", c.fd.net, addr, os.EINVAL} + return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL} } return c.WriteToIP(b, a) } diff --git a/libgo/go/net/ipsock_plan9.go b/libgo/go/net/ipsock_plan9.go index 597b1277544..eab0bf3e899 100644 --- a/libgo/go/net/ipsock_plan9.go +++ b/libgo/go/net/ipsock_plan9.go @@ -10,6 +10,7 @@ import ( "errors" "io" "os" + "syscall" "time" ) @@ -83,7 +84,7 @@ func (c *plan9Conn) ok() bool { return c != nil && c.ctl != nil } // Read implements the Conn Read method. func (c *plan9Conn) Read(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } if c.data == nil { c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0) @@ -102,7 +103,7 @@ func (c *plan9Conn) Read(b []byte) (n int, err error) { // Write implements the Conn Write method. func (c *plan9Conn) Write(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } if c.data == nil { c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0) @@ -116,7 +117,7 @@ func (c *plan9Conn) Write(b []byte) (n int, err error) { // Close closes the connection. func (c *plan9Conn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.ctl.Close() if err != nil { @@ -148,17 +149,17 @@ func (c *plan9Conn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *plan9Conn) SetDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetReadDeadline implements the Conn SetReadDeadline method. func (c *plan9Conn) SetReadDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *plan9Conn) SetWriteDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } func startPlan9(net string, addr Addr) (ctl *os.File, dest, proto, name string, err error) { @@ -280,7 +281,7 @@ func (l *plan9Listener) Accept() (c Conn, err error) { func (l *plan9Listener) Close() error { if l == nil || l.ctl == nil { - return os.EINVAL + return syscall.EINVAL } return l.ctl.Close() } diff --git a/libgo/go/net/ipsock_posix.go b/libgo/go/net/ipsock_posix.go index 3a059f516bc..4841057d6be 100644 --- a/libgo/go/net/ipsock_posix.go +++ b/libgo/go/net/ipsock_posix.go @@ -53,13 +53,13 @@ func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) { } // favoriteAddrFamily returns the appropriate address family to -// the given net, raddr, laddr and mode. At first it figures +// the given net, laddr, raddr and mode. At first it figures // address family out from the net. If mode indicates "listen" // and laddr.(type).IP is nil, it assumes that the user wants to // make a passive connection with wildcard address family, both // INET and INET6, and wildcard address. Otherwise guess: if the // addresses are IPv4 then returns INET, or else returns INET6. -func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int { +func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) int { switch net[len(net)-1] { case '4': return syscall.AF_INET @@ -68,17 +68,20 @@ func favoriteAddrFamily(net string, raddr, laddr sockaddr, mode string) int { } if mode == "listen" { + // Note that OpenBSD allows neither "net.inet6.ip6.v6only" + // change nor IPPROTO_IPV6 level IPV6_V6ONLY socket option + // setting. switch a := laddr.(type) { case *TCPAddr: - if a.IP == nil && supportsIPv6 { + if a.IP == nil && supportsIPv6 && supportsIPv4map { return syscall.AF_INET6 } case *UDPAddr: - if a.IP == nil && supportsIPv6 { + if a.IP == nil && supportsIPv6 && supportsIPv4map { return syscall.AF_INET6 } case *IPAddr: - if a.IP == nil && supportsIPv6 { + if a.IP == nil && supportsIPv6 && supportsIPv4map { return syscall.AF_INET6 } } @@ -102,21 +105,20 @@ type sockaddr interface { } func internetSocket(net string, laddr, raddr sockaddr, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { - var oserr error var la, ra syscall.Sockaddr - family := favoriteAddrFamily(net, raddr, laddr, mode) + family := favoriteAddrFamily(net, laddr, raddr, mode) if laddr != nil { - if la, oserr = laddr.sockaddr(family); oserr != nil { + if la, err = laddr.sockaddr(family); err != nil { goto Error } } if raddr != nil { - if ra, oserr = raddr.sockaddr(family); oserr != nil { + if ra, err = raddr.sockaddr(family); err != nil { goto Error } } - fd, oserr = socket(net, family, sotype, proto, la, ra, toAddr) - if oserr != nil { + fd, err = socket(net, family, sotype, proto, la, ra, toAddr) + if err != nil { goto Error } return fd, nil @@ -126,7 +128,7 @@ Error: if mode == "listen" { addr = laddr } - return nil, &OpError{mode, net, addr, oserr} + return nil, &OpError{mode, net, addr, err} } func ipToSockaddr(family int, ip IP, port int) (syscall.Sockaddr, error) { diff --git a/libgo/go/net/lookup_plan9.go b/libgo/go/net/lookup_plan9.go index c0bb9225a7d..2c698304b21 100644 --- a/libgo/go/net/lookup_plan9.go +++ b/libgo/go/net/lookup_plan9.go @@ -7,6 +7,7 @@ package net import ( "errors" "os" + "syscall" ) func query(filename, query string, bufSize int) (res []string, err error) { @@ -71,11 +72,11 @@ func queryDNS(addr string, typ string) (res []string, err error) { func lookupProtocol(name string) (proto int, err error) { // TODO: Implement this - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } func lookupHost(host string) (addrs []string, err error) { - // Use /net/cs insead of /net/dns because cs knows about + // Use /net/cs instead of /net/dns because cs knows about // host names in local network (e.g. from /lib/ndb/local) lines, err := queryCS("tcp", host, "1") if err != nil { diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index 9a39ca8a1eb..3a61dfb29c2 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -8,14 +8,14 @@ package net import ( - "runtime" + "flag" "testing" ) -var avoidMacFirewall = runtime.GOOS == "darwin" +var testExternal = flag.Bool("external", true, "allow use of external networks during long test") func TestGoogleSRV(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -38,7 +38,7 @@ func TestGoogleSRV(t *testing.T) { } func TestGmailMX(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -52,7 +52,7 @@ func TestGmailMX(t *testing.T) { } func TestGmailTXT(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -66,7 +66,7 @@ func TestGmailTXT(t *testing.T) { } func TestGoogleDNSAddr(t *testing.T) { - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") return } @@ -78,3 +78,40 @@ func TestGoogleDNSAddr(t *testing.T) { t.Errorf("no results") } } + +var revAddrTests = []struct { + Addr string + Reverse string + ErrPrefix string +}{ + {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""}, + {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""}, + {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""}, + {"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""}, + {"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""}, + {"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, + {"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, + {"1.2.3", "", "unrecognized address"}, + {"1.2.3.4.5", "", "unrecognized address"}, + {"1234:567:bcbca::89a:bcde", "", "unrecognized address"}, + {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"}, +} + +func TestReverseAddress(t *testing.T) { + for i, tt := range revAddrTests { + a, err := reverseaddr(tt.Addr) + if len(tt.ErrPrefix) > 0 && err == nil { + t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix) + continue + } + if len(tt.ErrPrefix) == 0 && err != nil { + t.Errorf("#%d: expected <nil>, got %q (error)", i, err) + } + if err != nil && err.(*DNSError).Err != tt.ErrPrefix { + t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err) + } + if a != tt.Reverse { + t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a) + } + } +} diff --git a/libgo/go/net/mac.go b/libgo/go/net/mac.go new file mode 100644 index 00000000000..e0637d00b74 --- /dev/null +++ b/libgo/go/net/mac.go @@ -0,0 +1,84 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// MAC address manipulations + +package net + +import ( + "bytes" + "errors" + "fmt" +) + +// A HardwareAddr represents a physical hardware address. +type HardwareAddr []byte + +func (a HardwareAddr) String() string { + var buf bytes.Buffer + for i, b := range a { + if i > 0 { + buf.WriteByte(':') + } + fmt.Fprintf(&buf, "%02x", b) + } + return buf.String() +} + +// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, or EUI-64 using one of the +// following formats: +// 01:23:45:67:89:ab +// 01:23:45:67:89:ab:cd:ef +// 01-23-45-67-89-ab +// 01-23-45-67-89-ab-cd-ef +// 0123.4567.89ab +// 0123.4567.89ab.cdef +func ParseMAC(s string) (hw HardwareAddr, err error) { + if len(s) < 14 { + goto error + } + + if s[2] == ':' || s[2] == '-' { + if (len(s)+1)%3 != 0 { + goto error + } + n := (len(s) + 1) / 3 + if n != 6 && n != 8 { + goto error + } + hw = make(HardwareAddr, n) + for x, i := 0, 0; i < n; i++ { + var ok bool + if hw[i], ok = xtoi2(s[x:], s[2]); !ok { + goto error + } + x += 3 + } + } else if s[4] == '.' { + if (len(s)+1)%5 != 0 { + goto error + } + n := 2 * (len(s) + 1) / 5 + if n != 6 && n != 8 { + goto error + } + hw = make(HardwareAddr, n) + for x, i := 0, 0; i < n; i += 2 { + var ok bool + if hw[i], ok = xtoi2(s[x:x+2], 0); !ok { + goto error + } + if hw[i+1], ok = xtoi2(s[x+2:], s[4]); !ok { + goto error + } + x += 5 + } + } else { + goto error + } + return hw, nil + +error: + return nil, errors.New("invalid MAC address: " + s) +} diff --git a/libgo/go/net/mac_test.go b/libgo/go/net/mac_test.go new file mode 100644 index 00000000000..3837e740cf9 --- /dev/null +++ b/libgo/go/net/mac_test.go @@ -0,0 +1,54 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import ( + "reflect" + "strings" + "testing" +) + +var mactests = []struct { + in string + out HardwareAddr + err string +}{ + {"01:23:45:67:89:AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, + {"01-23-45-67-89-AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, + {"0123.4567.89AB", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab}, ""}, + {"ab:cd:ef:AB:CD:EF", HardwareAddr{0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef}, ""}, + {"01.02.03.04.05.06", nil, "invalid MAC address"}, + {"01:02:03:04:05:06:", nil, "invalid MAC address"}, + {"x1:02:03:04:05:06", nil, "invalid MAC address"}, + {"01002:03:04:05:06", nil, "invalid MAC address"}, + {"01:02003:04:05:06", nil, "invalid MAC address"}, + {"01:02:03004:05:06", nil, "invalid MAC address"}, + {"01:02:03:04005:06", nil, "invalid MAC address"}, + {"01:02:03:04:05006", nil, "invalid MAC address"}, + {"01-02:03:04:05:06", nil, "invalid MAC address"}, + {"01:02-03-04-05-06", nil, "invalid MAC address"}, + {"0123:4567:89AF", nil, "invalid MAC address"}, + {"0123-4567-89AF", nil, "invalid MAC address"}, + {"01:23:45:67:89:AB:CD:EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, + {"01-23-45-67-89-AB-CD-EF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, + {"0123.4567.89AB.CDEF", HardwareAddr{1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, ""}, +} + +func match(err error, s string) bool { + if s == "" { + return err == nil + } + return err != nil && strings.Contains(err.Error(), s) +} + +func TestParseMAC(t *testing.T) { + for _, tt := range mactests { + out, err := ParseMAC(tt.in) + if !reflect.DeepEqual(out, tt.out) || !match(err, tt.err) { + t.Errorf("ParseMAC(%q) = %v, %v, want %v, %v", tt.in, out, err, tt.out, + tt.err) + } + } +} diff --git a/libgo/go/net/multicast_test.go b/libgo/go/net/multicast_test.go index f62580de66e..1d760c21051 100644 --- a/libgo/go/net/multicast_test.go +++ b/libgo/go/net/multicast_test.go @@ -5,30 +5,46 @@ package net import ( + "errors" "os" "runtime" + "syscall" "testing" ) -var listenMulticastUDPTests = []struct { +var multicastListenerTests = []struct { net string gaddr *UDPAddr flags Flags - ipv6 bool + ipv6 bool // test with underlying AF_INET6 socket }{ // cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers + {"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, - {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, + {"udp", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, 0, false}, {"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp", &UDPAddr{ParseIP("ff0e::114"), 12345}, 0, true}, + + {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, FlagUp | FlagLoopback, false}, + {"udp4", &UDPAddr{IPv4(224, 0, 0, 254), 12345}, 0, false}, + {"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff01::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff02::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff04::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff05::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff08::114"), 12345}, 0, true}, {"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, FlagUp | FlagLoopback, true}, + {"udp6", &UDPAddr{ParseIP("ff0e::114"), 12345}, 0, true}, } -func TestListenMulticastUDP(t *testing.T) { +// TestMulticastListener tests both single and double listen to a test +// listener with same address family, same group address and same port. +func TestMulticastListener(t *testing.T) { switch runtime.GOOS { case "netbsd", "openbsd", "plan9", "windows": return @@ -38,112 +54,142 @@ func TestListenMulticastUDP(t *testing.T) { } } - for _, tt := range listenMulticastUDPTests { + for _, tt := range multicastListenerTests { if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) { continue } - ift, err := Interfaces() + ifi, err := availMulticastInterface(t, tt.flags) if err != nil { - t.Fatalf("Interfaces failed: %v", err) - } - var ifi *Interface - for _, x := range ift { - if x.Flags&tt.flags == tt.flags { - ifi = &x - break - } - } - if ifi == nil { - t.Logf("an appropriate multicast interface not found") - return + continue } - c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + c1, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) if err != nil { - t.Fatalf("ListenMulticastUDP failed: %v", err) + t.Fatalf("First ListenMulticastUDP failed: %v", err) } - defer c.Close() // test to listen concurrently across multiple listeners - if !tt.ipv6 { - testIPv4MulticastSocketOptions(t, c.fd, ifi) - } else { - testIPv6MulticastSocketOptions(t, c.fd, ifi) - } - ifmat, err := ifi.MulticastAddrs() + checkMulticastListener(t, err, c1, tt.gaddr) + c2, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) if err != nil { - t.Fatalf("MulticastAddrs failed: %v", err) - } - var found bool - for _, ifma := range ifmat { - if ifma.(*IPAddr).IP.Equal(tt.gaddr.IP) { - found = true - break - } + t.Fatalf("Second ListenMulticastUDP failed: %v", err) } - if !found { - t.Fatalf("%q not found in RIB", tt.gaddr.String()) + checkMulticastListener(t, err, c2, tt.gaddr) + c2.Close() + switch c1.fd.family { + case syscall.AF_INET: + testIPv4MulticastSocketOptions(t, c1.fd, ifi) + case syscall.AF_INET6: + testIPv6MulticastSocketOptions(t, c1.fd, ifi) } + c1.Close() } } -func TestSimpleListenMulticastUDP(t *testing.T) { +func TestSimpleMulticastListener(t *testing.T) { switch runtime.GOOS { case "plan9": return } - for _, tt := range listenMulticastUDPTests { + for _, tt := range multicastListenerTests { if tt.ipv6 { continue } - tt.flags = FlagUp | FlagMulticast + tt.flags = FlagUp | FlagMulticast // for windows testing + ifi, err := availMulticastInterface(t, tt.flags) + if err != nil { + continue + } + c1, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + if err != nil { + t.Fatalf("First ListenMulticastUDP failed: %v", err) + } + checkSimpleMulticastListener(t, err, c1, tt.gaddr) + c2, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + if err != nil { + t.Fatalf("Second ListenMulticastUDP failed: %v", err) + } + checkSimpleMulticastListener(t, err, c2, tt.gaddr) + c2.Close() + c1.Close() + } +} + +func checkMulticastListener(t *testing.T, err error, c *UDPConn, gaddr *UDPAddr) { + if !multicastRIBContains(t, gaddr.IP) { + t.Fatalf("%q not found in RIB", gaddr.String()) + } + if c.LocalAddr().String() != gaddr.String() { + t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), gaddr.String()) + } +} + +func checkSimpleMulticastListener(t *testing.T, err error, c *UDPConn, gaddr *UDPAddr) { + if c.LocalAddr().String() != gaddr.String() { + t.Fatalf("LocalAddr returns %q, expected %q", c.LocalAddr().String(), gaddr.String()) + } +} + +func availMulticastInterface(t *testing.T, flags Flags) (*Interface, error) { + var ifi *Interface + if flags != Flags(0) { ift, err := Interfaces() if err != nil { t.Fatalf("Interfaces failed: %v", err) } - var ifi *Interface for _, x := range ift { - if x.Flags&tt.flags == tt.flags { + if x.Flags&flags == flags { ifi = &x break } } if ifi == nil { - t.Logf("an appropriate multicast interface not found") - return + return nil, errors.New("an appropriate multicast interface not found") } - c, err := ListenMulticastUDP(tt.net, ifi, tt.gaddr) + } + return ifi, nil +} + +func multicastRIBContains(t *testing.T, ip IP) bool { + ift, err := Interfaces() + if err != nil { + t.Fatalf("Interfaces failed: %v", err) + } + for _, ifi := range ift { + ifmat, err := ifi.MulticastAddrs() if err != nil { - t.Fatalf("ListenMulticastUDP failed: %v", err) + t.Fatalf("MulticastAddrs failed: %v", err) + } + for _, ifma := range ifmat { + if ifma.(*IPAddr).IP.Equal(ip) { + return true + } } - c.Close() } + return false } func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { - ifmc, err := ipv4MulticastInterface(fd) + _, err := ipv4MulticastInterface(fd) if err != nil { t.Fatalf("ipv4MulticastInterface failed: %v", err) } - t.Logf("IPv4 multicast interface: %v", ifmc) - err = setIPv4MulticastInterface(fd, ifi) - if err != nil { - t.Fatalf("setIPv4MulticastInterface failed: %v", err) + if ifi != nil { + err = setIPv4MulticastInterface(fd, ifi) + if err != nil { + t.Fatalf("setIPv4MulticastInterface failed: %v", err) + } } - - ttl, err := ipv4MulticastTTL(fd) + _, err = ipv4MulticastTTL(fd) if err != nil { t.Fatalf("ipv4MulticastTTL failed: %v", err) } - t.Logf("IPv4 multicast TTL: %v", ttl) err = setIPv4MulticastTTL(fd, 1) if err != nil { t.Fatalf("setIPv4MulticastTTL failed: %v", err) } - - loop, err := ipv4MulticastLoopback(fd) + _, err = ipv4MulticastLoopback(fd) if err != nil { t.Fatalf("ipv4MulticastLoopback failed: %v", err) } - t.Logf("IPv4 multicast loopback: %v", loop) err = setIPv4MulticastLoopback(fd, false) if err != nil { t.Fatalf("setIPv4MulticastLoopback failed: %v", err) @@ -151,31 +197,28 @@ func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { } func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) { - ifmc, err := ipv6MulticastInterface(fd) + _, err := ipv6MulticastInterface(fd) if err != nil { t.Fatalf("ipv6MulticastInterface failed: %v", err) } - t.Logf("IPv6 multicast interface: %v", ifmc) - err = setIPv6MulticastInterface(fd, ifi) - if err != nil { - t.Fatalf("setIPv6MulticastInterface failed: %v", err) + if ifi != nil { + err = setIPv6MulticastInterface(fd, ifi) + if err != nil { + t.Fatalf("setIPv6MulticastInterface failed: %v", err) + } } - - hoplim, err := ipv6MulticastHopLimit(fd) + _, err = ipv6MulticastHopLimit(fd) if err != nil { t.Fatalf("ipv6MulticastHopLimit failed: %v", err) } - t.Logf("IPv6 multicast hop limit: %v", hoplim) err = setIPv6MulticastHopLimit(fd, 1) if err != nil { t.Fatalf("setIPv6MulticastHopLimit failed: %v", err) } - - loop, err := ipv6MulticastLoopback(fd) + _, err = ipv6MulticastLoopback(fd) if err != nil { t.Fatalf("ipv6MulticastLoopback failed: %v", err) } - t.Logf("IPv6 multicast loopback: %v", loop) err = setIPv6MulticastLoopback(fd, false) if err != nil { t.Fatalf("setIPv6MulticastLoopback failed: %v", err) diff --git a/libgo/go/net/net.go b/libgo/go/net/net.go index 79d36a2a813..bf242ff8dd6 100644 --- a/libgo/go/net/net.go +++ b/libgo/go/net/net.go @@ -2,8 +2,41 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package net provides a portable interface to Unix networks sockets, -// including TCP/IP, UDP, domain name resolution, and Unix domain sockets. +/* +Package net provides a portable interface for network I/O, including +TCP/IP, UDP, domain name resolution, and Unix domain sockets. + +Although the package provides access to low-level networking +primitives, most clients will need only the basic interface provided +by the Dial, Listen, and Accept functions and the associated +Conn and Listener interfaces. The crypto/tls package uses +the same interfaces and similar Dial and Listen functions. + +The Dial function connects to a server: + + conn, err := net.Dial("tcp", "google.com:80") + if err != nil { + // handle error + } + fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") + status, err := bufio.NewReader(conn).ReadString('\n') + // ... + +The Listen function creates servers: + + ln, err := net.Listen("tcp", ":8080") + if err != nil { + // handle error + } + for { + conn, err := ln.Accept() + if err != nil { + // handle error + continue + } + go handleConnection(conn) + } +*/ package net // TODO(rsc): @@ -42,21 +75,28 @@ type Conn interface { RemoteAddr() Addr // SetDeadline sets the read and write deadlines associated - // with the connection. + // with the connection. It is equivalent to calling both + // SetReadDeadline and SetWriteDeadline. + // + // A deadline is an absolute time after which I/O operations + // fail with a timeout (see type Error) instead of + // blocking. The deadline applies to all future I/O, not just + // the immediately following call to Read or Write. + // + // An idle timeout can be implemented by repeatedly extending + // the deadline after successful Read or Write calls. + // + // A zero value for t means I/O operations will not time out. SetDeadline(t time.Time) error - // SetReadDeadline sets the deadline for all Read calls to return. - // If the deadline is reached, Read will fail with a timeout - // (see type Error) instead of blocking. + // SetReadDeadline sets the deadline for Read calls. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error - // SetWriteDeadline sets the deadline for all Write calls to return. - // If the deadline is reached, Write will fail with a timeout - // (see type Error) instead of blocking. - // A zero value for t means Write will not time out. + // SetWriteDeadline sets the deadline for Write calls. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. + // A zero value for t means Write will not time out. SetWriteDeadline(t time.Time) error } diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go index 1bc997754bb..c1a90de0131 100644 --- a/libgo/go/net/net_test.go +++ b/libgo/go/net/net_test.go @@ -5,129 +5,12 @@ package net import ( - "flag" "io" - "regexp" "runtime" "testing" + "time" ) -var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors") - -type DialErrorTest struct { - Net string - Raddr string - Pattern string -} - -var dialErrorTests = []DialErrorTest{ - { - "datakit", "mh/astro/r70", - "dial datakit mh/astro/r70: unknown network datakit", - }, - { - "tcp", "127.0.0.1:☺", - "dial tcp 127.0.0.1:☺: unknown port tcp/☺", - }, - { - "tcp", "no-such-name.google.com.:80", - "dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)", - }, - { - "tcp", "no-such-name.no-such-top-level-domain.:80", - "dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)", - }, - { - "tcp", "no-such-name:80", - `dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`, - }, - { - "tcp", "mh/astro/r70:http", - "dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name", - }, - { - "unix", "/etc/file-not-found", - "dial unix /etc/file-not-found: [nN]o such file or directory", - }, - { - "unix", "/etc/", - "dial unix /etc/: ([pP]ermission denied|socket operation on non-socket|connection refused)", - }, - { - "unixpacket", "/etc/file-not-found", - "dial unixpacket /etc/file-not-found: no such file or directory", - }, - { - "unixpacket", "/etc/", - "dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)", - }, -} - -var duplicateErrorPattern = `dial (.*) dial (.*)` - -func TestDialError(t *testing.T) { - if !*runErrorTest { - t.Logf("test disabled; use --run_error_test to enable") - return - } - for i, tt := range dialErrorTests { - c, err := Dial(tt.Net, tt.Raddr) - if c != nil { - c.Close() - } - if err == nil { - t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern) - continue - } - s := err.Error() - match, _ := regexp.MatchString(tt.Pattern, s) - if !match { - t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern) - } - match, _ = regexp.MatchString(duplicateErrorPattern, s) - if match { - t.Errorf("#%d: %q, duplicate error return from Dial", i, s) - } - } -} - -var revAddrTests = []struct { - Addr string - Reverse string - ErrPrefix string -}{ - {"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""}, - {"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""}, - {"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""}, - {"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""}, - {"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""}, - {"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, - {"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""}, - {"1.2.3", "", "unrecognized address"}, - {"1.2.3.4.5", "", "unrecognized address"}, - {"1234:567:bcbca::89a:bcde", "", "unrecognized address"}, - {"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"}, -} - -func TestReverseAddress(t *testing.T) { - for i, tt := range revAddrTests { - a, err := reverseaddr(tt.Addr) - if len(tt.ErrPrefix) > 0 && err == nil { - t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix) - continue - } - if len(tt.ErrPrefix) == 0 && err != nil { - t.Errorf("#%d: expected <nil>, got %q (error)", i, err) - } - if err != nil && err.(*DNSError).Err != tt.ErrPrefix { - t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err) - } - if a != tt.Reverse { - t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a) - } - } -} - func TestShutdown(t *testing.T) { if runtime.GOOS == "plan9" { return @@ -173,3 +56,58 @@ func TestShutdown(t *testing.T) { t.Errorf("read = %q, want \"response\"", got) } } + +func TestTCPListenClose(t *testing.T) { + l, err := Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("Listen failed: %v", err) + } + + done := make(chan bool, 1) + go func() { + time.Sleep(100 * time.Millisecond) + l.Close() + }() + go func() { + _, err = l.Accept() + if err == nil { + t.Error("Accept succeeded") + } else { + t.Logf("Accept timeout error: %s (any error is fine)", err) + } + done <- true + }() + select { + case <-done: + case <-time.After(2 * time.Second): + t.Fatal("timeout waiting for TCP close") + } +} + +func TestUDPListenClose(t *testing.T) { + l, err := ListenPacket("udp", "127.0.0.1:0") + if err != nil { + t.Fatalf("Listen failed: %v", err) + } + + buf := make([]byte, 1000) + done := make(chan bool, 1) + go func() { + time.Sleep(100 * time.Millisecond) + l.Close() + }() + go func() { + _, _, err = l.ReadFrom(buf) + if err == nil { + t.Error("ReadFrom succeeded") + } else { + t.Logf("ReadFrom timeout error: %s (any error is fine)", err) + } + done <- true + }() + select { + case <-done: + case <-time.After(2 * time.Second): + t.Fatal("timeout waiting for UDP close") + } +} diff --git a/libgo/go/net/newpollserver.go b/libgo/go/net/newpollserver.go index 06bc24cd8a2..d34bb511f7f 100644 --- a/libgo/go/net/newpollserver.go +++ b/libgo/go/net/newpollserver.go @@ -18,16 +18,16 @@ func newPollServer() (s *pollServer, err error) { if s.pr, s.pw, err = os.Pipe(); err != nil { return nil, err } - if err = syscall.SetNonblock(s.pr.Fd(), true); err != nil { + if err = syscall.SetNonblock(int(s.pr.Fd()), true); err != nil { goto Errno } - if err = syscall.SetNonblock(s.pw.Fd(), true); err != nil { + if err = syscall.SetNonblock(int(s.pw.Fd()), true); err != nil { goto Errno } if s.poll, err = newpollster(); err != nil { goto Error } - if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil { + if _, err = s.poll.AddFD(int(s.pr.Fd()), 'r', true); err != nil { s.poll.Close() goto Error } diff --git a/libgo/go/net/parse.go b/libgo/go/net/parse.go index 4c4200a49b7..7c87b42f6d9 100644 --- a/libgo/go/net/parse.go +++ b/libgo/go/net/parse.go @@ -67,7 +67,7 @@ func open(name string) (*file, error) { if err != nil { return nil, err } - return &file{fd, make([]byte, 1024)[0:0], false}, nil + return &file{fd, make([]byte, os.Getpagesize())[0:0], false}, nil } func byteIndex(s string, c byte) int { diff --git a/libgo/go/net/rpc/client.go b/libgo/go/net/rpc/client.go index 34f9ae317e2..f7abf21f157 100644 --- a/libgo/go/net/rpc/client.go +++ b/libgo/go/net/rpc/client.go @@ -140,7 +140,7 @@ func (client *Client) input() { } client.mutex.Unlock() client.sending.Unlock() - if err != io.EOF || !closing { + if err != io.EOF && !closing { log.Println("rpc: client protocol error:", err) } } diff --git a/libgo/go/net/rpc/server.go b/libgo/go/net/rpc/server.go index 920ae9137a6..1680e2f0d70 100644 --- a/libgo/go/net/rpc/server.go +++ b/libgo/go/net/rpc/server.go @@ -13,13 +13,19 @@ Only methods that satisfy these criteria will be made available for remote access; other methods will be ignored: - - the method name is exported, that is, begins with an upper case letter. - - the method receiver is exported or local (defined in the package - registering the service). - - the method has two arguments, both exported or local types. + - the method is exported. + - the method has two arguments, both exported (or builtin) types. - the method's second argument is a pointer. - the method has return type error. + In effect, the method must look schematically like + + func (t *T) MethodName(argType T1, replyType *T2) error + + where T, T1 and T2 can be marshaled by encoding/gob. + These requirements apply even if a different codec is used. + (In future, these requirements may soften for custom codecs.) + The method's first argument represents the arguments provided by the caller; the second argument represents the result parameters to be returned to the caller. The method's return value, if non-nil, is passed back as a string that the client @@ -36,10 +42,12 @@ call, a pointer containing the arguments, and a pointer to receive the result parameters. - Call waits for the remote call to complete; Go launches the call asynchronously - and returns a channel that will signal completion. + The Call method waits for the remote call to complete while the Go method + launches the call asynchronously and signals completion using the Call + structure's Done channel. - Package "gob" is used to transport the data. + Unless an explicit codec is set up, package encoding/gob is used to + transport the data. Here is a simple example. A server wishes to export an object of type Arith: @@ -256,6 +264,7 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro method := s.typ.Method(m) mtype := method.Type mname := method.Name + // Method must be exported. if method.PkgPath != "" { continue } @@ -267,7 +276,7 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro // First arg need not be a pointer. argType := mtype.In(1) if !isExportedOrBuiltinType(argType) { - log.Println(mname, "argument type not exported or local:", argType) + log.Println(mname, "argument type not exported:", argType) continue } // Second arg must be a pointer. @@ -276,15 +285,17 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro log.Println("method", mname, "reply type not a pointer:", replyType) continue } + // Reply type must be exported. if !isExportedOrBuiltinType(replyType) { - log.Println("method", mname, "reply type not exported or local:", replyType) + log.Println("method", mname, "reply type not exported:", replyType) continue } - // Method needs one out: error. + // Method needs one out. if mtype.NumOut() != 1 { log.Println("method", mname, "has wrong number of outs:", mtype.NumOut()) continue } + // The return type of the method must be error. if returnType := mtype.Out(0); returnType != typeOfError { log.Println("method", mname, "returns", returnType.String(), "not error") continue @@ -301,10 +312,10 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro return nil } -// A value sent as a placeholder for the response when the server receives an invalid request. -type InvalidRequest struct{} - -var invalidRequest = InvalidRequest{} +// A value sent as a placeholder for the server's response value when the server +// receives an invalid request. It is never decoded by the client since the Response +// contains an error when it is used. +var invalidRequest = struct{}{} func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) { resp := server.getResponse() diff --git a/libgo/go/net/rpc/server_test.go b/libgo/go/net/rpc/server_test.go index 8cfa033ccc3..62c7b1e6004 100644 --- a/libgo/go/net/rpc/server_test.go +++ b/libgo/go/net/rpc/server_test.go @@ -387,12 +387,12 @@ func (WriteFailCodec) WriteRequest(*Request, interface{}) error { } func (WriteFailCodec) ReadResponseHeader(*Response) error { - time.Sleep(120 * time.Second) + select {} panic("unreachable") } func (WriteFailCodec) ReadResponseBody(interface{}) error { - time.Sleep(120 * time.Second) + select {} panic("unreachable") } diff --git a/libgo/go/net/sendfile_linux.go b/libgo/go/net/sendfile_linux.go index 7f51519b2ed..a0d53036263 100644 --- a/libgo/go/net/sendfile_linux.go +++ b/libgo/go/net/sendfile_linux.go @@ -38,11 +38,13 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { c.wio.Lock() defer c.wio.Unlock() - c.incref() + if err := c.incref(false); err != nil { + return 0, err, true + } defer c.decref() dst := c.sysfd - src := f.Fd() + src := int(f.Fd()) for remain > 0 { n := maxSendfileSize if int64(n) > remain { @@ -57,8 +59,9 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { break } if err1 == syscall.EAGAIN && c.wdeadline >= 0 { - pollserver.WaitWrite(c) - continue + if err1 = pollserver.WaitWrite(c); err1 == nil { + continue + } } if err1 != nil { // This includes syscall.ENOSYS (no kernel diff --git a/libgo/go/net/sendfile_windows.go b/libgo/go/net/sendfile_windows.go index ee7ff8b98c2..f5a6d8804da 100644 --- a/libgo/go/net/sendfile_windows.go +++ b/libgo/go/net/sendfile_windows.go @@ -50,13 +50,15 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { c.wio.Lock() defer c.wio.Unlock() - c.incref() + if err := c.incref(false); err != nil { + return 0, err, true + } defer c.decref() var o sendfileOp o.Init(c, 'w') o.n = uint32(n) - o.src = f.Fd() + o.src = syscall.Handle(f.Fd()) done, err := iosrv.ExecIO(&o, 0) if err != nil { return 0, err, false diff --git a/libgo/go/net/server_test.go b/libgo/go/net/server_test.go index b0b546be32b..b9862168153 100644 --- a/libgo/go/net/server_test.go +++ b/libgo/go/net/server_test.go @@ -83,7 +83,7 @@ func connect(t *testing.T, network, addr string, isEmpty bool) { } // Send explicit ending for unixpacket. - // Older Linux kernels do stop reads on close. + // Older Linux kernels do not stop reads on close. if network == "unixpacket" { fd.Write([]byte("END")) } @@ -95,7 +95,7 @@ func doTest(t *testing.T, network, listenaddr, dialaddr string) { t.Logf("Test %q %q %q", network, listenaddr, dialaddr) switch listenaddr { case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]": - if testing.Short() || avoidMacFirewall { + if testing.Short() || !*testExternal { t.Logf("skip wildcard listen during short test") return } @@ -115,16 +115,13 @@ func doTest(t *testing.T, network, listenaddr, dialaddr string) { } func TestTCPServer(t *testing.T) { - if runtime.GOOS != "openbsd" { - doTest(t, "tcp", "", "127.0.0.1") - } + doTest(t, "tcp", "", "127.0.0.1") doTest(t, "tcp", "0.0.0.0", "127.0.0.1") doTest(t, "tcp", "127.0.0.1", "127.0.0.1") doTest(t, "tcp4", "", "127.0.0.1") doTest(t, "tcp4", "0.0.0.0", "127.0.0.1") doTest(t, "tcp4", "127.0.0.1", "127.0.0.1") if supportsIPv6 { - doTest(t, "tcp", "", "[::1]") doTest(t, "tcp", "[::]", "[::1]") doTest(t, "tcp", "[::1]", "[::1]") doTest(t, "tcp6", "", "[::1]") diff --git a/libgo/go/net/smtp/smtp.go b/libgo/go/net/smtp/smtp.go index f600cc86482..59f6449f0ab 100644 --- a/libgo/go/net/smtp/smtp.go +++ b/libgo/go/net/smtp/smtp.go @@ -50,15 +50,14 @@ func Dial(addr string) (*Client, error) { // server name to be used when authenticating. func NewClient(conn net.Conn, host string) (*Client, error) { text := textproto.NewConn(conn) - _, msg, err := text.ReadResponse(220) + _, _, err := text.ReadResponse(220) if err != nil { text.Close() return nil, err } c := &Client{Text: text, conn: conn, serverName: host} - if strings.Contains(msg, "ESMTP") { - err = c.ehlo() - } else { + err = c.ehlo() + if err != nil { err = c.helo() } return c, err diff --git a/libgo/go/net/smtp/smtp_test.go b/libgo/go/net/smtp/smtp_test.go index ce887820531..c315d185c9d 100644 --- a/libgo/go/net/smtp/smtp_test.go +++ b/libgo/go/net/smtp/smtp_test.go @@ -8,9 +8,11 @@ import ( "bufio" "bytes" "io" + "net" "net/textproto" "strings" "testing" + "time" ) type authTest struct { @@ -59,9 +61,12 @@ type faker struct { io.ReadWriter } -func (f faker) Close() error { - return nil -} +func (f faker) Close() error { return nil } +func (f faker) LocalAddr() net.Addr { return nil } +func (f faker) RemoteAddr() net.Addr { return nil } +func (f faker) SetDeadline(time.Time) error { return nil } +func (f faker) SetReadDeadline(time.Time) error { return nil } +func (f faker) SetWriteDeadline(time.Time) error { return nil } func TestBasic(t *testing.T) { basicServer = strings.Join(strings.Split(basicServer, "\n"), "\r\n") @@ -180,3 +185,87 @@ Goodbye. . QUIT ` + +func TestNewClient(t *testing.T) { + newClientServer = strings.Join(strings.Split(newClientServer, "\n"), "\r\n") + newClientClient = strings.Join(strings.Split(newClientClient, "\n"), "\r\n") + + var cmdbuf bytes.Buffer + bcmdbuf := bufio.NewWriter(&cmdbuf) + out := func() string { + bcmdbuf.Flush() + return cmdbuf.String() + } + var fake faker + fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClientServer)), bcmdbuf) + c, err := NewClient(fake, "fake.host") + if err != nil { + t.Fatalf("NewClient: %v\n(after %v)", err, out()) + } + if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" { + t.Fatalf("Expected AUTH supported") + } + if ok, _ := c.Extension("DSN"); ok { + t.Fatalf("Shouldn't support DSN") + } + if err := c.Quit(); err != nil { + t.Fatalf("QUIT failed: %s", err) + } + + actualcmds := out() + if newClientClient != actualcmds { + t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClientClient) + } +} + +var newClientServer = `220 hello world +250-mx.google.com at your service +250-SIZE 35651584 +250-AUTH LOGIN PLAIN +250 8BITMIME +221 OK +` + +var newClientClient = `EHLO localhost +QUIT +` + +func TestNewClient2(t *testing.T) { + newClient2Server = strings.Join(strings.Split(newClient2Server, "\n"), "\r\n") + newClient2Client = strings.Join(strings.Split(newClient2Client, "\n"), "\r\n") + + var cmdbuf bytes.Buffer + bcmdbuf := bufio.NewWriter(&cmdbuf) + var fake faker + fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClient2Server)), bcmdbuf) + c, err := NewClient(fake, "fake.host") + if err != nil { + t.Fatalf("NewClient: %v", err) + } + if ok, _ := c.Extension("DSN"); ok { + t.Fatalf("Shouldn't support DSN") + } + if err := c.Quit(); err != nil { + t.Fatalf("QUIT failed: %s", err) + } + + bcmdbuf.Flush() + actualcmds := cmdbuf.String() + if newClient2Client != actualcmds { + t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClient2Client) + } +} + +var newClient2Server = `220 hello world +502 EH? +250-mx.google.com at your service +250-SIZE 35651584 +250-AUTH LOGIN PLAIN +250 8BITMIME +221 OK +` + +var newClient2Client = `EHLO localhost +HELO localhost +QUIT +` diff --git a/libgo/go/net/sock.go b/libgo/go/net/sock.go index 70064c307ef..dc139f04a25 100644 --- a/libgo/go/net/sock.go +++ b/libgo/go/net/sock.go @@ -33,13 +33,14 @@ func socket(net string, f, t, p int, la, ra syscall.Sockaddr, toAddr func(syscal return nil, err } + var bla syscall.Sockaddr if la != nil { - la, err = listenerSockaddr(s, f, la, toAddr) + bla, err = listenerSockaddr(s, f, la, toAddr) if err != nil { closesocket(s) return nil, err } - err = syscall.Bind(s, la) + err = syscall.Bind(s, bla) if err != nil { closesocket(s) return nil, err @@ -61,7 +62,12 @@ func socket(net string, f, t, p int, la, ra syscall.Sockaddr, toAddr func(syscal } sa, _ := syscall.Getsockname(s) - laddr := toAddr(sa) + var laddr Addr + if la != nil && bla != la { + laddr = toAddr(la) + } else { + laddr = toAddr(sa) + } sa, _ = syscall.Getpeername(s) raddr := toAddr(sa) diff --git a/libgo/go/net/sock_bsd.go b/libgo/go/net/sock_bsd.go index 7c693a271f7..2607b04c7bc 100644 --- a/libgo/go/net/sock_bsd.go +++ b/libgo/go/net/sock_bsd.go @@ -38,6 +38,11 @@ func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockadd return la, nil } switch v := a.(type) { + case *TCPAddr, *UnixAddr: + err := setDefaultListenerSockopts(s) + if err != nil { + return nil, err + } case *UDPAddr: if v.IP.IsMulticast() { err := setDefaultMulticastSockopts(s) diff --git a/libgo/go/net/sock_linux.go b/libgo/go/net/sock_linux.go index 0743843bf28..e509d93978b 100644 --- a/libgo/go/net/sock_linux.go +++ b/libgo/go/net/sock_linux.go @@ -32,6 +32,11 @@ func listenerSockaddr(s, f int, la syscall.Sockaddr, toAddr func(syscall.Sockadd return la, nil } switch v := a.(type) { + case *TCPAddr, *UnixAddr: + err := setDefaultListenerSockopts(s) + if err != nil { + return nil, err + } case *UDPAddr: if v.IP.IsMulticast() { err := setDefaultMulticastSockopts(s) diff --git a/libgo/go/net/sock_windows.go b/libgo/go/net/sock_windows.go index 434122c9e46..cce6181c9e5 100644 --- a/libgo/go/net/sock_windows.go +++ b/libgo/go/net/sock_windows.go @@ -19,6 +19,11 @@ func listenerSockaddr(s syscall.Handle, f int, la syscall.Sockaddr, toAddr func( return la, nil } switch v := a.(type) { + case *TCPAddr, *UnixAddr: + err := setDefaultListenerSockopts(s) + if err != nil { + return nil, err + } case *UDPAddr: if v.IP.IsMulticast() { err := setDefaultMulticastSockopts(s) diff --git a/libgo/go/net/sockopt.go b/libgo/go/net/sockopt.go index b5b75a2745a..0a051d7ae3c 100644 --- a/libgo/go/net/sockopt.go +++ b/libgo/go/net/sockopt.go @@ -105,13 +105,17 @@ done: } func setReadBuffer(fd *netFD, bytes int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)) } func setWriteBuffer(fd *netFD, bytes int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)) } @@ -142,25 +146,33 @@ func setDeadline(fd *netFD, t time.Time) error { } func setReuseAddr(fd *netFD, reuse bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse))) } func setDontRoute(fd *netFD, dontroute bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute))) } func setKeepAlive(fd *netFD, keepalive bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))) } func setNoDelay(fd *netFD, noDelay bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay))) } @@ -174,7 +186,9 @@ func setLinger(fd *netFD, sec int) error { l.Onoff = 0 l.Linger = 0 } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l)) } diff --git a/libgo/go/net/sockopt_bsd.go b/libgo/go/net/sockopt_bsd.go index bc764650627..79e0e57e21e 100644 --- a/libgo/go/net/sockopt_bsd.go +++ b/libgo/go/net/sockopt_bsd.go @@ -20,31 +20,20 @@ func setDefaultSockopts(s, f, t int) error { // Note that some operating systems never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } - - if f == syscall.AF_UNIX || - (f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM { - // Allow reuse of recently-used addresses. - err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) - if err != nil { - return os.NewSyscallError("setsockopt", err) - } - - // Allow reuse of recently-used ports. - // This option is supported only in descendants of 4.4BSD, - // to make an effective multicast application and an application - // that requires quick draw possible. - err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1) - if err != nil { - return os.NewSyscallError("setsockopt", err) - } - } - // Allow broadcast. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } + return nil +} +func setDefaultListenerSockopts(s int) error { + // Allow reuse of recently-used addresses. + err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } return nil } @@ -55,6 +44,10 @@ func setDefaultMulticastSockopts(s int) error { if err != nil { return os.NewSyscallError("setsockopt", err) } + // Allow reuse of recently-used ports. + // This option is supported only in descendants of 4.4BSD, + // to make an effective multicast application that requires + // quick draw possible. err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1) if err != nil { return os.NewSyscallError("setsockopt", err) diff --git a/libgo/go/net/sockopt_linux.go b/libgo/go/net/sockopt_linux.go index 67c1dc87a7a..7509c29eecf 100644 --- a/libgo/go/net/sockopt_linux.go +++ b/libgo/go/net/sockopt_linux.go @@ -18,23 +18,20 @@ func setDefaultSockopts(s, f, t int) error { // Note that some operating systems never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } - - if f == syscall.AF_UNIX || - (f == syscall.AF_INET || f == syscall.AF_INET6) && t == syscall.SOCK_STREAM { - // Allow reuse of recently-used addresses. - err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) - if err != nil { - return os.NewSyscallError("setsockopt", err) - } - - } - // Allow broadcast. err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) if err != nil { return os.NewSyscallError("setsockopt", err) } + return nil +} +func setDefaultListenerSockopts(s int) error { + // Allow reuse of recently-used addresses. + err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } return nil } diff --git a/libgo/go/net/sockopt_windows.go b/libgo/go/net/sockopt_windows.go index 842bccc8f40..b18af67d754 100644 --- a/libgo/go/net/sockopt_windows.go +++ b/libgo/go/net/sockopt_windows.go @@ -18,16 +18,18 @@ func setDefaultSockopts(s syscall.Handle, f, t int) error { // Note that some operating systems never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0) } + // Allow broadcast. + syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) + return nil +} +func setDefaultListenerSockopts(s syscall.Handle) error { // Windows will reuse recently-used addresses by default. // SO_REUSEADDR should not be used here, as it allows // a socket to forcibly bind to a port in use by another socket. // This could lead to a non-deterministic behavior, where // connection requests over the port cannot be guaranteed // to be handled by the correct socket. - - // Allow broadcast. - syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) return nil } diff --git a/libgo/go/net/sockoptip.go b/libgo/go/net/sockoptip.go index 90b6f751e1d..1fcad4018cc 100644 --- a/libgo/go/net/sockoptip.go +++ b/libgo/go/net/sockoptip.go @@ -14,17 +14,21 @@ import ( ) func ipv4TOS(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TOS) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv4TOS(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TOS, v) if err != nil { @@ -34,17 +38,21 @@ func setIPv4TOS(fd *netFD, v int) error { } func ipv4TTL(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TTL) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv4TTL(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TTL, v) if err != nil { @@ -58,7 +66,9 @@ func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error { if err := setIPv4MreqToInterface(mreq, ifi); err != nil { return err } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq)) } @@ -68,23 +78,29 @@ func leaveIPv4Group(fd *netFD, ifi *Interface, ip IP) error { if err := setIPv4MreqToInterface(mreq, ifi); err != nil { return err } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)) } func ipv6HopLimit(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv6HopLimit(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, v) if err != nil { @@ -94,7 +110,9 @@ func setIPv6HopLimit(fd *netFD, v int) error { } func ipv6MulticastInterface(fd *netFD) (*Interface, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return nil, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF) if err != nil { @@ -115,7 +133,9 @@ func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error { if ifi != nil { v = ifi.Index } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF, v) if err != nil { @@ -125,17 +145,21 @@ func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error { } func ipv6MulticastHopLimit(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_HOPS) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv6MulticastHopLimit(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_HOPS, v) if err != nil { @@ -145,7 +169,9 @@ func setIPv6MulticastHopLimit(fd *netFD, v int) error { } func ipv6MulticastLoopback(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP) if err != nil { @@ -155,7 +181,9 @@ func ipv6MulticastLoopback(fd *netFD) (bool, error) { } func setIPv6MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP, boolint(v)) if err != nil { @@ -170,7 +198,9 @@ func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error { if ifi != nil { mreq.Interface = uint32(ifi.Index) } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_JOIN_GROUP, mreq)) } @@ -181,7 +211,9 @@ func leaveIPv6Group(fd *netFD, ifi *Interface, ip IP) error { if ifi != nil { mreq.Interface = uint32(ifi.Index) } - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_LEAVE_GROUP, mreq)) } diff --git a/libgo/go/net/sockoptip_bsd.go b/libgo/go/net/sockoptip_bsd.go index 5f7dff248a3..19e2b142e92 100644 --- a/libgo/go/net/sockoptip_bsd.go +++ b/libgo/go/net/sockoptip_bsd.go @@ -14,17 +14,21 @@ import ( ) func ipv4MulticastTTL(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return int(v), nil } func setIPv4MulticastTTL(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, byte(v)) if err != nil { @@ -34,17 +38,21 @@ func setIPv4MulticastTTL(fd *netFD, v int) error { } func ipv6TrafficClass(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv6TrafficClass(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS, v) if err != nil { diff --git a/libgo/go/net/sockoptip_darwin.go b/libgo/go/net/sockoptip_darwin.go index dedfd6f4c3a..52b237c4b8d 100644 --- a/libgo/go/net/sockoptip_darwin.go +++ b/libgo/go/net/sockoptip_darwin.go @@ -12,7 +12,9 @@ import ( ) func ipv4MulticastInterface(fd *netFD) (*Interface, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return nil, err + } defer fd.decref() a, err := syscall.GetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF) if err != nil { @@ -28,7 +30,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } var x [4]byte copy(x[:], ip.To4()) - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err = syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, x) if err != nil { @@ -38,7 +42,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } func ipv4MulticastLoopback(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP) if err != nil { @@ -48,7 +54,9 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v)) if err != nil { @@ -58,7 +66,9 @@ func setIPv4MulticastLoopback(fd *netFD, v bool) error { } func ipv4ReceiveInterface(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF) if err != nil { @@ -68,7 +78,9 @@ func ipv4ReceiveInterface(fd *netFD) (bool, error) { } func setIPv4ReceiveInterface(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF, boolint(v)) if err != nil { diff --git a/libgo/go/net/sockoptip_freebsd.go b/libgo/go/net/sockoptip_freebsd.go index 55f7b1a6025..4a3bc2e82c8 100644 --- a/libgo/go/net/sockoptip_freebsd.go +++ b/libgo/go/net/sockoptip_freebsd.go @@ -12,7 +12,9 @@ import ( ) func ipv4MulticastInterface(fd *netFD) (*Interface, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return nil, err + } defer fd.decref() mreq, err := syscall.GetsockoptIPMreqn(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF) if err != nil { @@ -30,7 +32,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { v = int32(ifi.Index) } mreq := &syscall.IPMreqn{Ifindex: v} - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptIPMreqn(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, mreq) if err != nil { @@ -40,7 +44,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } func ipv4MulticastLoopback(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP) if err != nil { @@ -50,7 +56,9 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v)) if err != nil { @@ -60,7 +68,9 @@ func setIPv4MulticastLoopback(fd *netFD, v bool) error { } func ipv4ReceiveInterface(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF) if err != nil { @@ -70,7 +80,9 @@ func ipv4ReceiveInterface(fd *netFD) (bool, error) { } func setIPv4ReceiveInterface(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF, boolint(v)) if err != nil { diff --git a/libgo/go/net/sockoptip_linux.go b/libgo/go/net/sockoptip_linux.go index 360f8dea60a..169718f14aa 100644 --- a/libgo/go/net/sockoptip_linux.go +++ b/libgo/go/net/sockoptip_linux.go @@ -12,7 +12,9 @@ import ( ) func ipv4MulticastInterface(fd *netFD) (*Interface, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return nil, err + } defer fd.decref() mreq, err := syscall.GetsockoptIPMreqn(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF) if err != nil { @@ -30,7 +32,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { v = int32(ifi.Index) } mreq := &syscall.IPMreqn{Ifindex: v} - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptIPMreqn(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, mreq) if err != nil { @@ -40,7 +44,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } func ipv4MulticastTTL(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL) if err != nil { @@ -50,7 +56,9 @@ func ipv4MulticastTTL(fd *netFD) (int, error) { } func setIPv4MulticastTTL(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, v) if err != nil { @@ -60,7 +68,9 @@ func setIPv4MulticastTTL(fd *netFD, v int) error { } func ipv4MulticastLoopback(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP) if err != nil { @@ -70,7 +80,9 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v)) if err != nil { @@ -80,7 +92,9 @@ func setIPv4MulticastLoopback(fd *netFD, v bool) error { } func ipv4ReceiveInterface(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_PKTINFO) if err != nil { @@ -90,7 +104,9 @@ func ipv4ReceiveInterface(fd *netFD) (bool, error) { } func setIPv4ReceiveInterface(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_PKTINFO, boolint(v)) if err != nil { @@ -100,17 +116,21 @@ func setIPv4ReceiveInterface(fd *netFD, v bool) error { } func ipv6TrafficClass(fd *netFD) (int, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return 0, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS) if err != nil { - return -1, os.NewSyscallError("getsockopt", err) + return 0, os.NewSyscallError("getsockopt", err) } return v, nil } func setIPv6TrafficClass(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS, v) if err != nil { diff --git a/libgo/go/net/sockoptip_netbsd.go b/libgo/go/net/sockoptip_netbsd.go new file mode 100644 index 00000000000..446d92aa343 --- /dev/null +++ b/libgo/go/net/sockoptip_netbsd.go @@ -0,0 +1,39 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// IP-level socket options for NetBSD + +package net + +import "syscall" + +func ipv4MulticastInterface(fd *netFD) (*Interface, error) { + // TODO: Implement this + return nil, syscall.EAFNOSUPPORT +} + +func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { + // TODO: Implement this + return syscall.EAFNOSUPPORT +} + +func ipv4MulticastLoopback(fd *netFD) (bool, error) { + // TODO: Implement this + return false, syscall.EAFNOSUPPORT +} + +func setIPv4MulticastLoopback(fd *netFD, v bool) error { + // TODO: Implement this + return syscall.EAFNOSUPPORT +} + +func ipv4ReceiveInterface(fd *netFD) (bool, error) { + // TODO: Implement this + return false, syscall.EAFNOSUPPORT +} + +func setIPv4ReceiveInterface(fd *netFD, v bool) error { + // TODO: Implement this + return syscall.EAFNOSUPPORT +} diff --git a/libgo/go/net/sockoptip_openbsd.go b/libgo/go/net/sockoptip_openbsd.go index 89b8e459207..f3e42f1a9bc 100644 --- a/libgo/go/net/sockoptip_openbsd.go +++ b/libgo/go/net/sockoptip_openbsd.go @@ -12,7 +12,9 @@ import ( ) func ipv4MulticastInterface(fd *netFD) (*Interface, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return nil, err + } defer fd.decref() a, err := syscall.GetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF) if err != nil { @@ -28,7 +30,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } var x [4]byte copy(x[:], ip.To4()) - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err = syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, x) if err != nil { @@ -38,7 +42,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } func ipv4MulticastLoopback(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP) if err != nil { @@ -48,7 +54,9 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v))) if err != nil { @@ -58,7 +66,9 @@ func setIPv4MulticastLoopback(fd *netFD, v bool) error { } func ipv4ReceiveInterface(fd *netFD) (bool, error) { - fd.incref() + if err := fd.incref(false); err != nil { + return false, err + } defer fd.decref() v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF) if err != nil { @@ -68,7 +78,9 @@ func ipv4ReceiveInterface(fd *netFD) (bool, error) { } func setIPv4ReceiveInterface(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_RECVIF, boolint(v)) if err != nil { diff --git a/libgo/go/net/sockoptip_windows.go b/libgo/go/net/sockoptip_windows.go index a8a9d1c2bfb..b9db3334d5f 100644 --- a/libgo/go/net/sockoptip_windows.go +++ b/libgo/go/net/sockoptip_windows.go @@ -23,7 +23,9 @@ func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { } var x [4]byte copy(x[:], ip.To4()) - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err = syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, x) if err != nil { @@ -38,7 +40,9 @@ func ipv4MulticastTTL(fd *netFD) (int, error) { } func setIPv4MulticastTTL(fd *netFD, v int) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, v) if err != nil { @@ -54,7 +58,9 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - fd.incref() + if err := fd.incref(false); err != nil { + return err + } defer fd.decref() err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v)) if err != nil { diff --git a/libgo/go/net/tcpsock_plan9.go b/libgo/go/net/tcpsock_plan9.go index 128766144dd..35f56966eae 100644 --- a/libgo/go/net/tcpsock_plan9.go +++ b/libgo/go/net/tcpsock_plan9.go @@ -7,7 +7,7 @@ package net import ( - "os" + "syscall" "time" ) @@ -19,35 +19,35 @@ type TCPConn struct { // SetDeadline implements the Conn SetDeadline method. func (c *TCPConn) SetDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetReadDeadline implements the Conn SetReadDeadline method. func (c *TCPConn) SetReadDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *TCPConn) SetWriteDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // CloseRead shuts down the reading side of the TCP connection. // Most callers should just use Close. func (c *TCPConn) CloseRead() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } - return os.EPLAN9 + return syscall.EPLAN9 } // CloseWrite shuts down the writing side of the TCP connection. // Most callers should just use Close. func (c *TCPConn) CloseWrite() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } - return os.EPLAN9 + return syscall.EPLAN9 } // DialTCP connects to the remote address raddr on the network net, diff --git a/libgo/go/net/tcpsock_posix.go b/libgo/go/net/tcpsock_posix.go index 51a5d6f0ed8..e05bc10170e 100644 --- a/libgo/go/net/tcpsock_posix.go +++ b/libgo/go/net/tcpsock_posix.go @@ -9,6 +9,7 @@ package net import ( + "fmt" "io" "os" "syscall" @@ -26,6 +27,11 @@ func sockaddrToTCP(sa syscall.Sockaddr) Addr { return &TCPAddr{sa.Addr[0:], sa.Port} case *syscall.SockaddrInet6: return &TCPAddr{sa.Addr[0:], sa.Port} + default: + if sa != nil { + // Diagnose when we will turn a non-nil sockaddr into a nil. + panic(fmt.Sprintf("unexpected type in sockaddrToTCP: %T", sa)) + } } return nil } @@ -70,7 +76,7 @@ func (c *TCPConn) ok() bool { return c != nil && c.fd != nil } // Read implements the Conn Read method. func (c *TCPConn) Read(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Read(b) } @@ -86,7 +92,7 @@ func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) { // Write implements the Conn Write method. func (c *TCPConn) Write(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Write(b) } @@ -94,7 +100,7 @@ func (c *TCPConn) Write(b []byte) (n int, err error) { // Close closes the TCP connection. func (c *TCPConn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.fd.Close() c.fd = nil @@ -105,7 +111,7 @@ func (c *TCPConn) Close() error { // Most callers should just use Close. func (c *TCPConn) CloseRead() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return c.fd.CloseRead() } @@ -114,7 +120,7 @@ func (c *TCPConn) CloseRead() error { // Most callers should just use Close. func (c *TCPConn) CloseWrite() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return c.fd.CloseWrite() } @@ -138,7 +144,7 @@ func (c *TCPConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *TCPConn) SetDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setDeadline(c.fd, t) } @@ -146,7 +152,7 @@ func (c *TCPConn) SetDeadline(t time.Time) error { // SetReadDeadline implements the Conn SetReadDeadline method. func (c *TCPConn) SetReadDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadDeadline(c.fd, t) } @@ -154,7 +160,7 @@ func (c *TCPConn) SetReadDeadline(t time.Time) error { // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *TCPConn) SetWriteDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteDeadline(c.fd, t) } @@ -163,7 +169,7 @@ func (c *TCPConn) SetWriteDeadline(t time.Time) error { // receive buffer associated with the connection. func (c *TCPConn) SetReadBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadBuffer(c.fd, bytes) } @@ -172,7 +178,7 @@ func (c *TCPConn) SetReadBuffer(bytes int) error { // transmit buffer associated with the connection. func (c *TCPConn) SetWriteBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteBuffer(c.fd, bytes) } @@ -190,7 +196,7 @@ func (c *TCPConn) SetWriteBuffer(bytes int) error { // data to be sent and acknowledged. func (c *TCPConn) SetLinger(sec int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setLinger(c.fd, sec) } @@ -199,7 +205,7 @@ func (c *TCPConn) SetLinger(sec int) error { // keepalive messages on the connection. func (c *TCPConn) SetKeepAlive(keepalive bool) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setKeepAlive(c.fd, keepalive) } @@ -210,7 +216,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error { // that data is sent as soon as possible after a Write. func (c *TCPConn) SetNoDelay(noDelay bool) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setNoDelay(c.fd, noDelay) } @@ -227,13 +233,54 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { if raddr == nil { return nil, &OpError{"dial", net, nil, errMissingAddress} } + fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP) + + // TCP has a rarely used mechanism called a 'simultaneous connection' in + // which Dial("tcp", addr1, addr2) run on the machine at addr1 can + // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine + // at addr2, without either machine executing Listen. If laddr == nil, + // it means we want the kernel to pick an appropriate originating local + // address. Some Linux kernels cycle blindly through a fixed range of + // local ports, regardless of destination port. If a kernel happens to + // pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"), + // then the Dial will succeed, having simultaneously connected to itself. + // This can only happen when we are letting the kernel pick a port (laddr == nil) + // and when there is no listener for the destination address. + // It's hard to argue this is anything other than a kernel bug. If we + // see this happen, rather than expose the buggy effect to users, we + // close the fd and try again. If it happens twice more, we relent and + // use the result. See also: + // http://golang.org/issue/2690 + // http://stackoverflow.com/questions/4949858/ + for i := 0; i < 2 && err == nil && laddr == nil && selfConnect(fd); i++ { + fd.Close() + fd, err = internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP) + } + if err != nil { return nil, err } return newTCPConn(fd), nil } +func selfConnect(fd *netFD) bool { + // The socket constructor can return an fd with raddr nil under certain + // unknown conditions. The errors in the calls there to Getpeername + // are discarded, but we can't catch the problem there because those + // calls are sometimes legally erroneous with a "socket not connected". + // Since this code (selfConnect) is already trying to work around + // a problem, we make sure if this happens we recognize trouble and + // ask the DialTCP routine to try again. + // TODO: try to understand what's really going on. + if fd.laddr == nil || fd.raddr == nil { + return true + } + l := fd.laddr.(*TCPAddr) + r := fd.raddr.(*TCPAddr) + return l.Port == r.Port && l.IP.Equal(r.IP) +} + // TCPListener is a TCP network listener. // Clients should typically use variables of type Listener // instead of assuming TCP. @@ -264,7 +311,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { // and the remote address. func (l *TCPListener) AcceptTCP() (c *TCPConn, err error) { if l == nil || l.fd == nil || l.fd.sysfd < 0 { - return nil, os.EINVAL + return nil, syscall.EINVAL } fd, err := l.fd.accept(sockaddrToTCP) if err != nil { @@ -287,7 +334,7 @@ func (l *TCPListener) Accept() (c Conn, err error) { // Already Accepted connections are not closed. func (l *TCPListener) Close() error { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } return l.fd.Close() } @@ -299,7 +346,7 @@ func (l *TCPListener) Addr() Addr { return l.fd.laddr } // A zero time value disables the deadline. func (l *TCPListener) SetDeadline(t time.Time) error { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } return setDeadline(l.fd, t) } diff --git a/libgo/go/net/testdata/hosts b/libgo/go/net/testdata/hosts new file mode 100644 index 00000000000..b601763898b --- /dev/null +++ b/libgo/go/net/testdata/hosts @@ -0,0 +1,12 @@ +255.255.255.255 broadcasthost +127.0.0.2 odin +127.0.0.3 odin # inline comment +::2 odin +127.1.1.1 thor +# aliases +127.1.1.2 ullr ullrhost +# Bogus entries that must be ignored. +123.123.123 loki +321.321.321.321 +# TODO(yvesj): Should we be able to parse this? From a Darwin system. +fe80::1%lo0 localhost diff --git a/libgo/go/net/testdata/igmp b/libgo/go/net/testdata/igmp new file mode 100644 index 00000000000..5f380a2c7db --- /dev/null +++ b/libgo/go/net/testdata/igmp @@ -0,0 +1,24 @@ +Idx Device : Count Querier Group Users Timer Reporter +1 lo : 1 V3 + 010000E0 1 0:00000000 0 +2 eth0 : 2 V2 + FB0000E0 1 0:00000000 1 + 010000E0 1 0:00000000 0 +3 eth1 : 1 V3 + 010000E0 1 0:00000000 0 +4 eth2 : 1 V3 + 010000E0 1 0:00000000 0 +5 eth0.100 : 2 V3 + FB0000E0 1 0:00000000 0 + 010000E0 1 0:00000000 0 +6 eth0.101 : 2 V3 + FB0000E0 1 0:00000000 0 + 010000E0 1 0:00000000 0 +7 eth0.102 : 2 V3 + FB0000E0 1 0:00000000 0 + 010000E0 1 0:00000000 0 +8 eth0.103 : 2 V3 + FB0000E0 1 0:00000000 0 + 010000E0 1 0:00000000 0 +9 device1tap2: 1 V3 + 010000E0 1 0:00000000 0 diff --git a/libgo/go/net/testdata/igmp6 b/libgo/go/net/testdata/igmp6 new file mode 100644 index 00000000000..6cd5a2d4d9d --- /dev/null +++ b/libgo/go/net/testdata/igmp6 @@ -0,0 +1,18 @@ +1 lo ff020000000000000000000000000001 1 0000000C 0 +2 eth0 ff0200000000000000000001ffac891e 1 00000006 0 +2 eth0 ff020000000000000000000000000001 1 0000000C 0 +3 eth1 ff0200000000000000000001ffac8928 2 00000006 0 +3 eth1 ff020000000000000000000000000001 1 0000000C 0 +4 eth2 ff0200000000000000000001ffac8932 2 00000006 0 +4 eth2 ff020000000000000000000000000001 1 0000000C 0 +5 eth0.100 ff0200000000000000000001ffac891e 1 00000004 0 +5 eth0.100 ff020000000000000000000000000001 1 0000000C 0 +6 pan0 ff020000000000000000000000000001 1 0000000C 0 +7 eth0.101 ff0200000000000000000001ffac891e 1 00000004 0 +7 eth0.101 ff020000000000000000000000000001 1 0000000C 0 +8 eth0.102 ff0200000000000000000001ffac891e 1 00000004 0 +8 eth0.102 ff020000000000000000000000000001 1 0000000C 0 +9 eth0.103 ff0200000000000000000001ffac891e 1 00000004 0 +9 eth0.103 ff020000000000000000000000000001 1 0000000C 0 +10 device1tap2 ff0200000000000000000001ff4cc3a3 1 00000004 0 +10 device1tap2 ff020000000000000000000000000001 1 0000000C 0 diff --git a/libgo/go/net/textproto/reader.go b/libgo/go/net/textproto/reader.go index 862cd536c46..125feb3e885 100644 --- a/libgo/go/net/textproto/reader.go +++ b/libgo/go/net/textproto/reader.go @@ -454,10 +454,14 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) { // Key ends at first colon; must not have spaces. i := bytes.IndexByte(kv, ':') - if i < 0 || bytes.IndexByte(kv[0:i], ' ') >= 0 { + if i < 0 { return m, ProtocolError("malformed MIME header line: " + string(kv)) } - key := CanonicalMIMEHeaderKey(string(kv[0:i])) + key := string(kv[0:i]) + if strings.Index(key, " ") >= 0 { + key = strings.TrimRight(key, " ") + } + key = CanonicalMIMEHeaderKey(key) // Skip initial spaces in value. i++ // skip colon @@ -503,6 +507,11 @@ MustRewrite: a := []byte(s) upper := true for i, v := range a { + if v == ' ' { + a[i] = '-' + upper = true + continue + } if upper && 'a' <= v && v <= 'z' { a[i] = v + 'A' - 'a' } diff --git a/libgo/go/net/textproto/reader_test.go b/libgo/go/net/textproto/reader_test.go index 4d036914801..7c5d16227ff 100644 --- a/libgo/go/net/textproto/reader_test.go +++ b/libgo/go/net/textproto/reader_test.go @@ -164,6 +164,29 @@ func TestLargeReadMIMEHeader(t *testing.T) { } } +// Test that we read slightly-bogus MIME headers seen in the wild, +// with spaces before colons, and spaces in keys. +func TestReadMIMEHeaderNonCompliant(t *testing.T) { + // Invalid HTTP response header as sent by an Axis security + // camera: (this is handled by IE, Firefox, Chrome, curl, etc.) + r := reader("Foo: bar\r\n" + + "Content-Language: en\r\n" + + "SID : 0\r\n" + + "Audio Mode : None\r\n" + + "Privilege : 127\r\n\r\n") + m, err := r.ReadMIMEHeader() + want := MIMEHeader{ + "Foo": {"bar"}, + "Content-Language": {"en"}, + "Sid": {"0"}, + "Audio-Mode": {"None"}, + "Privilege": {"127"}, + } + if !reflect.DeepEqual(m, want) || err != nil { + t.Fatalf("ReadMIMEHeader =\n%v, %v; want:\n%v", m, err, want) + } +} + type readResponseTest struct { in string inCode int diff --git a/libgo/go/net/textproto/textproto.go b/libgo/go/net/textproto/textproto.go index 317ec72b0cc..ad5840cf7da 100644 --- a/libgo/go/net/textproto/textproto.go +++ b/libgo/go/net/textproto/textproto.go @@ -20,6 +20,9 @@ // // Writer, to write dot-encoded text blocks. // +// Conn, a convenient packaging of Reader, Writer, and Pipeline for use +// with a single network connection. +// package textproto import ( diff --git a/libgo/go/net/timeout_test.go b/libgo/go/net/timeout_test.go index bae37c86b2e..ef350f0f946 100644 --- a/libgo/go/net/timeout_test.go +++ b/libgo/go/net/timeout_test.go @@ -40,7 +40,7 @@ func testTimeout(t *testing.T, network, addr string, readFrom bool) { errc <- fmt.Errorf("fd.%s on %s %s did not return 0, timeout: %v, %v", what, network, addr, n, err1) return } - if dt := t1.Sub(t0); dt < 50*time.Millisecond || dt > 250*time.Millisecond { + if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond { errc <- fmt.Errorf("fd.%s on %s %s took %s, expected 0.1s", what, network, addr, dt) return } diff --git a/libgo/go/net/udp_test.go b/libgo/go/net/udp_test.go index 6ba762b1f78..ea5fad41a53 100644 --- a/libgo/go/net/udp_test.go +++ b/libgo/go/net/udp_test.go @@ -38,18 +38,18 @@ func testWriteToConn(t *testing.T, raddr string) { _, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra) if err == nil { - t.Fatal("WriteToUDP should be failed") + t.Fatal("WriteToUDP should fail") } if err != nil && err.(*OpError).Err != ErrWriteToConnected { - t.Fatalf("WriteToUDP should be failed as ErrWriteToConnected: %v", err) + t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err) } _, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra) if err == nil { - t.Fatal("WriteTo should be failed") + t.Fatal("WriteTo should fail") } if err != nil && err.(*OpError).Err != ErrWriteToConnected { - t.Fatalf("WriteTo should be failed as ErrWriteToConnected: %v", err) + t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err) } _, err = c.Write([]byte("Connection-oriented mode socket")) @@ -82,6 +82,6 @@ func testWriteToPacketConn(t *testing.T, raddr string) { _, err = c.(*UDPConn).Write([]byte("Connection-less mode socket")) if err == nil { - t.Fatal("Write should be failed") + t.Fatal("Write should fail") } } diff --git a/libgo/go/net/udpsock_plan9.go b/libgo/go/net/udpsock_plan9.go index f90a5fe9ab8..4f298a42f87 100644 --- a/libgo/go/net/udpsock_plan9.go +++ b/libgo/go/net/udpsock_plan9.go @@ -9,6 +9,7 @@ package net import ( "errors" "os" + "syscall" "time" ) @@ -20,17 +21,17 @@ type UDPConn struct { // SetDeadline implements the Conn SetDeadline method. func (c *UDPConn) SetDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetReadDeadline implements the Conn SetReadDeadline method. func (c *UDPConn) SetReadDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *UDPConn) SetWriteDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // UDP-specific methods. @@ -43,7 +44,7 @@ func (c *UDPConn) SetWriteDeadline(t time.Time) error { // after a fixed time limit; see SetDeadline and SetReadDeadline. func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } if c.data == nil { c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0) @@ -69,7 +70,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { // ReadFrom implements the PacketConn ReadFrom method. func (c *UDPConn) ReadFrom(b []byte) (n int, addr Addr, err error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } return c.ReadFromUDP(b) } @@ -82,7 +83,7 @@ func (c *UDPConn) ReadFrom(b []byte) (n int, addr Addr, err error) { // On packet-oriented connections, write timeouts are rare. func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } if c.data == nil { c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0) @@ -106,11 +107,11 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (n int, err error) { // WriteTo implements the PacketConn WriteTo method. func (c *UDPConn) WriteTo(b []byte, addr Addr) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } a, ok := addr.(*UDPAddr) if !ok { - return 0, &OpError{"write", c.dir, addr, os.EINVAL} + return 0, &OpError{"write", c.dir, addr, syscall.EINVAL} } return c.WriteToUDP(b, a) } @@ -191,5 +192,5 @@ func ListenUDP(net string, laddr *UDPAddr) (c *UDPConn, err error) { // the interface to join. ListenMulticastUDP uses default // multicast interface if ifi is nil. func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } diff --git a/libgo/go/net/udpsock_posix.go b/libgo/go/net/udpsock_posix.go index 6108373568a..1f99dc53867 100644 --- a/libgo/go/net/udpsock_posix.go +++ b/libgo/go/net/udpsock_posix.go @@ -63,7 +63,7 @@ func (c *UDPConn) ok() bool { return c != nil && c.fd != nil } // Read implements the Conn Read method. func (c *UDPConn) Read(b []byte) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Read(b) } @@ -71,7 +71,7 @@ func (c *UDPConn) Read(b []byte) (int, error) { // Write implements the Conn Write method. func (c *UDPConn) Write(b []byte) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Write(b) } @@ -79,7 +79,7 @@ func (c *UDPConn) Write(b []byte) (int, error) { // Close closes the UDP connection. func (c *UDPConn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.fd.Close() c.fd = nil @@ -105,7 +105,7 @@ func (c *UDPConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *UDPConn) SetDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setDeadline(c.fd, t) } @@ -113,7 +113,7 @@ func (c *UDPConn) SetDeadline(t time.Time) error { // SetReadDeadline implements the Conn SetReadDeadline method. func (c *UDPConn) SetReadDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadDeadline(c.fd, t) } @@ -121,7 +121,7 @@ func (c *UDPConn) SetReadDeadline(t time.Time) error { // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *UDPConn) SetWriteDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteDeadline(c.fd, t) } @@ -130,7 +130,7 @@ func (c *UDPConn) SetWriteDeadline(t time.Time) error { // receive buffer associated with the connection. func (c *UDPConn) SetReadBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadBuffer(c.fd, bytes) } @@ -139,7 +139,7 @@ func (c *UDPConn) SetReadBuffer(bytes int) error { // transmit buffer associated with the connection. func (c *UDPConn) SetWriteBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteBuffer(c.fd, bytes) } @@ -154,7 +154,7 @@ func (c *UDPConn) SetWriteBuffer(bytes int) error { // after a fixed time limit; see SetDeadline and SetReadDeadline. func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } n, sa, err := c.fd.ReadFrom(b) switch sa := sa.(type) { @@ -169,7 +169,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { // ReadFrom implements the PacketConn ReadFrom method. func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } n, uaddr, err := c.ReadFromUDP(b) return n, uaddr.toAddr(), err @@ -183,7 +183,7 @@ func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) { // On packet-oriented connections, write timeouts are rare. func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } if c.fd.isConnected { return 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected} @@ -198,11 +198,11 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { // WriteTo implements the PacketConn WriteTo method. func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } a, ok := addr.(*UDPAddr) if !ok { - return 0, &OpError{"write", c.fd.net, addr, os.EINVAL} + return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL} } return c.WriteToUDP(b, a) } @@ -262,7 +262,7 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e return nil, UnknownNetworkError(net) } if gaddr == nil || gaddr.IP == nil { - return nil, &OpError{"listenmulticastudp", "udp", nil, errMissingAddress} + return nil, &OpError{"listenmulticast", net, nil, errMissingAddress} } fd, err := internetSocket(net, gaddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP) if err != nil { diff --git a/libgo/go/net/unixsock_plan9.go b/libgo/go/net/unixsock_plan9.go index 1d9d7578f4f..7b4ae6bd116 100644 --- a/libgo/go/net/unixsock_plan9.go +++ b/libgo/go/net/unixsock_plan9.go @@ -7,7 +7,7 @@ package net import ( - "os" + "syscall" "time" ) @@ -19,17 +19,17 @@ type UnixConn bool // Read implements the Conn Read method. func (c *UnixConn) Read(b []byte) (n int, err error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // Write implements the Conn Write method. func (c *UnixConn) Write(b []byte) (n int, err error) { - return 0, os.EPLAN9 + return 0, syscall.EPLAN9 } // Close closes the Unix domain connection. func (c *UnixConn) Close() error { - return os.EPLAN9 + return syscall.EPLAN9 } // LocalAddr returns the local network address, a *UnixAddr. @@ -47,28 +47,28 @@ func (c *UnixConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *UnixConn) SetDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetReadDeadline implements the Conn SetReadDeadline method. func (c *UnixConn) SetReadDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *UnixConn) SetWriteDeadline(t time.Time) error { - return os.EPLAN9 + return syscall.EPLAN9 } // ReadFrom implements the PacketConn ReadFrom method. func (c *UnixConn) ReadFrom(b []byte) (n int, addr Addr, err error) { - err = os.EPLAN9 + err = syscall.EPLAN9 return } // WriteTo implements the PacketConn WriteTo method. func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) { - err = os.EPLAN9 + err = syscall.EPLAN9 return } @@ -76,7 +76,7 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) { // which must be "unix" or "unixgram". If laddr is not nil, it is used // as the local address for the connection. func DialUnix(net string, laddr, raddr *UnixAddr) (c *UnixConn, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // UnixListener is a Unix domain socket listener. @@ -87,19 +87,19 @@ type UnixListener bool // ListenUnix announces on the Unix domain socket laddr and returns a Unix listener. // Net must be "unix" (stream sockets). func ListenUnix(net string, laddr *UnixAddr) (l *UnixListener, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // Accept implements the Accept method in the Listener interface; // it waits for the next call and returns a generic Conn. func (l *UnixListener) Accept() (c Conn, err error) { - return nil, os.EPLAN9 + return nil, syscall.EPLAN9 } // Close stops listening on the Unix address. // Already accepted connections are not closed. func (l *UnixListener) Close() error { - return os.EPLAN9 + return syscall.EPLAN9 } // Addr returns the listener's network address. diff --git a/libgo/go/net/unixsock_posix.go b/libgo/go/net/unixsock_posix.go index 10b79668511..3a94cf5c5ad 100644 --- a/libgo/go/net/unixsock_posix.go +++ b/libgo/go/net/unixsock_posix.go @@ -59,8 +59,8 @@ func unixSocket(net string, laddr, raddr *UnixAddr, mode string) (fd *netFD, err f = sockaddrToUnixpacket } - fd, oserr := socket(net, syscall.AF_UNIX, sotype, 0, la, ra, f) - if oserr != nil { + fd, err = socket(net, syscall.AF_UNIX, sotype, 0, la, ra, f) + if err != nil { goto Error } return fd, nil @@ -70,7 +70,7 @@ Error: if mode == "listen" { addr = laddr } - return nil, &OpError{Op: mode, Net: net, Addr: addr, Err: oserr} + return nil, &OpError{Op: mode, Net: net, Addr: addr, Err: err} } func sockaddrToUnix(sa syscall.Sockaddr) Addr { @@ -123,7 +123,7 @@ func (c *UnixConn) ok() bool { return c != nil && c.fd != nil } // Read implements the Conn Read method. func (c *UnixConn) Read(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Read(b) } @@ -131,7 +131,7 @@ func (c *UnixConn) Read(b []byte) (n int, err error) { // Write implements the Conn Write method. func (c *UnixConn) Write(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Write(b) } @@ -139,7 +139,7 @@ func (c *UnixConn) Write(b []byte) (n int, err error) { // Close closes the Unix domain connection. func (c *UnixConn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.fd.Close() c.fd = nil @@ -168,7 +168,7 @@ func (c *UnixConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *UnixConn) SetDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setDeadline(c.fd, t) } @@ -176,7 +176,7 @@ func (c *UnixConn) SetDeadline(t time.Time) error { // SetReadDeadline implements the Conn SetReadDeadline method. func (c *UnixConn) SetReadDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadDeadline(c.fd, t) } @@ -184,7 +184,7 @@ func (c *UnixConn) SetReadDeadline(t time.Time) error { // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *UnixConn) SetWriteDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteDeadline(c.fd, t) } @@ -193,7 +193,7 @@ func (c *UnixConn) SetWriteDeadline(t time.Time) error { // receive buffer associated with the connection. func (c *UnixConn) SetReadBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadBuffer(c.fd, bytes) } @@ -202,7 +202,7 @@ func (c *UnixConn) SetReadBuffer(bytes int) error { // transmit buffer associated with the connection. func (c *UnixConn) SetWriteBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteBuffer(c.fd, bytes) } @@ -216,7 +216,7 @@ func (c *UnixConn) SetWriteBuffer(bytes int) error { // see SetDeadline and SetReadDeadline. func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } n, sa, err := c.fd.ReadFrom(b) switch sa := sa.(type) { @@ -229,7 +229,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) { // ReadFrom implements the PacketConn ReadFrom method. func (c *UnixConn) ReadFrom(b []byte) (n int, addr Addr, err error) { if !c.ok() { - return 0, nil, os.EINVAL + return 0, nil, syscall.EINVAL } n, uaddr, err := c.ReadFromUnix(b) return n, uaddr.toAddr(), err @@ -243,10 +243,10 @@ func (c *UnixConn) ReadFrom(b []byte) (n int, addr Addr, err error) { // On packet-oriented connections, write timeouts are rare. func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } if addr.Net != sotypeToNet(c.fd.sotype) { - return 0, os.EAFNOSUPPORT + return 0, syscall.EAFNOSUPPORT } sa := &syscall.SockaddrUnix{Name: addr.Name} return c.fd.WriteTo(b, sa) @@ -255,18 +255,18 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) { // WriteTo implements the PacketConn WriteTo method. func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } a, ok := addr.(*UnixAddr) if !ok { - return 0, &OpError{"write", c.fd.net, addr, os.EINVAL} + return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL} } return c.WriteToUnix(b, a) } func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) { if !c.ok() { - return 0, 0, 0, nil, os.EINVAL + return 0, 0, 0, nil, syscall.EINVAL } n, oobn, flags, sa, err := c.fd.ReadMsg(b, oob) switch sa := sa.(type) { @@ -278,11 +278,11 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) { if !c.ok() { - return 0, 0, os.EINVAL + return 0, 0, syscall.EINVAL } if addr != nil { if addr.Net != sotypeToNet(c.fd.sotype) { - return 0, 0, os.EAFNOSUPPORT + return 0, 0, syscall.EAFNOSUPPORT } sa := &syscall.SockaddrUnix{Name: addr.Name} return c.fd.WriteMsg(b, oob, sa) @@ -339,7 +339,7 @@ func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) { // and the remote address. func (l *UnixListener) AcceptUnix() (*UnixConn, error) { if l == nil || l.fd == nil { - return nil, os.EINVAL + return nil, syscall.EINVAL } fd, err := l.fd.accept(sockaddrToUnix) if err != nil { @@ -363,7 +363,7 @@ func (l *UnixListener) Accept() (c Conn, err error) { // Already accepted connections are not closed. func (l *UnixListener) Close() error { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } // The operating system doesn't clean up @@ -391,7 +391,7 @@ func (l *UnixListener) Addr() Addr { return l.fd.laddr } // A zero time value disables the deadline. func (l *UnixListener) SetDeadline(t time.Time) (err error) { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } return setDeadline(l.fd, t) } diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go index a9ce3b31e24..88ff7ebfef3 100644 --- a/libgo/go/net/url/url.go +++ b/libgo/go/net/url/url.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package URL parses URLs and implements query escaping. +// Package url parses URLs and implements query escaping. // See RFC 3986. package url @@ -321,19 +321,28 @@ func split(s string, c byte, cutc bool) (string, string) { } // Parse parses rawurl into a URL structure. -// The string rawurl is assumed not to have a #fragment suffix. -// (Web browsers strip #fragment before sending the URL to a web server.) // The rawurl may be relative or absolute. func Parse(rawurl string) (url *URL, err error) { - return parse(rawurl, false) + // Cut off #frag + u, frag := split(rawurl, '#', true) + if url, err = parse(u, false); err != nil { + return nil, err + } + if frag == "" { + return url, nil + } + if url.Fragment, err = unescape(frag, encodeFragment); err != nil { + return nil, &Error{"parse", rawurl, err} + } + return url, nil } -// ParseRequest parses rawurl into a URL structure. It assumes that -// rawurl was received from an HTTP request, so the rawurl is interpreted +// ParseRequestURI parses rawurl into a URL structure. It assumes that +// rawurl was received in an HTTP request, so the rawurl is interpreted // only as an absolute URI or an absolute path. // The string rawurl is assumed not to have a #fragment suffix. // (Web browsers strip #fragment before sending the URL to a web server.) -func ParseRequest(rawurl string) (url *URL, err error) { +func ParseRequestURI(rawurl string) (url *URL, err error) { return parse(rawurl, true) } @@ -415,22 +424,6 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) { return } -// ParseWithReference is like Parse but allows a trailing #fragment. -func ParseWithReference(rawurlref string) (url *URL, err error) { - // Cut off #frag - rawurl, frag := split(rawurlref, '#', true) - if url, err = Parse(rawurl); err != nil { - return nil, err - } - if frag == "" { - return url, nil - } - if url.Fragment, err = unescape(frag, encodeFragment); err != nil { - return nil, &Error{"parse", rawurlref, err} - } - return url, nil -} - // String reassembles the URL into a valid URL string. func (u *URL) String() string { // TODO: Rewrite to use bytes.Buffer @@ -589,15 +582,15 @@ func (u *URL) IsAbs() bool { return u.Scheme != "" } -// Parse parses a URL in the context of a base URL. The URL in ref +// Parse parses a URL in the context of the receiver. The provided URL // may be relative or absolute. Parse returns nil, err on parse // failure, otherwise its return value is the same as ResolveReference. -func (base *URL) Parse(ref string) (*URL, error) { +func (u *URL) Parse(ref string) (*URL, error) { refurl, err := Parse(ref) if err != nil { return nil, err } - return base.ResolveReference(refurl), nil + return u.ResolveReference(refurl), nil } // ResolveReference resolves a URI reference to an absolute URI from @@ -606,13 +599,13 @@ func (base *URL) Parse(ref string) (*URL, error) { // URL instance, even if the returned URL is identical to either the // base or reference. If ref is an absolute URL, then ResolveReference // ignores base and returns a copy of ref. -func (base *URL) ResolveReference(ref *URL) *URL { +func (u *URL) ResolveReference(ref *URL) *URL { if ref.IsAbs() { url := *ref return &url } // relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] - url := *base + url := *u url.RawQuery = ref.RawQuery url.Fragment = ref.Fragment if ref.Opaque != "" { @@ -632,7 +625,7 @@ func (base *URL) ResolveReference(ref *URL) *URL { url.Path = ref.Path } else { // The "rel_path" case. - path := resolvePath(base.Path, ref.Path) + path := resolvePath(u.Path, ref.Path) if !strings.HasPrefix(path, "/") { path = "/" + path } diff --git a/libgo/go/net/url/url_test.go b/libgo/go/net/url/url_test.go index 9fe5ff886b7..2d911ed505a 100644 --- a/libgo/go/net/url/url_test.go +++ b/libgo/go/net/url/url_test.go @@ -188,22 +188,6 @@ var urltests = []URLTest{ }, "http://user:password@google.com", }, -} - -var urlnofragtests = []URLTest{ - { - "http://www.google.com/?q=go+language#foo", - &URL{ - Scheme: "http", - Host: "www.google.com", - Path: "/", - RawQuery: "q=go+language#foo", - }, - "", - }, -} - -var urlfragtests = []URLTest{ { "http://www.google.com/?q=go+language#foo", &URL{ @@ -257,12 +241,6 @@ func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests [ func TestParse(t *testing.T) { DoTest(t, Parse, "Parse", urltests) - DoTest(t, Parse, "Parse", urlnofragtests) -} - -func TestParseWithReference(t *testing.T) { - DoTest(t, ParseWithReference, "ParseWithReference", urltests) - DoTest(t, ParseWithReference, "ParseWithReference", urlfragtests) } const pathThatLooksSchemeRelative = "//not.a.user@not.a.host/just/a/path" @@ -281,16 +259,16 @@ var parseRequestUrlTests = []struct { {"../dir/", false}, } -func TestParseRequest(t *testing.T) { +func TestParseRequestURI(t *testing.T) { for _, test := range parseRequestUrlTests { - _, err := ParseRequest(test.url) + _, err := ParseRequestURI(test.url) valid := err == nil if valid != test.expectedValid { t.Errorf("Expected valid=%v for %q; got %v", test.expectedValid, test.url, valid) } } - url, err := ParseRequest(pathThatLooksSchemeRelative) + url, err := ParseRequestURI(pathThatLooksSchemeRelative) if err != nil { t.Fatalf("Unexpected error %v", err) } @@ -319,9 +297,6 @@ func DoTestString(t *testing.T, parse func(string) (*URL, error), name string, t func TestURLString(t *testing.T) { DoTestString(t, Parse, "Parse", urltests) - DoTestString(t, Parse, "Parse", urlnofragtests) - DoTestString(t, ParseWithReference, "ParseWithReference", urltests) - DoTestString(t, ParseWithReference, "ParseWithReference", urlfragtests) } type EscapeTest struct { @@ -538,7 +513,7 @@ var resolveReferenceTests = []struct { func TestResolveReference(t *testing.T) { mustParse := func(url string) *URL { - u, err := ParseWithReference(url) + u, err := Parse(url) if err != nil { t.Fatalf("Expected URL to parse: %q, got error: %v", url, err) } @@ -589,7 +564,7 @@ func TestResolveReference(t *testing.T) { func TestResolveReferenceOpaque(t *testing.T) { mustParse := func(url string) *URL { - u, err := ParseWithReference(url) + u, err := Parse(url) if err != nil { t.Fatalf("Expected URL to parse: %q, got error: %v", url, err) } diff --git a/libgo/go/old/netchan/netchan_test.go b/libgo/go/old/netchan/netchan_test.go index 53f0f787765..9a7c076d59c 100644 --- a/libgo/go/old/netchan/netchan_test.go +++ b/libgo/go/old/netchan/netchan_test.go @@ -291,6 +291,10 @@ func exportLoopback(exp *Exporter, t *testing.T) { // This test checks that channel operations can proceed // even when other concurrent operations are blocked. func TestIndependentSends(t *testing.T) { + if testing.Short() { + t.Logf("disabled test during -short") + return + } exp, imp := pair(t) exportLoopback(exp, t) @@ -378,6 +382,10 @@ const flowCount = 100 // test flow control from exporter to importer. func TestExportFlowControl(t *testing.T) { + if testing.Short() { + t.Logf("disabled test during -short") + return + } exp, imp := pair(t) sendDone := make(chan bool, 1) @@ -394,6 +402,10 @@ func TestExportFlowControl(t *testing.T) { // test flow control from importer to exporter. func TestImportFlowControl(t *testing.T) { + if testing.Short() { + t.Logf("disabled test during -short") + return + } exp, imp := pair(t) ch := make(chan int) diff --git a/libgo/go/os/dir_plan9.go b/libgo/go/os/dir_plan9.go index f2dc15409db..7fa4c7f4449 100644 --- a/libgo/go/os/dir_plan9.go +++ b/libgo/go/os/dir_plan9.go @@ -10,6 +10,9 @@ import ( "syscall" ) +var errShortStat = errors.New("short stat message") +var errBadStat = errors.New("bad stat message format") + func (file *File) readdir(n int) (fi []FileInfo, err error) { // If this file has no dirinfo, create one. if file.dirinfo == nil { @@ -35,7 +38,7 @@ func (file *File) readdir(n int) (fi []FileInfo, err error) { break } if d.nbuf < syscall.STATFIXLEN { - return result, &PathError{"readdir", file.name, Eshortstat} + return result, &PathError{"readdir", file.name, errShortStat} } } @@ -43,7 +46,7 @@ func (file *File) readdir(n int) (fi []FileInfo, err error) { m, _ := gbit16(d.buf[d.bufp:]) m += 2 if m < syscall.STATFIXLEN { - return result, &PathError{"readdir", file.name, Eshortstat} + return result, &PathError{"readdir", file.name, errShortStat} } dir, e := UnmarshalDir(d.buf[d.bufp : d.bufp+int(m)]) if e != nil { @@ -138,7 +141,7 @@ func UnmarshalDir(b []byte) (d *Dir, err error) { n, b = gbit16(b) if int(n) != len(b) { - return nil, Ebadstat + return nil, errBadStat } d = new(Dir) @@ -155,7 +158,7 @@ func UnmarshalDir(b []byte) (d *Dir, err error) { d.Muid, b = gstring(b) if len(b) != 0 { - return nil, Ebadstat + return nil, errBadStat } return d, nil diff --git a/libgo/go/os/doc.go b/libgo/go/os/doc.go index ef857c0429f..6a531e0d74e 100644 --- a/libgo/go/os/doc.go +++ b/libgo/go/os/doc.go @@ -4,6 +4,8 @@ package os +import "time" + // FindProcess looks for a running process by its pid. // The Process it returns can be used to obtain information // about the underlying operating system process. @@ -11,6 +13,76 @@ func FindProcess(pid int) (p *Process, err error) { return findProcess(pid) } +// StartProcess starts a new process with the program, arguments and attributes +// specified by name, argv and attr. +// +// StartProcess is a low-level interface. The os/exec package provides +// higher-level interfaces. +// +// If there is an error, it will be of type *PathError. +func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) { + return startProcess(name, argv, attr) +} + +// Release releases any resources associated with the Process p, +// rendering it unusable in the future. +// Release only needs to be called if Wait is not. +func (p *Process) Release() error { + return p.release() +} + +// Kill causes the Process to exit immediately. +func (p *Process) Kill() error { + return p.kill() +} + +// Wait waits for the Process to exit, and then returns a +// ProcessState describing its status and an error, if any. +// Wait releases any resources associated with the Process. +func (p *Process) Wait() (*ProcessState, error) { + return p.wait() +} + +// Signal sends a signal to the Process. +func (p *Process) Signal(sig Signal) error { + return p.signal(sig) +} + +// UserTime returns the user CPU time of the exited process and its children. +func (p *ProcessState) UserTime() time.Duration { + return p.userTime() +} + +// SystemTime returns the system CPU time of the exited process and its children. +func (p *ProcessState) SystemTime() time.Duration { + return p.systemTime() +} + +// Exited returns whether the program has exited. +func (p *ProcessState) Exited() bool { + return p.exited() +} + +// Success reports whether the program exited successfully, +// such as with exit status 0 on Unix. +func (p *ProcessState) Success() bool { + return p.success() +} + +// Sys returns system-dependent exit information about +// the process. Convert it to the appropriate underlying +// type, such as syscall.WaitStatus on Unix, to access its contents. +func (p *ProcessState) Sys() interface{} { + return p.sys() +} + +// SysUsage returns system-dependent resource usage information about +// the exited process. Convert it to the appropriate underlying +// type, such as *syscall.Rusage on Unix, to access its contents. +func (p *ProcessState) SysUsage() interface{} { + return p.sysUsage() +} + // Hostname returns the host name reported by the kernel. func Hostname() (name string, err error) { return hostname() diff --git a/libgo/go/os/env.go b/libgo/go/os/env.go index 7e3f52502e5..eb265f24138 100644 --- a/libgo/go/os/env.go +++ b/libgo/go/os/env.go @@ -6,10 +6,7 @@ package os -import ( - "errors" - "syscall" -) +import "syscall" // Expand replaces ${var} or $var in the string based on the mapping function. // Invocations of undefined variables are replaced with the empty string. @@ -29,10 +26,10 @@ func Expand(s string, mapping func(string) string) string { return string(buf) + s[i:] } -// ShellExpand replaces ${var} or $var in the string according to the values -// of the operating system's environment variables. References to undefined +// ExpandEnv replaces ${var} or $var in the string according to the values +// of the current environment variables. References to undefined // variables are replaced by the empty string. -func ShellExpand(s string) string { +func ExpandEnv(s string) string { return Expand(s, Getenv) } @@ -77,26 +74,10 @@ func getShellName(s string) (string, int) { return s[:i], i } -// ENOENV is the error indicating that an environment variable does not exist. -var ENOENV = errors.New("no such environment variable") - -// Getenverror retrieves the value of the environment variable named by the key. -// It returns the value and an error, if any. -func Getenverror(key string) (value string, err error) { - if len(key) == 0 { - return "", EINVAL - } - val, found := syscall.Getenv(key) - if !found { - return "", ENOENV - } - return val, nil -} - // Getenv retrieves the value of the environment variable named by the key. // It returns the value, which will be empty if the variable is not present. func Getenv(key string) string { - v, _ := Getenverror(key) + v, _ := syscall.Getenv(key) return v } @@ -115,7 +96,7 @@ func Clearenv() { syscall.Clearenv() } -// Environ returns an array of strings representing the environment, +// Environ returns a copy of strings representing the environment, // in the form "key=value". func Environ() []string { return syscall.Environ() diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go index c3dd06feb7b..e0b83b5c22c 100644 --- a/libgo/go/os/error.go +++ b/libgo/go/os/error.go @@ -4,6 +4,18 @@ package os +import ( + "errors" +) + +// Portable analogs of some common system call errors. +var ( + ErrInvalid = errors.New("invalid argument") + ErrPermission = errors.New("permission denied") + ErrExist = errors.New("file already exists") + ErrNotExist = errors.New("file does not exist") +) + // PathError records an error and the operation and file path that caused it. type PathError struct { Op string @@ -12,3 +24,21 @@ type PathError struct { } func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() } + +// SyscallError records an error from a specific system call. +type SyscallError struct { + Syscall string + Err error +} + +func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() } + +// NewSyscallError returns, as an error, a new SyscallError +// with the given system call name and error details. +// As a convenience, if err is nil, NewSyscallError returns nil. +func NewSyscallError(syscall string, err error) error { + if err == nil { + return nil + } + return &SyscallError{syscall, err} +} diff --git a/libgo/go/os/error_plan9.go b/libgo/go/os/error_plan9.go index 3c727b2ab39..159d685e7cd 100644 --- a/libgo/go/os/error_plan9.go +++ b/libgo/go/os/error_plan9.go @@ -4,52 +4,38 @@ package os -import ( - "errors" - "syscall" -) - -// SyscallError records an error from a specific system call. -type SyscallError struct { - Syscall string - Err string +// IsExist returns whether the error is known to report that a file already exists. +func IsExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return contains(err.Error(), " exists") } -func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err } - -// NewSyscallError returns, as an error, a new SyscallError -// with the given system call name and error details. -// As a convenience, if err is nil, NewSyscallError returns nil. -func NewSyscallError(syscall string, err error) error { - if err == nil { - return nil +// IsNotExist returns whether the error is known to report that a file does not exist. +func IsNotExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err } - return &SyscallError{syscall, err.Error()} + return contains(err.Error(), "does not exist") } -var ( - Eshortstat = errors.New("stat buffer too small") - Ebadstat = errors.New("malformed stat buffer") - Ebadfd = errors.New("fd out of range or not open") - Ebadarg = errors.New("bad arg in system call") - Enotdir = errors.New("not a directory") - Enonexist = errors.New("file does not exist") - Eexist = errors.New("file already exists") - Eio = errors.New("i/o error") - Eperm = errors.New("permission denied") - - EINVAL = Ebadarg - ENOTDIR = Enotdir - ENOENT = Enonexist - EEXIST = Eexist - EIO = Eio - EACCES = Eperm - EPERM = Eperm - EISDIR = syscall.EISDIR +// IsPermission returns whether the error is known to report that permission is denied. +func IsPermission(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return contains(err.Error(), "permission denied") +} - EBADF = errors.New("bad file descriptor") - ENAMETOOLONG = errors.New("file name too long") - ERANGE = errors.New("math result not representable") - EPIPE = errors.New("Broken Pipe") - EPLAN9 = errors.New("not supported by plan 9") -) +// contains is a local version of strings.Contains. It knows len(sep) > 1. +func contains(s, sep string) bool { + n := len(sep) + c := sep[0] + for i := 0; i+n <= len(s); i++ { + if s[i] == c && s[i:i+n] == sep { + return true + } + } + return false +} diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go index 1a08627256a..74b75d11218 100644 --- a/libgo/go/os/error_posix.go +++ b/libgo/go/os/error_posix.go @@ -6,65 +6,31 @@ package os -import syscall "syscall" +import "syscall" -// Commonly known Unix errors. -var ( - EPERM error = syscall.EPERM - ENOENT error = syscall.ENOENT - ESRCH error = syscall.ESRCH - EINTR error = syscall.EINTR - EIO error = syscall.EIO - ENXIO error = syscall.ENXIO - E2BIG error = syscall.E2BIG - ENOEXEC error = syscall.ENOEXEC - EBADF error = syscall.EBADF - ECHILD error = syscall.ECHILD - EDEADLK error = syscall.EDEADLK - ENOMEM error = syscall.ENOMEM - EACCES error = syscall.EACCES - EFAULT error = syscall.EFAULT - EBUSY error = syscall.EBUSY - EEXIST error = syscall.EEXIST - EXDEV error = syscall.EXDEV - ENODEV error = syscall.ENODEV - ENOTDIR error = syscall.ENOTDIR - EISDIR error = syscall.EISDIR - EINVAL error = syscall.EINVAL - ENFILE error = syscall.ENFILE - EMFILE error = syscall.EMFILE - ENOTTY error = syscall.ENOTTY - EFBIG error = syscall.EFBIG - ENOSPC error = syscall.ENOSPC - ESPIPE error = syscall.ESPIPE - EROFS error = syscall.EROFS - EMLINK error = syscall.EMLINK - EPIPE error = syscall.EPIPE - EAGAIN error = syscall.EAGAIN - EDOM error = syscall.EDOM - ERANGE error = syscall.ERANGE - EADDRINUSE error = syscall.EADDRINUSE - ECONNREFUSED error = syscall.ECONNREFUSED - ENAMETOOLONG error = syscall.ENAMETOOLONG - EAFNOSUPPORT error = syscall.EAFNOSUPPORT - ETIMEDOUT error = syscall.ETIMEDOUT - ENOTCONN error = syscall.ENOTCONN -) - -// SyscallError records an error from a specific system call. -type SyscallError struct { - Syscall string - Errno error +// IsExist returns whether the error is known to report that a file already exists. +// It is satisfied by ErrExist as well as some syscall errors. +func IsExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return err == syscall.EEXIST || err == ErrExist } -func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Errno.Error() } +// IsNotExist returns whether the error is known to report that a file does not exist. +// It is satisfied by ErrNotExist as well as some syscall errors. +func IsNotExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return err == syscall.ENOENT || err == ErrNotExist +} -// NewSyscallError returns, as an error, a new SyscallError -// with the given system call name and error details. -// As a convenience, if err is nil, NewSyscallError returns nil. -func NewSyscallError(syscall string, err error) error { - if err == nil { - return nil +// IsPermission returns whether the error is known to report that permission is denied. +// It is satisfied by ErrPermission as well as some syscall errors. +func IsPermission(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err } - return &SyscallError{syscall, err} + return err == syscall.EACCES || err == syscall.EPERM || err == ErrPermission } diff --git a/libgo/go/os/exec.go b/libgo/go/os/exec.go index 6e0f168c767..531b87ca556 100644 --- a/libgo/go/os/exec.go +++ b/libgo/go/os/exec.go @@ -13,7 +13,7 @@ import ( type Process struct { Pid int handle uintptr - done bool // process has been successfuly waited on + done bool // process has been successfully waited on } func newProcess(pid int, handle uintptr) *Process { @@ -46,11 +46,22 @@ type ProcAttr struct { Sys *syscall.SysProcAttr } -// A Signal can represent any operating system signal. +// A Signal represents an operating system signal. +// The usual underlying implementation is operating system-dependent: +// on Unix it is syscall.Signal. type Signal interface { String() string + Signal() // to distinguish from other Stringers } +// The only signal values guaranteed to be present on all systems +// are Interrupt (send the process an interrupt) and +// Kill (force the process to exit). +var ( + Interrupt Signal = syscall.SIGINT + Kill Signal = syscall.SIGKILL +) + // Getpid returns the process id of the caller. func Getpid() int { return syscall.Getpid() } diff --git a/libgo/go/os/exec/exec.go b/libgo/go/os/exec/exec.go index a00fdad497f..ebe92a9fba3 100644 --- a/libgo/go/os/exec/exec.go +++ b/libgo/go/os/exec/exec.go @@ -68,7 +68,7 @@ type Cmd struct { // new process. It does not include standard input, standard output, or // standard error. If non-nil, entry i becomes file descriptor 3+i. // - // BUG: on OS X 10.6, child processes may sometimes inherit extra fds. + // BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds. // http://golang.org/issue/2603 ExtraFiles []*os.File @@ -79,6 +79,10 @@ type Cmd struct { // Process is the underlying process, once started. Process *os.Process + // ProcessState contains information about an exited process, + // available after a call to Wait or Run. + ProcessState *os.ProcessState + err error // last error (from LookPath, stdin, stdout, stderr) finished bool // when Wait was called childFiles []*os.File @@ -262,11 +266,11 @@ func (c *Cmd) Start() error { // An ExitError reports an unsuccessful exit by a command. type ExitError struct { - *os.Waitmsg + *os.ProcessState } func (e *ExitError) Error() string { - return e.Waitmsg.String() + return e.ProcessState.String() } // Wait waits for the command to exit. @@ -287,7 +291,8 @@ func (c *Cmd) Wait() error { return errors.New("exec: Wait was already called") } c.finished = true - msg, err := c.Process.Wait(0) + state, err := c.Process.Wait() + c.ProcessState = state var copyError error for _ = range c.goroutine { @@ -302,8 +307,8 @@ func (c *Cmd) Wait() error { if err != nil { return err - } else if !msg.Exited() || msg.ExitStatus() != 0 { - return &ExitError{msg} + } else if !state.Success() { + return &ExitError{state} } return copyError diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go index d00d12008f7..52f4bce3aea 100644 --- a/libgo/go/os/exec/exec_test.go +++ b/libgo/go/os/exec/exec_test.go @@ -17,7 +17,6 @@ import ( "runtime" "strconv" "strings" - "syscall" "testing" ) @@ -154,7 +153,7 @@ func TestExtraFiles(t *testing.T) { // Ensure that file descriptors have not already been leaked into // our environment. for fd := os.Stderr.Fd() + 1; fd <= 101; fd++ { - err := syscall.Close(fd) + err := os.NewFile(fd, "").Close() if err == nil { t.Logf("Something already leaked - closed fd %d", fd) } diff --git a/libgo/go/os/exec/lp_plan9.go b/libgo/go/os/exec/lp_plan9.go index d88cd0df959..0e229e03ee7 100644 --- a/libgo/go/os/exec/lp_plan9.go +++ b/libgo/go/os/exec/lp_plan9.go @@ -8,6 +8,7 @@ import ( "errors" "os" "strings" + "syscall" ) // ErrNotFound is the error resulting if a path search failed to find an executable file. @@ -21,7 +22,7 @@ func findExecutable(file string) error { if m := d.Mode(); !m.IsDir() && m&0111 != 0 { return nil } - return os.EPERM + return syscall.EPERM } // LookPath searches for an executable binary named file diff --git a/libgo/go/os/exec/lp_unix.go b/libgo/go/os/exec/lp_unix.go index 2d3a919dc6e..21632219972 100644 --- a/libgo/go/os/exec/lp_unix.go +++ b/libgo/go/os/exec/lp_unix.go @@ -23,7 +23,7 @@ func findExecutable(file string) error { if m := d.Mode(); !m.IsDir() && m&0111 != 0 { return nil } - return os.EPERM + return os.ErrPermission } // LookPath searches for an executable binary named file diff --git a/libgo/go/os/exec/lp_windows.go b/libgo/go/os/exec/lp_windows.go index b7efcd68b80..d8351d7e6d3 100644 --- a/libgo/go/os/exec/lp_windows.go +++ b/libgo/go/os/exec/lp_windows.go @@ -19,7 +19,7 @@ func chkStat(file string) error { return err } if d.IsDir() { - return os.EPERM + return os.ErrPermission } return nil } @@ -39,7 +39,7 @@ func findExecutable(file string, exts []string) (string, error) { return f, nil } } - return ``, os.ENOENT + return ``, os.ErrNotExist } // LookPath searches for an executable binary named file diff --git a/libgo/go/os/exec_plan9.go b/libgo/go/os/exec_plan9.go index 879d4d2a736..41cc8c26f4c 100644 --- a/libgo/go/os/exec_plan9.go +++ b/libgo/go/os/exec_plan9.go @@ -8,29 +8,20 @@ import ( "errors" "runtime" "syscall" + "time" ) -// StartProcess starts a new process with the program, arguments and attributes -// specified by name, argv and attr. -func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) { +func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) { sysattr := &syscall.ProcAttr{ Dir: attr.Dir, Env: attr.Env, Sys: attr.Sys, } - // Create array of integer (system) fds. - intfd := make([]int, len(attr.Files)) - for i, f := range attr.Files { - if f == nil { - intfd[i] = -1 - } else { - intfd[i] = f.Fd() - } + for _, f := range attr.Files { + sysattr.Files = append(sysattr.Files, f.Fd()) } - sysattr.Files = intfd - pid, h, e := syscall.StartProcess(name, argv, sysattr) if e != nil { return nil, &PathError{"fork/exec", name, e} @@ -46,7 +37,7 @@ func (note Plan9Note) String() string { return string(note) } -func (p *Process) Signal(sig Signal) error { +func (p *Process) signal(sig Signal) error { if p.done { return errors.New("os: process already finished") } @@ -60,8 +51,7 @@ func (p *Process) Signal(sig Signal) error { return e } -// Kill causes the Process to exit immediately. -func (p *Process) Kill() error { +func (p *Process) kill() error { f, e := OpenFile("/proc/"+itoa(p.Pid)+"/ctl", O_WRONLY, 0) if e != nil { return NewSyscallError("kill", e) @@ -71,32 +61,11 @@ func (p *Process) Kill() error { return e } -// Exec replaces the current process with an execution of the -// named binary, with arguments argv and environment envv. -// If successful, Exec never returns. If it fails, it returns an error. -// ForkExec is almost always a better way to execute a program. -func Exec(name string, argv []string, envv []string) error { - e := syscall.Exec(name, argv, envv) - if e != nil { - return &PathError{"exec", name, e} - } - - return nil -} - -// Waitmsg stores the information about an exited process as reported by Wait. -type Waitmsg struct { - syscall.Waitmsg -} - -// Wait waits for the Process to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. The options -// (WNOHANG etc.) affect the behavior of the Wait call. -func (p *Process) Wait(options int) (w *Waitmsg, err error) { +func (p *Process) wait() (ps *ProcessState, err error) { var waitmsg syscall.Waitmsg if p.Pid == -1 { - return nil, EINVAL + return nil, ErrInvalid } for true { @@ -112,25 +81,14 @@ func (p *Process) Wait(options int) (w *Waitmsg, err error) { } } - return &Waitmsg{waitmsg}, nil -} - -// Wait waits for process pid to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. The options -// (WNOHANG etc.) affect the behavior of the Wait call. -// Wait is equivalent to calling FindProcess and then Wait -// and Release on the result. -func Wait(pid int, options int) (w *Waitmsg, err error) { - p, e := FindProcess(pid) - if e != nil { - return nil, e + ps = &ProcessState{ + pid: waitmsg.Pid, + status: &waitmsg, } - defer p.Release() - return p.Wait(options) + return ps, nil } -// Release releases any resources associated with the Process. -func (p *Process) Release() error { +func (p *Process) release() error { // NOOP for Plan 9. p.Pid = -1 // no need for a finalizer anymore @@ -143,9 +101,44 @@ func findProcess(pid int) (p *Process, err error) { return newProcess(pid, 0), nil } -func (w *Waitmsg) String() string { - if w == nil { +// ProcessState stores information about a process, as reported by Wait. +type ProcessState struct { + pid int // The process's id. + status *syscall.Waitmsg // System-dependent status info. +} + +// Pid returns the process id of the exited process. +func (p *ProcessState) Pid() int { + return p.pid +} + +func (p *ProcessState) exited() bool { + return p.status.Exited() +} + +func (p *ProcessState) success() bool { + return p.status.ExitStatus() == 0 +} + +func (p *ProcessState) sys() interface{} { + return p.status +} + +func (p *ProcessState) sysUsage() interface{} { + return p.status +} + +func (p *ProcessState) userTime() time.Duration { + return time.Duration(p.status.Time[0]) * time.Millisecond +} + +func (p *ProcessState) systemTime() time.Duration { + return time.Duration(p.status.Time[1]) * time.Millisecond +} + +func (p *ProcessState) String() string { + if p == nil { return "<nil>" } - return "exit status: " + w.Msg + return "exit status: " + p.status.Msg } diff --git a/libgo/go/os/exec_posix.go b/libgo/go/os/exec_posix.go index 6465bfbb653..70351cfb313 100644 --- a/libgo/go/os/exec_posix.go +++ b/libgo/go/os/exec_posix.go @@ -7,26 +7,20 @@ package os import ( - "runtime" "syscall" ) -type UnixSignal int32 - -func (sig UnixSignal) String() string { - s := runtime.Signame(int32(sig)) - if len(s) > 0 { - return s +func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) { + // Double-check existence of the directory we want + // to chdir into. We can make the error clearer this way. + if attr != nil && attr.Dir != "" { + if _, err := Stat(attr.Dir); err != nil { + pe := err.(*PathError) + pe.Op = "chdir" + return nil, pe + } } - return "UnixSignal" -} -// StartProcess starts a new process with the program, arguments and attributes -// specified by name, argv and attr. -// -// StartProcess is a low-level interface. The os/exec package provides -// higher-level interfaces. -func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) { sysattr := &syscall.ProcAttr{ Dir: attr.Dir, Env: attr.Env, @@ -46,54 +40,36 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e return newProcess(pid, h), nil } -// Kill causes the Process to exit immediately. -func (p *Process) Kill() error { - return p.Signal(UnixSignal(syscall.SIGKILL)) +func (p *Process) kill() error { + return p.Signal(Kill) } -// Exec replaces the current process with an execution of the -// named binary, with arguments argv and environment envv. -// If successful, Exec never returns. If it fails, it returns an error. -// -// To run a child process, see StartProcess (for a low-level interface) -// or the os/exec package (for higher-level interfaces). -func Exec(name string, argv []string, envv []string) error { - if envv == nil { - envv = Environ() - } - e := syscall.Exec(name, argv, envv) - if e != nil { - return &PathError{"exec", name, e} - } - return nil +// ProcessState stores information about a process, as reported by Wait. +type ProcessState struct { + pid int // The process's id. + status syscall.WaitStatus // System-dependent status info. + rusage *syscall.Rusage } -// TODO(rsc): Should os implement its own syscall.WaitStatus -// wrapper with the methods, or is exposing the underlying one enough? -// -// TODO(rsc): Certainly need to have Rusage struct, -// since syscall one might have different field types across -// different OS. - -// Waitmsg stores the information about an exited process as reported by Wait. -type Waitmsg struct { - Pid int // The process's id. - syscall.WaitStatus // System-dependent status info. - Rusage *syscall.Rusage // System-dependent resource usage info. +// Pid returns the process id of the exited process. +func (p *ProcessState) Pid() int { + return p.pid } -// Wait waits for process pid to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. The options -// (WNOHANG etc.) affect the behavior of the Wait call. -// Wait is equivalent to calling FindProcess and then Wait -// and Release on the result. -func Wait(pid int, options int) (w *Waitmsg, err error) { - p, e := FindProcess(pid) - if e != nil { - return nil, e - } - defer p.Release() - return p.Wait(options) +func (p *ProcessState) exited() bool { + return p.status.Exited() +} + +func (p *ProcessState) success() bool { + return p.status.ExitStatus() == 0 +} + +func (p *ProcessState) sys() interface{} { + return p.status +} + +func (p *ProcessState) sysUsage() interface{} { + return p.rusage } // Convert i to decimal string. @@ -123,26 +99,26 @@ func itod(i int) string { return string(b[bp:]) } -func (w *Waitmsg) String() string { - if w == nil { +func (p *ProcessState) String() string { + if p == nil { return "<nil>" } - // TODO(austin) Use signal names when possible? + status := p.Sys().(syscall.WaitStatus) res := "" switch { - case w.Exited(): - res = "exit status " + itod(w.ExitStatus()) - case w.Signaled(): - res = "signal " + itod(w.Signal()) - case w.Stopped(): - res = "stop signal " + itod(w.StopSignal()) - if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 { - res += " (trap " + itod(w.TrapCause()) + ")" + case status.Exited(): + res = "exit status " + itod(status.ExitStatus()) + case status.Signaled(): + res = "signal " + itod(int(status.Signal())) + case status.Stopped(): + res = "stop signal " + itod(int(status.StopSignal())) + if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 { + res += " (trap " + itod(status.TrapCause()) + ")" } - case w.Continued(): + case status.Continued(): res = "continued" } - if w.CoreDump() { + if status.CoreDump() { res += " (core dumped)" } return res diff --git a/libgo/go/os/exec_unix.go b/libgo/go/os/exec_unix.go index 6c11b63c34f..ecfe5353bc1 100644 --- a/libgo/go/os/exec_unix.go +++ b/libgo/go/os/exec_unix.go @@ -10,61 +10,45 @@ import ( "errors" "runtime" "syscall" + "time" ) -// Options for Wait. -const ( - WNOHANG = syscall.WNOHANG // Don't wait if no process has exited. - WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses is also reported. - WUNTRACED = syscall.WUNTRACED // Usually an alias for WSTOPPED. - WRUSAGE = 1 << 20 // Record resource usage. -) - -// WRUSAGE must not be too high a bit, to avoid clashing with Linux's -// WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of -// the options - -// Wait waits for the Process to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. The options -// (WNOHANG etc.) affect the behavior of the Wait call. -func (p *Process) Wait(options int) (w *Waitmsg, err error) { +func (p *Process) wait() (ps *ProcessState, err error) { if p.Pid == -1 { - return nil, EINVAL + return nil, syscall.EINVAL } var status syscall.WaitStatus - var rusage *syscall.Rusage - if options&WRUSAGE != 0 { - rusage = new(syscall.Rusage) - options ^= WRUSAGE - } - pid1, e := syscall.Wait4(p.Pid, &status, options, rusage) + var rusage syscall.Rusage + pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage) if e != nil { return nil, NewSyscallError("wait", e) } - // With WNOHANG pid is 0 if child has not exited. - if pid1 != 0 && options&WSTOPPED == 0 { + if pid1 != 0 { p.done = true } - w = new(Waitmsg) - w.Pid = pid1 - w.WaitStatus = status - w.Rusage = rusage - return w, nil + ps = &ProcessState{ + pid: pid1, + status: status, + rusage: &rusage, + } + return ps, nil } -// Signal sends a signal to the Process. -func (p *Process) Signal(sig Signal) error { +func (p *Process) signal(sig Signal) error { if p.done { return errors.New("os: process already finished") } - if e := syscall.Kill(p.Pid, int(sig.(UnixSignal))); e != nil { + s, ok := sig.(syscall.Signal) + if !ok { + return errors.New("os: unsupported signal type") + } + if e := syscall.Kill(p.Pid, s); e != nil { return e } return nil } -// Release releases any resources associated with the Process. -func (p *Process) Release() error { +func (p *Process) release() error { // NOOP for unix. p.Pid = -1 // no need for a finalizer anymore @@ -76,3 +60,11 @@ func findProcess(pid int) (p *Process, err error) { // NOOP for unix. return newProcess(pid, 0), nil } + +func (p *ProcessState) userTime() time.Duration { + return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond +} + +func (p *ProcessState) systemTime() time.Duration { + return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond +} diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go index 9463d2c0e3f..5beca4a6509 100644 --- a/libgo/go/os/exec_windows.go +++ b/libgo/go/os/exec_windows.go @@ -8,12 +8,11 @@ import ( "errors" "runtime" "syscall" + "time" "unsafe" ) -// Wait waits for the Process to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. -func (p *Process) Wait(options int) (w *Waitmsg, err error) { +func (p *Process) wait() (ps *ProcessState, err error) { s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: @@ -28,26 +27,36 @@ func (p *Process) Wait(options int) (w *Waitmsg, err error) { if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } + var u syscall.Rusage + e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) + if e != nil { + return nil, NewSyscallError("GetProcessTimes", e) + } p.done = true - return &Waitmsg{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil + // NOTE(brainman): It seems that sometimes process is not dead + // when WaitForSingleObject returns. But we do not know any + // other way to wait for it. Sleeping for a while seems to do + // the trick sometimes. So we will sleep and smell the roses. + defer time.Sleep(5 * time.Millisecond) + defer p.Release() + return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil } -// Signal sends a signal to the Process. -func (p *Process) Signal(sig Signal) error { +func (p *Process) signal(sig Signal) error { if p.done { return errors.New("os: process already finished") } - if us, ok := sig.(UnixSignal); ok && us == syscall.SIGKILL { + if sig == Kill { e := syscall.TerminateProcess(syscall.Handle(p.handle), 1) return NewSyscallError("TerminateProcess", e) } + // TODO(rsc): Handle Interrupt too? return syscall.Errno(syscall.EWINDOWS) } -// Release releases any resources associated with the Process. -func (p *Process) Release() error { +func (p *Process) release() error { if p.handle == uintptr(syscall.InvalidHandle) { - return EINVAL + return syscall.EINVAL } e := syscall.CloseHandle(syscall.Handle(p.handle)) if e != nil { @@ -82,3 +91,16 @@ func init() { Args[i] = string(syscall.UTF16ToString((*v)[:])) } } + +func ftToDuration(ft *syscall.Filetime) time.Duration { + n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals + return time.Duration(n*100) * time.Nanosecond +} + +func (p *ProcessState) userTime() time.Duration { + return ftToDuration(&p.rusage.UserTime) +} + +func (p *ProcessState) systemTime() time.Duration { + return ftToDuration(&p.rusage.KernelTime) +} diff --git a/libgo/go/os/file.go b/libgo/go/os/file.go index 3efa650c657..4acf35d6755 100644 --- a/libgo/go/os/file.go +++ b/libgo/go/os/file.go @@ -3,9 +3,37 @@ // license that can be found in the LICENSE file. // Package os provides a platform-independent interface to operating system -// functionality. The design is Unix-like. +// functionality. The design is Unix-like, although the error handling is +// Go-like; failing calls return values of type error rather than error numbers. +// Often, more information is available within the error. For example, +// if a call that takes a file name fails, such as Open or Stat, the error +// will include the failing file name when printed and will be of type +// *PathError, which may be unpacked for more information. +// // The os interface is intended to be uniform across all operating systems. // Features not generally available appear in the system-specific package syscall. +// +// Here is a simple example, opening a file and reading some of it. +// +// file, err := os.Open("file.go") // For read access. +// if err != nil { +// log.Fatal(err) +// } +// +// If the open fails, the error string will be self-explanatory, like +// +// open file.go: no such file or directory +// +// The file's data can then be read into a slice of bytes. Read and +// Write take their byte counts from the length of the argument slice. +// +// data := make([]byte, 100) +// count, err := file.Read(data) +// if err != nil { +// log.Fatal(err) +// } +// fmt.Printf("read %d bytes: %q\n", count, data[:count]) +// package os import ( @@ -19,26 +47,22 @@ func (f *File) Name() string { return f.name } // Stdin, Stdout, and Stderr are open Files pointing to the standard input, // standard output, and standard error file descriptors. var ( - Stdin = NewFile(syscall.Stdin, "/dev/stdin") - Stdout = NewFile(syscall.Stdout, "/dev/stdout") - Stderr = NewFile(syscall.Stderr, "/dev/stderr") + Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") + Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout") + Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr") ) // Flags to Open wrapping those of the underlying system. Not all flags // may be implemented on a given system. const ( - O_RDONLY int = syscall.O_RDONLY // open the file read-only. - O_WRONLY int = syscall.O_WRONLY // open the file write-only. - O_RDWR int = syscall.O_RDWR // open the file read-write. - O_APPEND int = syscall.O_APPEND // append data to the file when writing. - O_ASYNC int = syscall.O_ASYNC // generate a signal when I/O is available. - O_CREATE int = syscall.O_CREAT // create a new file if none exists. - O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist - O_NOCTTY int = syscall.O_NOCTTY // do not make file the controlling tty. - O_NONBLOCK int = syscall.O_NONBLOCK // open in non-blocking mode. - O_NDELAY int = O_NONBLOCK // synonym for O_NONBLOCK - O_SYNC int = syscall.O_SYNC // open for synchronous I/O. - O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened. + O_RDONLY int = syscall.O_RDONLY // open the file read-only. + O_WRONLY int = syscall.O_WRONLY // open the file write-only. + O_RDWR int = syscall.O_RDWR // open the file read-write. + O_APPEND int = syscall.O_APPEND // append data to the file when writing. + O_CREATE int = syscall.O_CREAT // create a new file if none exists. + O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist + O_SYNC int = syscall.O_SYNC // open for synchronous I/O. + O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened. ) // Seek whence values. @@ -48,12 +72,25 @@ const ( SEEK_END int = 2 // seek relative to the end ) +// LinkError records an error during a link or symlink or rename +// system call and the paths that caused it. +type LinkError struct { + Op string + Old string + New string + Err error +} + +func (e *LinkError) Error() string { + return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error() +} + // Read reads up to len(b) bytes from the File. // It returns the number of bytes read and an error, if any. // EOF is signaled by a zero count with err set to io.EOF. func (f *File) Read(b []byte) (n int, err error) { if f == nil { - return 0, EINVAL + return 0, ErrInvalid } n, e := f.read(b) if n < 0 { @@ -74,7 +111,7 @@ func (f *File) Read(b []byte) (n int, err error) { // At end of file, that error is io.EOF. func (f *File) ReadAt(b []byte, off int64) (n int, err error) { if f == nil { - return 0, EINVAL + return 0, ErrInvalid } for len(b) > 0 { m, e := f.pread(b, off) @@ -97,7 +134,7 @@ func (f *File) ReadAt(b []byte, off int64) (n int, err error) { // Write returns a non-nil error when n != len(b). func (f *File) Write(b []byte) (n int, err error) { if f == nil { - return 0, EINVAL + return 0, ErrInvalid } n, e := f.write(b) if n < 0 { @@ -117,7 +154,7 @@ func (f *File) Write(b []byte) (n int, err error) { // WriteAt returns a non-nil error when n != len(b). func (f *File) WriteAt(b []byte, off int64) (n int, err error) { if f == nil { - return 0, EINVAL + return 0, ErrInvalid } for len(b) > 0 { m, e := f.pwrite(b, off) @@ -151,13 +188,13 @@ func (f *File) Seek(offset int64, whence int) (ret int64, err error) { // an array of bytes. func (f *File) WriteString(s string) (ret int, err error) { if f == nil { - return 0, EINVAL + return 0, ErrInvalid } return f.Write([]byte(s)) } // Mkdir creates a new directory with the specified name and permission bits. -// It returns an error, if any. +// If there is an error, it will be of type *PathError. func Mkdir(name string, perm FileMode) error { e := syscall.Mkdir(name, syscallMode(perm)) if e != nil { @@ -167,6 +204,7 @@ func Mkdir(name string, perm FileMode) error { } // Chdir changes the current working directory to the named directory. +// If there is an error, it will be of type *PathError. func Chdir(dir string) error { if e := syscall.Chdir(dir); e != nil { return &PathError{"chdir", dir, e} @@ -176,6 +214,7 @@ func Chdir(dir string) error { // Chdir changes the current working directory to the file, // which must be a directory. +// If there is an error, it will be of type *PathError. func (f *File) Chdir() error { if e := syscall.Fchdir(f.fd); e != nil { return &PathError{"chdir", f.name, e} @@ -186,7 +225,7 @@ func (f *File) Chdir() error { // Open opens the named file for reading. If successful, methods on // the returned file can be used for reading; the associated file // descriptor has mode O_RDONLY. -// It returns the File and an error, if any. +// If there is an error, it will be of type *PathError. func Open(name string) (file *File, err error) { return OpenFile(name, O_RDONLY, 0) } @@ -195,7 +234,7 @@ func Open(name string) (file *File, err error) { // it if it already exists. If successful, methods on the returned // File can be used for I/O; the associated file descriptor has mode // O_RDWR. -// It returns the File and an error, if any. +// If there is an error, it will be of type *PathError. func Create(name string) (file *File, err error) { return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) } diff --git a/libgo/go/os/file_plan9.go b/libgo/go/os/file_plan9.go index 7d136eb3686..cb0e9ef9289 100644 --- a/libgo/go/os/file_plan9.go +++ b/libgo/go/os/file_plan9.go @@ -5,11 +5,14 @@ package os import ( + "errors" "runtime" "syscall" "time" ) +var ErrPlan9 = errors.New("unimplemented on Plan 9") + // File represents an open file descriptor. type File struct { *file @@ -26,19 +29,20 @@ type file struct { } // Fd returns the integer Unix file descriptor referencing the open file. -func (file *File) Fd() int { - if file == nil { - return -1 +func (f *File) Fd() uintptr { + if f == nil { + return ^(uintptr(0)) } - return file.fd + return uintptr(f.fd) } // NewFile returns a new File with the given file descriptor and name. -func NewFile(fd int, name string) *File { - if fd < 0 { +func NewFile(fd uintptr, name string) *File { + fdi := int(fd) + if fdi < 0 { return nil } - f := &File{&file{fd: fd, name: name}} + f := &File{&file{fd: fdi, name: name}} runtime.SetFinalizer(f.file, (*file).close) return f } @@ -76,7 +80,7 @@ func syscallMode(i FileMode) (o uint32) { // or Create instead. It opens the named file with specified flag // (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, // methods on the returned File can be used for I/O. -// It returns the File and an error, if any. +// If there is an error, it will be of type *PathError. func OpenFile(name string, flag int, perm FileMode) (file *File, err error) { var ( fd int @@ -128,7 +132,7 @@ func OpenFile(name string, flag int, perm FileMode) (file *File, err error) { } } - return NewFile(fd, name), nil + return NewFile(uintptr(fd), name), nil } // Close closes the File, rendering it unusable for I/O. @@ -139,7 +143,7 @@ func (file *File) Close() error { func (file *file) close() error { if file == nil || file.fd < 0 { - return Ebadfd + return ErrInvalid } var err error syscall.ForkLock.RLock() @@ -181,6 +185,7 @@ func (f *File) Truncate(size int64) error { const chmodMask = uint32(syscall.DMAPPEND | syscall.DMEXCL | syscall.DMTMP | ModePerm) // Chmod changes the mode of the file to mode. +// If there is an error, it will be of type *PathError. func (f *File) Chmod(mode FileMode) error { var d Dir @@ -201,7 +206,7 @@ func (f *File) Chmod(mode FileMode) error { // of recently written data to disk. func (f *File) Sync() (err error) { if f == nil { - return EINVAL + return ErrInvalid } var d Dir @@ -248,6 +253,7 @@ func (f *File) seek(offset int64, whence int) (ret int64, err error) { // Truncate changes the size of the named file. // If the file is a symbolic link, it changes the size of the link's target. +// If there is an error, it will be of type *PathError. func Truncate(name string, size int64) error { var d Dir d.Null() @@ -261,6 +267,7 @@ func Truncate(name string, size int64) error { } // Remove removes the named file or directory. +// If there is an error, it will be of type *PathError. func Remove(name string) error { if e := syscall.Remove(name); e != nil { return &PathError{"remove", name, e} @@ -282,6 +289,7 @@ func Rename(oldname, newname string) error { } // Chmod changes the mode of the named file to mode. +// If there is an error, it will be of type *PathError. func Chmod(name string, mode FileMode) error { var d Dir @@ -325,34 +333,37 @@ func Pipe() (r *File, w *File, err error) { } syscall.ForkLock.RUnlock() - return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil + return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil } // not supported on Plan 9 // Link creates a hard link. +// If there is an error, it will be of type *LinkError. func Link(oldname, newname string) error { - return EPLAN9 + return &LinkError{"link", oldname, newname, ErrPlan9} } +// Symlink creates newname as a symbolic link to oldname. +// If there is an error, it will be of type *LinkError. func Symlink(oldname, newname string) error { - return EPLAN9 + return &LinkError{"symlink", oldname, newname, ErrPlan9} } func Readlink(name string) (string, error) { - return "", EPLAN9 + return "", ErrPlan9 } func Chown(name string, uid, gid int) error { - return EPLAN9 + return ErrPlan9 } func Lchown(name string, uid, gid int) error { - return EPLAN9 + return ErrPlan9 } func (f *File) Chown(uid, gid int) error { - return EPLAN9 + return ErrPlan9 } // TempDir returns the default directory to use for temporary files. diff --git a/libgo/go/os/file_posix.go b/libgo/go/os/file_posix.go index 86ac1cab2cb..073bd56a471 100644 --- a/libgo/go/os/file_posix.go +++ b/libgo/go/os/file_posix.go @@ -24,20 +24,8 @@ func epipecheck(file *File, e error) { } } -// LinkError records an error during a link or symlink or rename -// system call and the paths that caused it. -type LinkError struct { - Op string - Old string - New string - Err error -} - -func (e *LinkError) Error() string { - return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error() -} - -// Link creates a hard link. +// Link creates newname as a hard link to the oldname file. +// If there is an error, it will be of type *LinkError. func Link(oldname, newname string) error { e := syscall.Link(oldname, newname) if e != nil { @@ -46,7 +34,8 @@ func Link(oldname, newname string) error { return nil } -// Symlink creates a symbolic link. +// Symlink creates newname as a symbolic link to oldname. +// If there is an error, it will be of type *LinkError. func Symlink(oldname, newname string) error { e := syscall.Symlink(oldname, newname) if e != nil { @@ -55,8 +44,8 @@ func Symlink(oldname, newname string) error { return nil } -// Readlink reads the contents of a symbolic link: the destination of -// the link. It returns the contents and an error, if any. +// Readlink returns the destination of the named symbolic link. +// If there is an error, it will be of type *PathError. func Readlink(name string) (string, error) { for len := 128; ; len *= 2 { b := make([]byte, len) @@ -99,6 +88,7 @@ func syscallMode(i FileMode) (o uint32) { // Chmod changes the mode of the named file to mode. // If the file is a symbolic link, it changes the mode of the link's target. +// If there is an error, it will be of type *PathError. func Chmod(name string, mode FileMode) error { if e := syscall.Chmod(name, syscallMode(mode)); e != nil { return &PathError{"chmod", name, e} @@ -107,6 +97,7 @@ func Chmod(name string, mode FileMode) error { } // Chmod changes the mode of the file to mode. +// If there is an error, it will be of type *PathError. func (f *File) Chmod(mode FileMode) error { if e := syscall.Fchmod(f.fd, syscallMode(mode)); e != nil { return &PathError{"chmod", f.name, e} @@ -116,6 +107,7 @@ func (f *File) Chmod(mode FileMode) error { // Chown changes the numeric uid and gid of the named file. // If the file is a symbolic link, it changes the uid and gid of the link's target. +// If there is an error, it will be of type *PathError. func Chown(name string, uid, gid int) error { if e := syscall.Chown(name, uid, gid); e != nil { return &PathError{"chown", name, e} @@ -125,6 +117,7 @@ func Chown(name string, uid, gid int) error { // Lchown changes the numeric uid and gid of the named file. // If the file is a symbolic link, it changes the uid and gid of the link itself. +// If there is an error, it will be of type *PathError. func Lchown(name string, uid, gid int) error { if e := syscall.Lchown(name, uid, gid); e != nil { return &PathError{"lchown", name, e} @@ -133,6 +126,7 @@ func Lchown(name string, uid, gid int) error { } // Chown changes the numeric uid and gid of the named file. +// If there is an error, it will be of type *PathError. func (f *File) Chown(uid, gid int) error { if e := syscall.Fchown(f.fd, uid, gid); e != nil { return &PathError{"chown", f.name, e} @@ -142,6 +136,7 @@ func (f *File) Chown(uid, gid int) error { // Truncate changes the size of the file. // It does not change the I/O offset. +// If there is an error, it will be of type *PathError. func (f *File) Truncate(size int64) error { if e := syscall.Ftruncate(f.fd, size); e != nil { return &PathError{"truncate", f.name, e} @@ -154,7 +149,7 @@ func (f *File) Truncate(size int64) error { // of recently written data to disk. func (f *File) Sync() (err error) { if f == nil { - return EINVAL + return syscall.EINVAL } if e := syscall.Fsync(f.fd); e != nil { return NewSyscallError("fsync", e) @@ -167,6 +162,7 @@ func (f *File) Sync() (err error) { // // The underlying filesystem may truncate or round the values to a // less precise time unit. +// If there is an error, it will be of type *PathError. func Chtimes(name string, atime time.Time, mtime time.Time) error { var utimes [2]syscall.Timeval atime_ns := atime.Unix()*1e9 + int64(atime.Nanosecond()) diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go index 8c61a82248f..a69680cb8c9 100644 --- a/libgo/go/os/file_unix.go +++ b/libgo/go/os/file_unix.go @@ -28,19 +28,20 @@ type file struct { } // Fd returns the integer Unix file descriptor referencing the open file. -func (f *File) Fd() int { +func (f *File) Fd() uintptr { if f == nil { - return -1 + return ^(uintptr(0)) } - return f.fd + return uintptr(f.fd) } // NewFile returns a new File with the given file descriptor and name. -func NewFile(fd int, name string) *File { - if fd < 0 { +func NewFile(fd uintptr, name string) *File { + fdi := int(fd) + if fdi < 0 { return nil } - f := &File{&file{fd: fd, name: name}} + f := &File{&file{fd: fdi, name: name}} runtime.SetFinalizer(f.file, (*file).close) return f } @@ -59,7 +60,7 @@ const DevNull = "/dev/null" // or Create instead. It opens the named file with specified flag // (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, // methods on the returned File can be used for I/O. -// It returns the File and an error, if any. +// If there is an error, it will be of type *PathError. func OpenFile(name string, flag int, perm FileMode) (file *File, err error) { r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm)) if e != nil { @@ -77,7 +78,7 @@ func OpenFile(name string, flag int, perm FileMode) (file *File, err error) { syscall.CloseOnExec(r) } - return NewFile(r, name), nil + return NewFile(uintptr(r), name), nil } // Close closes the File, rendering it unusable for I/O. @@ -88,7 +89,7 @@ func (f *File) Close() error { func (file *file) close() error { if file == nil || file.fd < 0 { - return EINVAL + return syscall.EINVAL } var err error if e := syscall.Close(file.fd); e != nil { @@ -109,7 +110,7 @@ func (file *file) close() error { } // Stat returns the FileInfo structure describing file. -// It returns the FileInfo and an error, if any. +// If there is an error, it will be of type *PathError. func (f *File) Stat() (fi FileInfo, err error) { var stat syscall.Stat_t err = syscall.Fstat(f.fd, &stat) @@ -119,11 +120,8 @@ func (f *File) Stat() (fi FileInfo, err error) { return fileInfoFromStat(&stat, f.name), nil } -// Stat returns a FileInfo describing the named file and an error, if any. -// If name names a valid symbolic link, the returned FileInfo describes -// the file pointed at by the link and has fi.FollowedSymlink set to true. -// If name names an invalid symbolic link, the returned FileInfo describes -// the link itself and has fi.FollowedSymlink set to false. +// Stat returns a FileInfo describing the named file. +// If there is an error, it will be of type *PathError. func Stat(name string) (fi FileInfo, err error) { var stat syscall.Stat_t err = syscall.Stat(name, &stat) @@ -133,9 +131,10 @@ func Stat(name string) (fi FileInfo, err error) { return fileInfoFromStat(&stat, name), nil } -// Lstat returns a FileInfo describing the named file and an -// error, if any. If the file is a symbolic link, the returned FileInfo +// Lstat returns a FileInfo describing the named file. +// If the file is a symbolic link, the returned FileInfo // describes the symbolic link. Lstat makes no attempt to follow the link. +// If there is an error, it will be of type *PathError. func Lstat(name string) (fi FileInfo, err error) { var stat syscall.Stat_t err = syscall.Lstat(name, &stat) @@ -199,6 +198,7 @@ func (f *File) seek(offset int64, whence int) (ret int64, err error) { // Truncate changes the size of the named file. // If the file is a symbolic link, it changes the size of the link's target. +// If there is an error, it will be of type *PathError. func Truncate(name string, size int64) error { if e := syscall.Truncate(name, size); e != nil { return &PathError{"truncate", name, e} @@ -207,6 +207,7 @@ func Truncate(name string, size int64) error { } // Remove removes the named file or directory. +// If there is an error, it will be of type *PathError. func Remove(name string) error { // System call interface forces us to know // whether name is a file or directory. @@ -270,7 +271,7 @@ func Pipe() (r *File, w *File, err error) { syscall.CloseOnExec(p[1]) syscall.ForkLock.RUnlock() - return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil + return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil } // TempDir returns the default directory to use for temporary files. diff --git a/libgo/go/os/getwd.go b/libgo/go/os/getwd.go index 56836434dbe..81d8fed926e 100644 --- a/libgo/go/os/getwd.go +++ b/libgo/go/os/getwd.go @@ -52,7 +52,7 @@ func Getwd() (pwd string, err error) { pwd = "" for parent := ".."; ; parent = "../" + parent { if len(parent) >= 1024 { // Sanity check - return "", ENAMETOOLONG + return "", syscall.ENAMETOOLONG } fd, err := Open(parent) if err != nil { @@ -74,7 +74,7 @@ func Getwd() (pwd string, err error) { } } fd.Close() - return "", ENOENT + return "", ErrNotExist Found: pd, err := fd.Stat() diff --git a/libgo/go/os/mkunixsignals.sh b/libgo/go/os/mkunixsignals.sh deleted file mode 100644 index 3487bc3bc3c..00000000000 --- a/libgo/go/os/mkunixsignals.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2010 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -echo '// ./mkunix.sh' "$1" -echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT' -echo - -cat <<EOH -package os - -import ( - "syscall" -) - -var _ = syscall.Open // in case there are zero signals - -const ( -EOH - -sed -n 's/^const[ ]*\(SIG[A-Z0-9][A-Z0-9]*\)[ ].*/ \1 = UnixSignal(syscall.\1)/p' "$1" - -echo ")" diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index 36bb496d979..aa01669a5da 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -13,6 +13,7 @@ import ( "path/filepath" "runtime" "strings" + "syscall" "testing" "time" ) @@ -23,7 +24,6 @@ var dot = []string{ "error.go", "file.go", "os_test.go", - "time.go", "types.go", } @@ -528,7 +528,6 @@ func exec(t *testing.T, dir, cmd string, args []string, expect string) { if err != nil { t.Fatalf("StartProcess: %v", err) } - defer p.Release() w.Close() var b bytes.Buffer @@ -539,7 +538,7 @@ func exec(t *testing.T, dir, cmd string, args []string, expect string) { t.Errorf("exec %q returned %q wanted %q", strings.Join(append([]string{cmd}, args...), " "), output, expect) } - p.Wait(0) + p.Wait() } func TestStartProcess(t *testing.T) { @@ -742,19 +741,6 @@ func TestChdirAndGetwd(t *testing.T) { fd.Close() } -func TestTime(t *testing.T) { - // Just want to check that Time() is getting something. - // A common failure mode on Darwin is to get 0, 0, - // because it returns the time in registers instead of - // filling in the structure passed to the system call. - // Too bad the compiler doesn't know that - // 365.24*86400 is an integer. - sec, nsec, err := Time() - if sec < (2009-1970)*36524*864 { - t.Errorf("Time() = %d, %d, %s; not plausible", sec, nsec, err) - } -} - func TestSeek(t *testing.T) { f := newFile("TestSeek", t) defer Remove(f.Name()) @@ -781,7 +767,7 @@ func TestSeek(t *testing.T) { for i, tt := range tests { off, err := f.Seek(tt.in, tt.whence) if off != tt.out || err != nil { - if e, ok := err.(*PathError); ok && e.Err == EINVAL && tt.out > 1<<32 { + if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 { // Reiserfs rejects the big seeks. // http://code.google.com/p/go/issues/detail?id=91 break @@ -801,17 +787,17 @@ var openErrorTests = []openErrorTest{ { sfdir + "/no-such-file", O_RDONLY, - ENOENT, + syscall.ENOENT, }, { sfdir, O_WRONLY, - EISDIR, + syscall.EISDIR, }, { sfdir + "/" + sfname + "/no-such-file", O_WRONLY, - ENOTDIR, + syscall.ENOTDIR, }, } @@ -859,12 +845,11 @@ func run(t *testing.T, cmd []string) string { if err != nil { t.Fatal(err) } - defer p.Release() w.Close() var b bytes.Buffer io.Copy(&b, r) - _, err = p.Wait(0) + _, err = p.Wait() if err != nil { t.Fatalf("run hostname Wait: %v", err) } @@ -997,32 +982,66 @@ func TestAppend(t *testing.T) { } func TestStatDirWithTrailingSlash(t *testing.T) { - // Create new dir, in _test so it will get - // cleaned up by make if not by us. - path := "_test/_TestStatDirWithSlash_" - err := MkdirAll(path, 0777) + // Create new temporary directory and arrange to clean it up. + path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_") if err != nil { - t.Fatalf("MkdirAll %q: %s", path, err) + t.Fatalf("TempDir: %s", err) } defer RemoveAll(path) // Stat of path should succeed. _, err = Stat(path) if err != nil { - t.Fatal("stat failed:", err) + t.Fatalf("stat %s failed: %s", path, err) } // Stat of path+"/" should succeed too. - _, err = Stat(path + "/") + path += "/" + _, err = Stat(path) if err != nil { - t.Fatal("stat failed:", err) + t.Fatalf("stat %s failed: %s", path, err) } } -func TestNilWaitmsgString(t *testing.T) { - var w *Waitmsg - s := w.String() +func TestNilProcessStateString(t *testing.T) { + var ps *ProcessState + s := ps.String() if s != "<nil>" { - t.Errorf("(*Waitmsg)(nil).String() = %q, want %q", s, "<nil>") + t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>") + } +} + +func TestSameFile(t *testing.T) { + fa, err := Create("a") + if err != nil { + t.Fatalf("Create(a): %v", err) + } + defer Remove(fa.Name()) + fa.Close() + fb, err := Create("b") + if err != nil { + t.Fatalf("Create(b): %v", err) + } + defer Remove(fb.Name()) + fb.Close() + + ia1, err := Stat("a") + if err != nil { + t.Fatalf("Stat(a): %v", err) + } + ia2, err := Stat("a") + if err != nil { + t.Fatalf("Stat(a): %v", err) + } + if !SameFile(ia1, ia2) { + t.Errorf("files should be same") + } + + ib, err := Stat("b") + if err != nil { + t.Fatalf("Stat(b): %v", err) + } + if SameFile(ia1, ib) { + t.Errorf("files should be different") } } diff --git a/libgo/go/os/path.go b/libgo/go/os/path.go index e962f3e397b..02a77ec8051 100644 --- a/libgo/go/os/path.go +++ b/libgo/go/os/path.go @@ -4,7 +4,10 @@ package os -import "io" +import ( + "io" + "syscall" +) // MkdirAll creates a directory named path, // along with any necessary parents, and returns nil, @@ -20,7 +23,7 @@ func MkdirAll(path string, perm FileMode) error { if dir.IsDir() { return nil } - return &PathError{"mkdir", path, ENOTDIR} + return &PathError{"mkdir", path, syscall.ENOTDIR} } // Doesn't already exist; make sure parent does. @@ -70,7 +73,7 @@ func RemoveAll(path string) error { // Otherwise, is this a directory we need to recurse into? dir, serr := Lstat(path) if serr != nil { - if serr, ok := serr.(*PathError); ok && (serr.Err == ENOENT || serr.Err == ENOTDIR) { + if serr, ok := serr.(*PathError); ok && (IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) { return nil } return serr diff --git a/libgo/go/os/path_test.go b/libgo/go/os/path_test.go index 18634ba410e..c1e3fb35436 100644 --- a/libgo/go/os/path_test.go +++ b/libgo/go/os/path_test.go @@ -8,18 +8,18 @@ import ( . "os" "path/filepath" "runtime" + "syscall" "testing" ) func TestMkdirAll(t *testing.T) { - // Create new dir, in _test so it will get - // cleaned up by make if not by us. - path := "_test/_TestMkdirAll_/dir/./dir2" + tmpDir := TempDir() + path := tmpDir + "/_TestMkdirAll_/dir/./dir2" err := MkdirAll(path, 0777) if err != nil { t.Fatalf("MkdirAll %q: %s", path, err) } - defer RemoveAll("_test/_TestMkdirAll_") + defer RemoveAll(tmpDir + "/_TestMkdirAll_") // Already exists, should succeed. err = MkdirAll(path, 0777) @@ -63,7 +63,7 @@ func TestMkdirAll(t *testing.T) { } if runtime.GOOS == "windows" { - path := `_test\_TestMkdirAll_\dir\.\dir2\` + path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\` err := MkdirAll(path, 0777) if err != nil { t.Fatalf("MkdirAll %q: %s", path, err) @@ -72,8 +72,9 @@ func TestMkdirAll(t *testing.T) { } func TestRemoveAll(t *testing.T) { + tmpDir := TempDir() // Work directory. - path := "_test/_TestRemoveAll_" + path := tmpDir + "/_TestRemoveAll_" fpath := path + "/file" dpath := path + "/dir" @@ -170,19 +171,22 @@ func TestMkdirAllWithSymlink(t *testing.T) { return } - err := Mkdir("_test/dir", 0755) + tmpDir := TempDir() + dir := tmpDir + "/dir" + err := Mkdir(dir, 0755) if err != nil { - t.Fatal(`Mkdir "_test/dir":`, err) + t.Fatalf("Mkdir %s: %s", dir, err) } - defer RemoveAll("_test/dir") + defer RemoveAll(dir) - err = Symlink("dir", "_test/link") + link := tmpDir + "/link" + err = Symlink("dir", link) if err != nil { - t.Fatal(`Symlink "dir", "_test/link":`, err) + t.Fatalf("Symlink %s: %s", link, err) } - defer RemoveAll("_test/link") + defer RemoveAll(link) - path := "_test/link/foo" + path := link + "/foo" err = MkdirAll(path, 0755) if err != nil { t.Errorf("MkdirAll %q: %s", path, err) @@ -198,7 +202,7 @@ func TestMkdirAllAtSlash(t *testing.T) { if err != nil { pathErr, ok := err.(*PathError) // common for users not to be able to write to / - if ok && pathErr.Err == EACCES { + if ok && pathErr.Err == syscall.EACCES { return } t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err) diff --git a/libgo/go/os/signal/signal.go b/libgo/go/os/signal/signal.go new file mode 100644 index 00000000000..dfdcf406173 --- /dev/null +++ b/libgo/go/os/signal/signal.go @@ -0,0 +1,72 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package signal implements access to incoming signals. +package signal + +// BUG(rsc): This package is not yet implemented on Plan 9 and Windows. + +import ( + "os" + "sync" +) + +var handlers struct { + sync.Mutex + list []handler +} + +type handler struct { + c chan<- os.Signal + sig os.Signal + all bool +} + +// Notify causes package signal to relay incoming signals to c. +// If no signals are listed, all incoming signals will be relayed to c. +// Otherwise, just the listed signals will. +// +// Package signal will not block sending to c: the caller must ensure +// that c has sufficient buffer space to keep up with the expected +// signal rate. For a channel used for notification of just one signal value, +// a buffer of size 1 is sufficient. +// +func Notify(c chan<- os.Signal, sig ...os.Signal) { + if c == nil { + panic("os/signal: Notify using nil channel") + } + + handlers.Lock() + defer handlers.Unlock() + if len(sig) == 0 { + enableSignal(nil) + handlers.list = append(handlers.list, handler{c: c, all: true}) + } else { + for _, s := range sig { + // We use nil as a special wildcard value for enableSignal, + // so filter it out of the list of arguments. This is safe because + // we will never get an incoming nil signal, so discarding the + // registration cannot affect the observed behavior. + if s != nil { + enableSignal(s) + handlers.list = append(handlers.list, handler{c: c, sig: s}) + } + } + } +} + +func process(sig os.Signal) { + handlers.Lock() + defer handlers.Unlock() + + for _, h := range handlers.list { + if h.all || h.sig == sig { + // send but do not block for it + select { + case h.c <- sig: + default: + } + } + } +} diff --git a/libgo/go/os/signal/signal_stub.go b/libgo/go/os/signal/signal_stub.go new file mode 100644 index 00000000000..fc227cf4c2d --- /dev/null +++ b/libgo/go/os/signal/signal_stub.go @@ -0,0 +1,11 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build plan9 + +package signal + +import "os" + +func enableSignal(sig os.Signal) {} diff --git a/libgo/go/os/signal/signal_test.go b/libgo/go/os/signal/signal_test.go new file mode 100644 index 00000000000..3494f8c34cb --- /dev/null +++ b/libgo/go/os/signal/signal_test.go @@ -0,0 +1,60 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd linux netbsd openbsd + +package signal + +import ( + "os" + "syscall" + "testing" + "time" +) + +const sighup = syscall.SIGHUP + +func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { + select { + case s := <-c: + if s != sig { + t.Fatalf("signal was %v, want %v", s, sig) + } + case <-time.After(1 * time.Second): + t.Fatalf("timeout waiting for %v", sig) + } +} + +func TestSignal(t *testing.T) { + // Ask for SIGHUP + c := make(chan os.Signal, 1) + Notify(c, sighup) + + t.Logf("sighup...") + // Send this process a SIGHUP + syscall.Kill(syscall.Getpid(), sighup) + waitSig(t, c, sighup) + + // Ask for everything we can get. + c1 := make(chan os.Signal, 1) + Notify(c1) + + t.Logf("sigwinch...") + // Send this process a SIGWINCH + syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) + waitSig(t, c1, syscall.SIGWINCH) + + // Send two more SIGHUPs, to make sure that + // they get delivered on c1 and that not reading + // from c does not block everything. + t.Logf("sigwinch...") + syscall.Kill(syscall.Getpid(), syscall.SIGHUP) + waitSig(t, c1, syscall.SIGHUP) + t.Logf("sigwinch...") + syscall.Kill(syscall.Getpid(), syscall.SIGHUP) + waitSig(t, c1, syscall.SIGHUP) + + // The first SIGHUP should be waiting for us on c. + waitSig(t, c, syscall.SIGHUP) +} diff --git a/libgo/go/os/signal/signal_unix.go b/libgo/go/os/signal/signal_unix.go new file mode 100644 index 00000000000..20ee5f26aaa --- /dev/null +++ b/libgo/go/os/signal/signal_unix.go @@ -0,0 +1,38 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd linux netbsd openbsd windows + +package signal + +import ( + "os" + "syscall" +) + +// In assembly. +func signal_enable(uint32) +func signal_recv() uint32 + +func loop() { + for { + process(syscall.Signal(signal_recv())) + } +} + +func init() { + signal_enable(0) // first call - initialize + go loop() +} + +func enableSignal(sig os.Signal) { + switch sig := sig.(type) { + case nil: + signal_enable(^uint32(0)) + case syscall.Signal: + signal_enable(uint32(sig)) + default: + // Can ignore: this signal (whatever it is) will never come in. + } +} diff --git a/libgo/go/os/stat_plan9.go b/libgo/go/os/stat_plan9.go index 7c2d1bd4efc..a7990a359ec 100644 --- a/libgo/go/os/stat_plan9.go +++ b/libgo/go/os/stat_plan9.go @@ -62,7 +62,7 @@ func dirstat(arg interface{}) (d *Dir, err error) { return nil, &PathError{"stat", name, err} } if n < syscall.STATFIXLEN { - return nil, &PathError{"stat", name, Eshortstat} + return nil, &PathError{"stat", name, errShortStat} } // Pull the real size out of the stat message. @@ -79,10 +79,11 @@ func dirstat(arg interface{}) (d *Dir, err error) { return } } - return nil, &PathError{"stat", name, Ebadstat} + return nil, &PathError{"stat", name, errBadStat} } -// Stat returns a FileInfo structure describing the named file and an error, if any. +// Stat returns a FileInfo structure describing the named file. +// If there is an error, it will be of type *PathError. func Stat(name string) (FileInfo, error) { d, err := dirstat(name) if err != nil { @@ -91,9 +92,10 @@ func Stat(name string) (FileInfo, error) { return fileInfoFromStat(d), nil } -// Lstat returns the FileInfo structure describing the named file and an -// error, if any. If the file is a symbolic link (though Plan 9 does not have symbolic links), +// Lstat returns the FileInfo structure describing the named file. +// If the file is a symbolic link (though Plan 9 does not have symbolic links), // the returned FileInfo describes the symbolic link. Lstat makes no attempt to follow the link. +// If there is an error, it will be of type *PathError. func Lstat(name string) (FileInfo, error) { return Stat(name) } diff --git a/libgo/go/os/time.go b/libgo/go/os/time.go deleted file mode 100644 index eb564e57a6c..00000000000 --- a/libgo/go/os/time.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package os - -import "syscall" - -// Time returns the current time, in whole seconds and -// fractional nanoseconds, plus an error if any. The current -// time is thus 1e9*sec+nsec, in nanoseconds. The zero of -// time is the Unix epoch. -func Time() (sec int64, nsec int64, err error) { - var tv syscall.Timeval - if e := syscall.Gettimeofday(&tv); e != nil { - return 0, 0, NewSyscallError("gettimeofday", e) - } - return int64(tv.Sec), int64(tv.Usec) * 1000, err -} diff --git a/libgo/go/path/example_test.go b/libgo/go/path/example_test.go index f0ac1301408..ca18b32305e 100644 --- a/libgo/go/path/example_test.go +++ b/libgo/go/path/example_test.go @@ -11,17 +11,11 @@ import ( "path" ) -// b func ExampleBase() { fmt.Println(path.Base("/a/b")) + // Output: b } -// Clean("a/c") = "a/c" -// Clean("a//c") = "a/c" -// Clean("a/c/.") = "a/c" -// Clean("a/c/b/..") = "a/c" -// Clean("/../a/c") = "/a/c" -// Clean("/../a/b/../././/c") = "/a/c" func ExampleClean() { paths := []string{ "a/c", @@ -35,31 +29,39 @@ func ExampleClean() { for _, p := range paths { fmt.Printf("Clean(%q) = %q\n", p, path.Clean(p)) } + + // Output: + // Clean("a/c") = "a/c" + // Clean("a//c") = "a/c" + // Clean("a/c/.") = "a/c" + // Clean("a/c/b/..") = "a/c" + // Clean("/../a/c") = "/a/c" + // Clean("/../a/b/../././/c") = "/a/c" } -// /a/b func ExampleDir() { fmt.Println(path.Dir("/a/b/c")) + // Output: /a/b } -// .css func ExampleExt() { fmt.Println(path.Ext("/a/b/c/bar.css")) + // Output: .css } -// true func ExampleIsAbs() { fmt.Println(path.IsAbs("/dev/null")) + // Output: true } -// a/b/c func ExampleJoin() { fmt.Println(path.Join("a", "b", "c")) + // Output: a/b/c } -// static/ myfile.css func ExampleSplit() { fmt.Println(path.Split("static/myfile.css")) + // Output: static/ myfile.css } */ diff --git a/libgo/go/path/filepath/match.go b/libgo/go/path/filepath/match.go index c3678f541d4..38d264fb97a 100644 --- a/libgo/go/path/filepath/match.go +++ b/libgo/go/path/filepath/match.go @@ -12,6 +12,7 @@ import ( "unicode/utf8" ) +// ErrBadPattern indicates a globbing pattern was malformed. var ErrBadPattern = errors.New("syntax error in pattern") // Match returns true if name matches the shell file name pattern. @@ -33,7 +34,8 @@ var ErrBadPattern = errors.New("syntax error in pattern") // lo '-' hi matches character c for lo <= c <= hi // // Match requires pattern to match all of name, not just a substring. -// The only possible error return occurs when the pattern is malformed. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. // func Match(pattern, name string) (matched bool, err error) { Pattern: @@ -211,7 +213,6 @@ func getEsc(chunk string) (r rune, nchunk string, err error) { // if there is no matching file. The syntax of patterns is the same // as in Match. The pattern may describe hierarchical names such as // /usr/*/bin/ed (assuming the Separator is '/'). -// The only possible error return occurs when the pattern is malformed. // func Glob(pattern string) (matches []string, err error) { if !hasMeta(pattern) { @@ -253,7 +254,6 @@ func Glob(pattern string) (matches []string, err error) { // and appends them to matches. If the directory cannot be // opened, it returns the existing matches. New matches are // added in lexicographical order. -// The only possible error return occurs when the pattern is malformed. func glob(dir, pattern string, matches []string) (m []string, e error) { m = matches fi, err := os.Stat(dir) diff --git a/libgo/go/path/filepath/path.go b/libgo/go/path/filepath/path.go index 3dc52aab467..cfe46981f13 100644 --- a/libgo/go/path/filepath/path.go +++ b/libgo/go/path/filepath/path.go @@ -36,7 +36,7 @@ const ( // returns the string ".". // // See also Rob Pike, ``Lexical File Names in Plan 9 or -// Getting Dot-Dot right,'' +// Getting Dot-Dot Right,'' // http://plan9.bell-labs.com/sys/doc/lexnames.html func Clean(path string) string { vol := VolumeName(path) @@ -118,7 +118,8 @@ func Clean(path string) string { } // ToSlash returns the result of replacing each separator character -// in path with a slash ('/') character. +// in path with a slash ('/') character. Multiple separators are +// replaced by multiple slashes. func ToSlash(path string) string { if Separator == '/' { return path @@ -127,7 +128,8 @@ func ToSlash(path string) string { } // FromSlash returns the result of replacing each slash ('/') character -// in path with a separator character. +// in path with a separator character. Multiple slashes are replaced +// by multiple separators. func FromSlash(path string) string { if Separator == '/' { return path @@ -135,7 +137,9 @@ func FromSlash(path string) string { return strings.Replace(path, "/", string(Separator), -1) } -// SplitList splits a list of paths joined by the OS-specific ListSeparator. +// SplitList splits a list of paths joined by the OS-specific ListSeparator, +// usually found in PATH or GOPATH environment variables. +// Unlike strings.Split, SplitList returns an empty slice when passed an empty string. func SplitList(path string) []string { if path == "" { return []string{} @@ -158,7 +162,8 @@ func Split(path string) (dir, file string) { } // Join joins any number of path elements into a single path, adding -// a Separator if necessary. All empty strings are ignored. +// a Separator if necessary. The result is Cleaned, in particular +// all empty strings are ignored. func Join(elem ...string) string { for i, e := range elem { if e != "" { @@ -183,7 +188,8 @@ func Ext(path string) string { // EvalSymlinks returns the path name after the evaluation of any symbolic // links. -// If path is relative it will be evaluated relative to the current directory. +// If path is relative the result will be relative to the current directory, +// unless one of the components is an absolute symbolic link. func EvalSymlinks(path string) (string, error) { if runtime.GOOS == "windows" { // Symlinks are not supported under windows. @@ -443,7 +449,7 @@ func Base(path string) string { return path } -// Dir returns the all but the last element of path, typically the path's directory. +// Dir returns all but the last element of path, typically the path's directory. // Trailing path separators are removed before processing. // If the path is empty, Dir returns ".". // If the path consists entirely of separators, Dir returns a single separator. diff --git a/libgo/go/path/filepath/path_plan9.go b/libgo/go/path/filepath/path_plan9.go index 17b873f1a9b..cf028a75c52 100644 --- a/libgo/go/path/filepath/path_plan9.go +++ b/libgo/go/path/filepath/path_plan9.go @@ -17,7 +17,7 @@ func VolumeName(path string) string { return "" } -// HasPrefix tests whether the path p begins with prefix. +// HasPrefix exists for historical compatibility and should not be used. func HasPrefix(p, prefix string) bool { return strings.HasPrefix(p, prefix) } diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go index fdcc637759c..93cca1e4c2b 100644 --- a/libgo/go/path/filepath/path_test.go +++ b/libgo/go/path/filepath/path_test.go @@ -356,7 +356,7 @@ func TestWalk(t *testing.T) { // Test permission errors. Only possible if we're not root // and only on some file systems (AFS, FAT). To avoid errors during - // all.bash on those file systems, skip during gotest -short. + // all.bash on those file systems, skip during go test -short. if os.Getuid() > 0 && !testing.Short() { // introduce 2 errors: chmod top-level directories to 0 os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0) @@ -558,6 +558,7 @@ var EvalSymlinksTestDirs = []EvalSymlinksTest{ {"test/dir/link3", "../../"}, {"test/link1", "../test"}, {"test/link2", "dir"}, + {"test/linkabs", "/"}, } var EvalSymlinksTests = []EvalSymlinksTest{ @@ -570,6 +571,7 @@ var EvalSymlinksTests = []EvalSymlinksTest{ {"test/link2/..", "test"}, {"test/dir/link3", "."}, {"test/link2/link3/test", "test"}, + {"test/linkabs", "/"}, } var EvalSymlinksAbsWindowsTests = []EvalSymlinksTest{ @@ -628,6 +630,9 @@ func TestEvalSymlinks(t *testing.T) { for _, d := range tests { path := simpleJoin(tmpDir, d.path) dest := simpleJoin(tmpDir, d.dest) + if filepath.IsAbs(d.dest) { + dest = d.dest + } if p, err := filepath.EvalSymlinks(path); err != nil { t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) } else if filepath.Clean(p) != filepath.Clean(dest) { diff --git a/libgo/go/path/filepath/path_unix.go b/libgo/go/path/filepath/path_unix.go index c5ac71efe21..305e307272f 100644 --- a/libgo/go/path/filepath/path_unix.go +++ b/libgo/go/path/filepath/path_unix.go @@ -19,7 +19,7 @@ func VolumeName(path string) string { return "" } -// HasPrefix tests whether the path p begins with prefix. +// HasPrefix exists for historical compatibility and should not be used. func HasPrefix(p, prefix string) bool { return strings.HasPrefix(p, prefix) } diff --git a/libgo/go/path/filepath/path_windows.go b/libgo/go/path/filepath/path_windows.go index 9692fd978c5..1d1d23bfe7c 100644 --- a/libgo/go/path/filepath/path_windows.go +++ b/libgo/go/path/filepath/path_windows.go @@ -67,8 +67,7 @@ func VolumeName(path string) (v string) { return "" } -// HasPrefix tests whether the path p begins with prefix. -// It ignores case while comparing. +// HasPrefix exists for historical compatibility and should not be used. func HasPrefix(p, prefix string) bool { if strings.HasPrefix(p, prefix) { return true diff --git a/libgo/go/path/match.go b/libgo/go/path/match.go index ba7e4de321e..8154bf60251 100644 --- a/libgo/go/path/match.go +++ b/libgo/go/path/match.go @@ -10,6 +10,7 @@ import ( "unicode/utf8" ) +// ErrBadPattern indicates a globbing pattern was malformed. var ErrBadPattern = errors.New("syntax error in pattern") // Match returns true if name matches the shell file name pattern. @@ -31,7 +32,8 @@ var ErrBadPattern = errors.New("syntax error in pattern") // lo '-' hi matches character c for lo <= c <= hi // // Match requires pattern to match all of name, not just a substring. -// The only possible error return is when pattern is malformed. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. // func Match(pattern, name string) (matched bool, err error) { Pattern: diff --git a/libgo/go/path/path.go b/libgo/go/path/path.go index 20d89c9ff0c..13abed0b09d 100644 --- a/libgo/go/path/path.go +++ b/libgo/go/path/path.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package path implements utility routines for manipulating slash-separated -// filename paths. +// paths. package path import ( @@ -25,7 +25,7 @@ import ( // returns the string ".". // // See also Rob Pike, ``Lexical File Names in Plan 9 or -// Getting Dot-Dot right,'' +// Getting Dot-Dot Right,'' // http://plan9.bell-labs.com/sys/doc/lexnames.html func Clean(path string) string { if path == "" { @@ -100,17 +100,19 @@ func Clean(path string) string { return string(buf[0:w]) } -// Split splits path immediately following the final path separator, +// Split splits path immediately following the final slash. // separating it into a directory and file name component. -// If there is no separator in path, Split returns an empty dir and +// If there is no slash path, Split returns an empty dir and // file set to path. +// The returned values have the property that path = dir+file. func Split(path string) (dir, file string) { i := strings.LastIndex(path, "/") return path[:i+1], path[i+1:] } // Join joins any number of path elements into a single path, adding a -// separating slash if necessary. All empty strings are ignored. +// separating slash if necessary. The result is Cleaned; in particular, +// all empty strings are ignored. func Join(elem ...string) string { for i, e := range elem { if e != "" { @@ -161,11 +163,12 @@ func IsAbs(path string) bool { return len(path) > 0 && path[0] == '/' } -// Dir returns the all but the last element of path, typically the path's directory. -// Trailing path separators are removed before processing. +// Dir returns all but the last element of path, typically the path's directory. +// The path is Cleaned and trailing slashes are removed before processing. // If the path is empty, Dir returns ".". -// If the path consists entirely of separators, Dir returns a single separator. -// The returned path does not end in a separator unless it is the root directory. +// If the path consists entirely of slashes followed by non-slash bytes, Dir +// returns a single slash. In any other case, the returned path does not end in a +// slash. func Dir(path string) string { dir, _ := Split(path) dir = Clean(dir) diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 557fb8e843e..56744a514bc 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -629,6 +629,13 @@ type DeepEqualTest struct { eq bool } +// Simple functions for DeepEqual tests. +var ( + fn1 func() // nil. + fn2 func() // nil. + fn3 = func() { fn1() } // Not nil. +) + var deepEqualTests = []DeepEqualTest{ // Equalities {1, 1, true}, @@ -641,6 +648,7 @@ var deepEqualTests = []DeepEqualTest{ {Basic{1, 0.5}, Basic{1, 0.5}, true}, {error(nil), error(nil), true}, {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true}, + {fn1, fn2, true}, // Inequalities {1, 2, false}, @@ -658,6 +666,8 @@ var deepEqualTests = []DeepEqualTest{ {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false}, {nil, 1, false}, {1, nil, false}, + {fn1, fn3, false}, + {fn3, fn3, false}, // Nil vs empty: not the same. {[]int{}, []int(nil), false}, @@ -1737,3 +1747,15 @@ func isValid(v Value) { panic("zero Value") } } + +func TestAlias(t *testing.T) { + x := string("hello") + v := ValueOf(&x).Elem() + oldvalue := v.Interface() + v.SetString("world") + newvalue := v.Interface() + + if oldvalue != "hello" || newvalue != "world" { + t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue) + } +} diff --git a/libgo/go/reflect/deepequal.go b/libgo/go/reflect/deepequal.go index df5ec0a6099..c12e90f36cc 100644 --- a/libgo/go/reflect/deepequal.go +++ b/libgo/go/reflect/deepequal.go @@ -108,6 +108,12 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool } } return true + case Func: + if v1.IsNil() && v2.IsNil() { + return true + } + // Can't do better than this: + return false default: // Normal equality suffices return valueInterface(v1, false) == valueInterface(v2, false) @@ -117,8 +123,8 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool } // DeepEqual tests for deep equality. It uses normal == equality where possible -// but will scan members of arrays, slices, and fields of structs. It correctly -// handles recursive types. +// but will scan members of arrays, slices, maps, and fields of structs. It correctly +// handles recursive types. Functions are equal only if they are both nil. func DeepEqual(a1, a2 interface{}) bool { if a1 == nil || a2 == nil { return a1 == a2 diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 1bb0a26b7a6..b1dd0a1fecd 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -12,11 +12,10 @@ // for that type. // // See "The Laws of Reflection" for an introduction to reflection in Go: -// http://blog.golang.org/2011/09/laws-of-reflection.html +// http://golang.org/doc/articles/laws_of_reflection.html package reflect import ( - "runtime" "strconv" "sync" "unsafe" @@ -181,7 +180,7 @@ type Type interface { // It panics if i is not in the range [0, NumOut()). Out(i int) Type - runtimeType() *runtime.Type + runtimeType() *runtimeType common() *commonType uncommon() *uncommonType } @@ -221,127 +220,127 @@ const ( ) /* - * Copy of data structures from ../runtime/type.go. - * For comments, see the ones in that file. - * - * These data structures are known to the compiler and the runtime. - * - * Putting these types in runtime instead of reflect means that - * reflect doesn't need to be autolinked into every binary, which - * simplifies bootstrapping and package dependencies. - * Unfortunately, it also means that reflect needs its own - * copy in order to access the private fields. + * These data structures are known to the compiler (../../cmd/gc/reflect.c). + * A few are known to ../runtime/type.go to convey to debuggers. */ +type runtimeType commonType + // commonType is the common implementation of most values. // It is embedded in other, public struct types, but always // with a unique tag like `reflect:"array"` or `reflect:"ptr"` // so that code cannot convert from, say, *arrayType to *ptrType. - type commonType struct { - kind uint8 - align int8 - fieldAlign uint8 - size uintptr - hash uint32 - hashfn func(unsafe.Pointer, uintptr) - equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) - string *string - *uncommonType - ptrToThis *runtime.Type + kind uint8 // enumeration for C + align int8 // alignment of variable with this type + fieldAlign uint8 // alignment of struct field with this type + size uintptr // size in bytes + hash uint32 // hash of type; avoids computation in hash tables + + hashfn func(unsafe.Pointer, uintptr) // hash function + equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function + + string *string // string form; unnecessary but undeniably useful + *uncommonType // (relatively) uncommon fields + ptrToThis *runtimeType // pointer to this type, if used in binary or has methods } +// Method on non-interface type type method struct { - name *string - pkgPath *string - mtyp *runtime.Type - typ *runtime.Type - tfn unsafe.Pointer + name *string // name of method + pkgPath *string // nil for exported Names; otherwise import path + mtyp *runtimeType // method type (without receiver) + typ *runtimeType // .(*FuncType) underneath (with receiver) + tfn unsafe.Pointer // fn used for normal method call } +// uncommonType is present only for types with names or methods +// (if T is a named type, the uncommonTypes for T and *T have methods). +// Using a pointer to this struct reduces the overall size required +// to describe an unnamed type with no methods. type uncommonType struct { - name *string - pkgPath *string - methods []method + name *string // name of type + pkgPath *string // import path; nil for built-in types like int, string + methods []method // methods associated with type } // ChanDir represents a channel type's direction. type ChanDir int const ( - RecvDir ChanDir = 1 << iota - SendDir - BothDir = RecvDir | SendDir + RecvDir ChanDir = 1 << iota // <-chan + SendDir // chan<- + BothDir = RecvDir | SendDir // chan ) // arrayType represents a fixed array type. type arrayType struct { commonType `reflect:"array"` - elem *runtime.Type - slice *runtime.Type + elem *runtimeType // array element type + slice *runtimeType // slice type len uintptr } // chanType represents a channel type. type chanType struct { commonType `reflect:"chan"` - elem *runtime.Type - dir uintptr + elem *runtimeType // channel element type + dir uintptr // channel direction (ChanDir) } // funcType represents a function type. type funcType struct { commonType `reflect:"func"` - dotdotdot bool - in []*runtime.Type - out []*runtime.Type + dotdotdot bool // last input parameter is ... + in []*runtimeType // input parameter types + out []*runtimeType // output parameter types } // imethod represents a method on an interface type type imethod struct { - name *string - pkgPath *string - typ *runtime.Type + name *string // name of method + pkgPath *string // nil for exported Names; otherwise import path + typ *runtimeType // .(*FuncType) underneath } // interfaceType represents an interface type. type interfaceType struct { commonType `reflect:"interface"` - methods []imethod + methods []imethod // sorted by hash } // mapType represents a map type. type mapType struct { commonType `reflect:"map"` - key *runtime.Type - elem *runtime.Type + key *runtimeType // map key type + elem *runtimeType // map element (value) type } // ptrType represents a pointer type. type ptrType struct { commonType `reflect:"ptr"` - elem *runtime.Type + elem *runtimeType // pointer element (pointed at) type } // sliceType represents a slice type. type sliceType struct { commonType `reflect:"slice"` - elem *runtime.Type + elem *runtimeType // slice element type } // Struct field type structField struct { - name *string - pkgPath *string - typ *runtime.Type - tag *string - offset uintptr + name *string // nil for embedded fields + pkgPath *string // nil for exported Names; otherwise import path + typ *runtimeType // type of field + tag *string // nil if no tag + offset uintptr // byte offset of field within struct } // structType represents a struct type. type structType struct { commonType `reflect:"struct"` - fields []structField + fields []structField // sorted by offset } /* @@ -559,7 +558,7 @@ func (t *commonType) Elem() Type { tt := (*sliceType)(unsafe.Pointer(t)) return toType(tt.elem) } - panic("reflect; Elem of invalid type") + panic("reflect: Elem of invalid type") } func (t *commonType) Field(i int) StructField { @@ -628,7 +627,7 @@ func (t *commonType) NumField() int { func (t *commonType) NumIn() int { if t.Kind() != Func { - panic("reflect; NumIn of non-func type") + panic("reflect: NumIn of non-func type") } tt := (*funcType)(unsafe.Pointer(t)) return len(tt.in) @@ -636,7 +635,7 @@ func (t *commonType) NumIn() int { func (t *commonType) NumOut() int { if t.Kind() != Func { - panic("reflect; NumOut of non-func type") + panic("reflect: NumOut of non-func type") } tt := (*funcType)(unsafe.Pointer(t)) return len(tt.out) @@ -909,12 +908,11 @@ func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, pr } // Convert runtime type to reflect type. -func toCommonType(p *runtime.Type) *commonType { +func toCommonType(p *runtimeType) *commonType { if p == nil { return nil } - x := unsafe.Pointer(p) - return (*commonType)(x) + return (*commonType)(unsafe.Pointer(p)) } // Canonicalize a Type. @@ -949,11 +947,11 @@ func canonicalize(t Type) Type { return t } -func toType(p *runtime.Type) Type { +func toType(p *runtimeType) Type { if p == nil { return nil } - return toCommonType(p).toType() + return (*commonType)(unsafe.Pointer(p)) } // TypeOf returns the reflection Type of the value in the interface{}. @@ -968,8 +966,8 @@ var ptrMap struct { m map[*commonType]*ptrType } -func (t *commonType) runtimeType() *runtime.Type { - return (*runtime.Type)(unsafe.Pointer(t)) +func (t *commonType) runtimeType() *runtimeType { + return (*runtimeType)(unsafe.Pointer(t)) } // PtrTo returns the pointer type with element t. @@ -1018,13 +1016,10 @@ func (ct *commonType) ptrTo() *commonType { return r.(*commonType) } - rp := new(runtime.PtrType) - // initialize p using *byte's ptrType as a prototype. - // have to do assignment as ptrType, not runtime.PtrType, - // in order to write to unexported fields. - p = (*ptrType)(unsafe.Pointer(rp)) - bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType))) + p = new(ptrType) + var ibyte interface{} = (*byte)(nil) + bp := (*ptrType)(unsafe.Pointer(*(**runtimeType)(unsafe.Pointer(&ibyte)))) *p = *bp p.string = &s @@ -1040,7 +1035,7 @@ func (ct *commonType) ptrTo() *commonType { p.uncommonType = nil p.ptrToThis = nil - p.elem = (*runtime.Type)(unsafe.Pointer(ct)) + p.elem = (*runtimeType)(unsafe.Pointer(ct)) p = canonicalize(p).(*ptrType) diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index a1bc3342620..b490e99f409 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -207,7 +207,7 @@ func storeIword(p unsafe.Pointer, w iword, n uintptr) { // emptyInterface is the header for an interface{} value. type emptyInterface struct { - typ *runtime.Type + typ *runtimeType word iword } @@ -215,7 +215,7 @@ type emptyInterface struct { type nonEmptyInterface struct { // see ../runtime/iface.c:/Itab itab *struct { - typ *runtime.Type // dynamic concrete type + typ *runtimeType // dynamic concrete type fun [100000]unsafe.Pointer // method table } word iword @@ -692,7 +692,7 @@ func (v Value) FieldByNameFunc(match func(string) bool) Value { return Value{} } -// Float returns v's underlying value, as an float64. +// Float returns v's underlying value, as a float64. // It panics if v's Kind is not Float32 or Float64 func (v Value) Float() float64 { k := v.kind() @@ -792,11 +792,15 @@ func (v Value) CanInterface() bool { return v.flag&(flagMethod|flagRO) == 0 } -// Interface returns v's value as an interface{}. +// Interface returns v's current value as an interface{}. +// It is equivalent to: +// var i interface{} = (v's underlying value) // If v is a method obtained by invoking Value.Method // (as opposed to Type.Method), Interface cannot return an // interface value, so it panics. -func (v Value) Interface() interface{} { +// It also panics if the Value was obtained by accessing +// unexported struct fields. +func (v Value) Interface() (i interface{}) { return valueInterface(v, true) } @@ -832,6 +836,16 @@ func valueInterface(v Value, safe bool) interface{} { var eface emptyInterface eface.typ = v.typ.runtimeType() eface.word = v.iword() + + if v.flag&flagIndir != 0 && v.typ.size > ptrSize { + // eface.word is a pointer to the actual data, + // which might be changed. We need to return + // a pointer to unchanging data, so make a copy. + ptr := unsafe_New(v.typ) + memmove(ptr, unsafe.Pointer(eface.word), v.typ.size) + eface.word = iword(ptr) + } + return *(*interface{})(unsafe.Pointer(&eface)) } @@ -1244,7 +1258,8 @@ func (v Value) SetInt(x int64) { } // SetLen sets v's length to n. -// It panics if v's Kind is not Slice. +// It panics if v's Kind is not Slice or if n is negative or +// greater than the capacity of the slice. func (v Value) SetLen(n int) { v.mustBeAssignable() v.mustBe(Slice) @@ -1595,6 +1610,10 @@ func Copy(dst, src Value) int { * constructors */ +// implemented in package runtime +func unsafe_New(Type) unsafe.Pointer +func unsafe_NewArray(Type, int) unsafe.Pointer + // MakeSlice creates a new zero-initialized slice value // for the specified slice type, length, and capacity. func MakeSlice(typ Type, len, cap int) Value { @@ -1607,7 +1626,7 @@ func MakeSlice(typ Type, len, cap int) Value { // Reinterpret as *SliceHeader to edit. s := (*SliceHeader)(unsafe.Pointer(&x)) - s.Data = uintptr(unsafe.NewArray(typ.Elem(), cap)) + s.Data = uintptr(unsafe_NewArray(typ.Elem(), cap)) s.Len = len s.Cap = cap @@ -1639,7 +1658,7 @@ func MakeMap(typ Type) Value { } // Indirect returns the value that v points to. -// If v is a nil pointer, Indirect returns a nil Value. +// If v is a nil pointer, Indirect returns a zero Value. // If v is not a pointer, Indirect returns v. func Indirect(v Value) Value { if v.Kind() != Ptr { @@ -1686,7 +1705,7 @@ func Zero(typ Type) Value { if t.Kind() == Ptr || t.Kind() == UnsafePointer { return Value{t, nil, fl} } - return Value{t, unsafe.New(typ), fl | flagIndir} + return Value{t, unsafe_New(typ), fl | flagIndir} } // New returns a Value representing a pointer to a new zero value @@ -1695,11 +1714,18 @@ func New(typ Type) Value { if typ == nil { panic("reflect: New(nil)") } - ptr := unsafe.New(typ) + ptr := unsafe_New(typ) fl := flag(Ptr) << flagKindShift return Value{typ.common().ptrTo(), ptr, fl} } +// NewAt returns a Value representing a pointer to a value of the +// specified type, using p as that pointer. +func NewAt(typ Type, p unsafe.Pointer) Value { + fl := flag(Ptr) << flagKindShift + return Value{typ.common().ptrTo(), p, fl} +} + // assignTo returns a value v that can be assigned directly to typ. // It panics if v is not assignable to typ. // For a conversion to an interface type, target is a suggested scratch space to use. @@ -1738,20 +1764,20 @@ func (v Value) assignTo(context string, dst *commonType, target *interface{}) Va func chancap(ch iword) int32 func chanclose(ch iword) func chanlen(ch iword) int32 -func chanrecv(t *runtime.Type, ch iword, nb bool) (val iword, selected, received bool) -func chansend(t *runtime.Type, ch iword, val iword, nb bool) bool - -func makechan(typ *runtime.Type, size uint32) (ch iword) -func makemap(t *runtime.Type) (m iword) -func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool) -func mapassign(t *runtime.Type, m iword, key, val iword, ok bool) -func mapiterinit(t *runtime.Type, m iword) *byte +func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received bool) +func chansend(t *runtimeType, ch iword, val iword, nb bool) bool + +func makechan(typ *runtimeType, size uint32) (ch iword) +func makemap(t *runtimeType) (m iword) +func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool) +func mapassign(t *runtimeType, m iword, key, val iword, ok bool) +func mapiterinit(t *runtimeType, m iword) *byte func mapiterkey(it *byte) (key iword, ok bool) func mapiternext(it *byte) func maplen(m iword) int32 func call(typ *commonType, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer) -func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer) +func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer) // Dummy annotation marking that the value x escapes, // for use in cases where the reflect code is so clever that diff --git a/libgo/go/regexp/all_test.go b/libgo/go/regexp/all_test.go index 107dfe37cc7..f7b41a67416 100644 --- a/libgo/go/regexp/all_test.go +++ b/libgo/go/regexp/all_test.go @@ -176,6 +176,45 @@ var replaceTests = []ReplaceTest{ {"[a-c]*", "x", "def", "xdxexfx"}, {"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"}, {"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"}, + + // Substitutions + {"a+", "($0)", "banana", "b(a)n(a)n(a)"}, + {"a+", "(${0})", "banana", "b(a)n(a)n(a)"}, + {"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"}, + {"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"}, + {"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, world"}, + {"hello, (.+)", "goodbye, $1x", "hello, world", "goodbye, "}, + {"hello, (.+)", "goodbye, ${1}x", "hello, world", "goodbye, worldx"}, + {"hello, (.+)", "<$0><$1><$2><$3>", "hello, world", "<hello, world><world><><>"}, + {"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, world!"}, + {"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, world"}, + {"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "hihihi"}, + {"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "byebyebye"}, + {"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", ""}, + {"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "hiyz"}, + {"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $x"}, + {"a+", "${oops", "aaa", "${oops"}, + {"a+", "$$", "aaa", "$"}, + {"a+", "$", "aaa", "$"}, +} + +var replaceLiteralTests = []ReplaceTest{ + // Substitutions + {"a+", "($0)", "banana", "b($0)n($0)n($0)"}, + {"a+", "(${0})", "banana", "b(${0})n(${0})n(${0})"}, + {"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"}, + {"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"}, + {"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, ${1}"}, + {"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, $noun!"}, + {"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, ${noun}"}, + {"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "$x$x$x"}, + {"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "$x$x$x"}, + {"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", "$xyz"}, + {"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "${x}yz"}, + {"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $$x"}, + {"a+", "${oops", "aaa", "${oops"}, + {"a+", "$$", "aaa", "$$"}, + {"a+", "$", "aaa", "$"}, } type ReplaceFuncTest struct { @@ -199,13 +238,58 @@ func TestReplaceAll(t *testing.T) { } actual := re.ReplaceAllString(tc.input, tc.replacement) if actual != tc.output { - t.Errorf("%q.Replace(%q,%q) = %q; want %q", + t.Errorf("%q.ReplaceAllString(%q,%q) = %q; want %q", tc.pattern, tc.input, tc.replacement, actual, tc.output) } // now try bytes actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement))) if actual != tc.output { - t.Errorf("%q.Replace(%q,%q) = %q; want %q", + t.Errorf("%q.ReplaceAll(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + } +} + +func TestReplaceAllLiteral(t *testing.T) { + // Run ReplaceAll tests that do not have $ expansions. + for _, tc := range replaceTests { + if strings.Contains(tc.replacement, "$") { + continue + } + re, err := Compile(tc.pattern) + if err != nil { + t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err) + continue + } + actual := re.ReplaceAllLiteralString(tc.input, tc.replacement) + if actual != tc.output { + t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + // now try bytes + actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement))) + if actual != tc.output { + t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + } + + // Run literal-specific tests. + for _, tc := range replaceLiteralTests { + re, err := Compile(tc.pattern) + if err != nil { + t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err) + continue + } + actual := re.ReplaceAllLiteralString(tc.input, tc.replacement) + if actual != tc.output { + t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q", + tc.pattern, tc.input, tc.replacement, actual, tc.output) + } + // now try bytes + actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement))) + if actual != tc.output { + t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q", tc.pattern, tc.input, tc.replacement, actual, tc.output) } } diff --git a/libgo/go/regexp/regexp.go b/libgo/go/regexp/regexp.go index 7aebd3728a3..54c53776cf7 100644 --- a/libgo/go/regexp/regexp.go +++ b/libgo/go/regexp/regexp.go @@ -61,6 +61,7 @@ import ( "strconv" "strings" "sync" + "unicode" "unicode/utf8" ) @@ -416,41 +417,79 @@ func Match(pattern string, b []byte) (matched bool, error error) { return re.Match(b), nil } -// ReplaceAllString returns a copy of src in which all matches for the Regexp -// have been replaced by repl. No support is provided for expressions -// (e.g. \1 or $1) in the replacement string. +// ReplaceAllString returns a copy of src, replacing matches of the Regexp +// with the replacement string repl. Inside repl, $ signs are interpreted as +// in Expand, so for instance $1 represents the text of the first submatch. func (re *Regexp) ReplaceAllString(src, repl string) string { - return re.ReplaceAllStringFunc(src, func(string) string { return repl }) + n := 2 + if strings.Index(repl, "$") >= 0 { + n = 2 * (re.numSubexp + 1) + } + b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte { + return re.expand(dst, repl, nil, src, match) + }) + return string(b) } -// ReplaceAllStringFunc returns a copy of src in which all matches for the -// Regexp have been replaced by the return value of of function repl (whose -// first argument is the matched string). No support is provided for -// expressions (e.g. \1 or $1) in the replacement string. +// ReplaceAllStringLiteral returns a copy of src, replacing matches of the Regexp +// with the replacement string repl. The replacement repl is substituted directly, +// without using Expand. +func (re *Regexp) ReplaceAllLiteralString(src, repl string) string { + return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte { + return append(dst, repl...) + })) +} + +// ReplaceAllStringFunc returns a copy of src in which all matches of the +// Regexp have been replaced by the return value of of function repl applied +// to the matched substring. The replacement returned by repl is substituted +// directly, without using Expand. func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string { + b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte { + return append(dst, repl(src[match[0]:match[1]])...) + }) + return string(b) +} + +func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte { lastMatchEnd := 0 // end position of the most recent match searchPos := 0 // position where we next look for a match - buf := new(bytes.Buffer) - for searchPos <= len(src) { - a := re.doExecute(nil, nil, src, searchPos, 2) + var buf []byte + var endPos int + if bsrc != nil { + endPos = len(bsrc) + } else { + endPos = len(src) + } + for searchPos <= endPos { + a := re.doExecute(nil, bsrc, src, searchPos, nmatch) if len(a) == 0 { break // no more matches } // Copy the unmatched characters before this match. - io.WriteString(buf, src[lastMatchEnd:a[0]]) + if bsrc != nil { + buf = append(buf, bsrc[lastMatchEnd:a[0]]...) + } else { + buf = append(buf, src[lastMatchEnd:a[0]]...) + } // Now insert a copy of the replacement string, but not for a // match of the empty string immediately after another match. // (Otherwise, we get double replacement for patterns that // match both empty and nonempty strings.) if a[1] > lastMatchEnd || a[0] == 0 { - io.WriteString(buf, repl(src[a[0]:a[1]])) + buf = repl(buf, a) } lastMatchEnd = a[1] // Advance past this match; always advance at least one character. - _, width := utf8.DecodeRuneInString(src[searchPos:]) + var width int + if bsrc != nil { + _, width = utf8.DecodeRune(bsrc[searchPos:]) + } else { + _, width = utf8.DecodeRuneInString(src[searchPos:]) + } if searchPos+width > a[1] { searchPos += width } else if searchPos+1 > a[1] { @@ -463,61 +502,50 @@ func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) str } // Copy the unmatched characters after the last match. - io.WriteString(buf, src[lastMatchEnd:]) + if bsrc != nil { + buf = append(buf, bsrc[lastMatchEnd:]...) + } else { + buf = append(buf, src[lastMatchEnd:]...) + } - return buf.String() + return buf } -// ReplaceAll returns a copy of src in which all matches for the Regexp -// have been replaced by repl. No support is provided for expressions -// (e.g. \1 or $1) in the replacement text. +// ReplaceAll returns a copy of src, replacing matches of the Regexp +// with the replacement string repl. Inside repl, $ signs are interpreted as +// in Expand, so for instance $1 represents the text of the first submatch. func (re *Regexp) ReplaceAll(src, repl []byte) []byte { - return re.ReplaceAllFunc(src, func([]byte) []byte { return repl }) -} - -// ReplaceAllFunc returns a copy of src in which all matches for the -// Regexp have been replaced by the return value of of function repl (whose -// first argument is the matched []byte). No support is provided for -// expressions (e.g. \1 or $1) in the replacement string. -func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte { - lastMatchEnd := 0 // end position of the most recent match - searchPos := 0 // position where we next look for a match - buf := new(bytes.Buffer) - for searchPos <= len(src) { - a := re.doExecute(nil, src, "", searchPos, 2) - if len(a) == 0 { - break // no more matches - } - - // Copy the unmatched characters before this match. - buf.Write(src[lastMatchEnd:a[0]]) - - // Now insert a copy of the replacement string, but not for a - // match of the empty string immediately after another match. - // (Otherwise, we get double replacement for patterns that - // match both empty and nonempty strings.) - if a[1] > lastMatchEnd || a[0] == 0 { - buf.Write(repl(src[a[0]:a[1]])) - } - lastMatchEnd = a[1] - - // Advance past this match; always advance at least one character. - _, width := utf8.DecodeRune(src[searchPos:]) - if searchPos+width > a[1] { - searchPos += width - } else if searchPos+1 > a[1] { - // This clause is only needed at the end of the input - // string. In that case, DecodeRuneInString returns width=0. - searchPos++ - } else { - searchPos = a[1] - } + n := 2 + if bytes.IndexByte(repl, '$') >= 0 { + n = 2 * (re.numSubexp + 1) } + srepl := "" + b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte { + if len(srepl) != len(repl) { + srepl = string(repl) + } + return re.expand(dst, srepl, src, "", match) + }) + return b +} - // Copy the unmatched characters after the last match. - buf.Write(src[lastMatchEnd:]) +// ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp +// with the replacement bytes repl. The replacement repl is substituted directly, +// without using Expand. +func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte { + return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte { + return append(dst, repl...) + }) +} - return buf.Bytes() +// ReplaceAllFunc returns a copy of src in which all matches of the +// Regexp have been replaced by the return value of of function repl applied +// to the matched byte slice. The replacement returned by repl is substituted +// directly, without using Expand. +func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte { + return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte { + return append(dst, repl(src[match[0]:match[1]])...) + }) } var specialBytes = []byte(`\.+*?()|[]{}^$`) @@ -648,7 +676,7 @@ func (re *Regexp) FindString(s string) string { // location of the leftmost match in s of the regular expression. The match // itself is at s[loc[0]:loc[1]]. // A return value of nil indicates no match. -func (re *Regexp) FindStringIndex(s string) []int { +func (re *Regexp) FindStringIndex(s string) (loc []int) { a := re.doExecute(nil, nil, s, 0, 2) if a == nil { return nil @@ -660,7 +688,7 @@ func (re *Regexp) FindStringIndex(s string) []int { // location of the leftmost match of the regular expression in text read from // the RuneReader. The match itself is at s[loc[0]:loc[1]]. A return // value of nil indicates no match. -func (re *Regexp) FindReaderIndex(r io.RuneReader) []int { +func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) { a := re.doExecute(r, nil, "", 0, 2) if a == nil { return nil @@ -687,6 +715,134 @@ func (re *Regexp) FindSubmatch(b []byte) [][]byte { return ret } +// Expand appends template to dst and returns the result; during the +// append, Expand replaces variables in the template with corresponding +// matches drawn from src. The match slice should have been returned by +// FindSubmatchIndex. +// +// In the template, a variable is denoted by a substring of the form +// $name or ${name}, where name is a non-empty sequence of letters, +// digits, and underscores. A purely numeric name like $1 refers to +// the submatch with the corresponding index; other names refer to +// capturing parentheses named with the (?P<name>...) syntax. A +// reference to an out of range or unmatched index or a name that is not +// present in the regular expression is replaced with an empty string. +// +// In the $name form, name is taken to be as long as possible: $1x is +// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0. +// +// To insert a literal $ in the output, use $$ in the template. +func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte { + return re.expand(dst, string(template), src, "", match) +} + +// ExpandString is like Expand but the template and source are strings. +// It appends to and returns a byte slice in order to give the calling +// code control over allocation. +func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte { + return re.expand(dst, template, nil, src, match) +} + +func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte { + for len(template) > 0 { + i := strings.Index(template, "$") + if i < 0 { + break + } + dst = append(dst, template[:i]...) + template = template[i:] + if len(template) > 1 && template[1] == '$' { + // Treat $$ as $. + dst = append(dst, '$') + template = template[2:] + continue + } + name, num, rest, ok := extract(template) + if !ok { + // Malformed; treat $ as raw text. + dst = append(dst, '$') + template = template[1:] + continue + } + template = rest + if num >= 0 { + if 2*num+1 < len(match) { + if bsrc != nil { + dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...) + } else { + dst = append(dst, src[match[2*num]:match[2*num+1]]...) + } + } + } else { + for i, namei := range re.subexpNames { + if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 { + if bsrc != nil { + dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...) + } else { + dst = append(dst, src[match[2*i]:match[2*i+1]]...) + } + break + } + } + } + } + dst = append(dst, template...) + return dst +} + +// extract returns the name from a leading "$name" or "${name}" in str. +// If it is a number, extract returns num set to that number; otherwise num = -1. +func extract(str string) (name string, num int, rest string, ok bool) { + if len(str) < 2 || str[0] != '$' { + return + } + brace := false + if str[1] == '{' { + brace = true + str = str[2:] + } else { + str = str[1:] + } + i := 0 + for i < len(str) { + rune, size := utf8.DecodeRuneInString(str[i:]) + if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' { + break + } + i += size + } + if i == 0 { + // empty name is not okay + return + } + name = str[:i] + if brace { + if i >= len(str) || str[i] != '}' { + // missing closing brace + return + } + i++ + } + + // Parse number. + num = 0 + for i := 0; i < len(name); i++ { + if name[i] < '0' || '9' < name[i] || num >= 1e8 { + num = -1 + break + } + num = num*10 + int(name[i]) - '0' + } + // Disallow leading zeros. + if name[0] == '0' && len(name) > 1 { + num = -1 + } + + rest = str[i:] + ok = true + return +} + // FindSubmatchIndex returns a slice holding the index pairs identifying the // leftmost match of the regular expression in b and the matches, if any, of // its subexpressions, as defined by the 'Submatch' and 'Index' descriptions diff --git a/libgo/go/regexp/syntax/parse.go b/libgo/go/regexp/syntax/parse.go index 07688bef9c4..71b07b99307 100644 --- a/libgo/go/regexp/syntax/parse.go +++ b/libgo/go/regexp/syntax/parse.go @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package syntax parses regular expressions into parse trees and compiles +// parse trees into programs. Most clients of regular expressions will use +// the facilities of package regexp (such as Compile and Match) instead of +// this package. package syntax import ( @@ -648,6 +652,9 @@ func literalRegexp(s string, flags Flags) *Regexp { // Parsing. +// Parse parses a regular expression string s, controlled by the specified +// Flags, and returns a regular expression parse tree. The syntax is +// described in the top-level comment for package regexp. func Parse(s string, flags Flags) (*Regexp, error) { if flags&Literal != 0 { // Trivial parser for literal string. diff --git a/libgo/go/regexp/syntax/regexp.go b/libgo/go/regexp/syntax/regexp.go index 668a07764a1..329a90e0129 100644 --- a/libgo/go/regexp/syntax/regexp.go +++ b/libgo/go/regexp/syntax/regexp.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package syntax parses regular expressions into syntax trees. -// WORK IN PROGRESS. package syntax // Note to implementers: diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index 4f09146fac1..b802fc63f71 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -26,23 +26,11 @@ func GOMAXPROCS(n int) int // NumCPU returns the number of logical CPUs on the local machine. func NumCPU() int -// Cgocalls returns the number of cgo calls made by the current process. -func Cgocalls() int64 +// NumCgoCall returns the number of cgo calls made by the current process. +func NumCgoCall() int64 -// Goroutines returns the number of goroutines that currently exist. -func Goroutines() int32 - -// Alloc allocates a block of the given size. -// FOR TESTING AND DEBUGGING ONLY. -func Alloc(uintptr) *byte - -// Free frees the block starting at the given pointer. -// FOR TESTING AND DEBUGGING ONLY. -func Free(*byte) - -// Lookup returns the base and size of the block containing the given pointer. -// FOR TESTING AND DEBUGGING ONLY. -func Lookup(*byte) (*byte, uintptr) +// NumGoroutine returns the number of goroutines that currently exist. +func NumGoroutine() int // MemProfileRate controls the fraction of memory allocations // that are recorded and reported in the memory profile. @@ -95,11 +83,44 @@ func (r *MemProfileRecord) Stack() []uintptr { // where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes. // These are sites where memory was allocated, but it has all // been released back to the runtime. +// // Most clients should use the runtime/pprof package or // the testing package's -test.memprofile flag instead // of calling MemProfile directly. func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) +// A StackRecord describes a single execution stack. +type StackRecord struct { + Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry +} + +// Stack returns the stack trace associated with the record, +// a prefix of r.Stack0. +func (r *StackRecord) Stack() []uintptr { + for i, v := range r.Stack0 { + if v == 0 { + return r.Stack0[0:i] + } + } + return r.Stack0[0:] +} + +// ThreadCreateProfile returns n, the number of records in the thread creation profile. +// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true. +// If len(p) < n, ThreadCreateProfile does not change p and returns n, false. +// +// Most clients should use the runtime/pprof package instead +// of calling ThreadCreateProfile directly. +func ThreadCreateProfile(p []StackRecord) (n int, ok bool) + +// GoroutineProfile returns n, the number of records in the active goroutine stack profile. +// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true. +// If len(p) < n, GoroutineProfile does not change p and returns n, false. +// +// Most clients should use the runtime/pprof package instead +// of calling GoroutineProfile directly. +func GoroutineProfile(p []StackRecord) (n int, ok bool) + // CPUProfile returns the next chunk of binary CPU profiling stack trace data, // blocking until data is available. If profiling is turned off and all the profile // data accumulated while it was on has been returned, CPUProfile returns nil. @@ -116,3 +137,9 @@ func CPUProfile() []byte // the testing package's -test.cpuprofile flag instead of calling // SetCPUProfileRate directly. func SetCPUProfileRate(hz int) + +// Stack formats a stack trace of the calling goroutine into buf +// and returns the number of bytes written to buf. +// If all is true, Stack formats stack traces of all other goroutines +// into buf after the trace for the current goroutine. +func Stack(buf []byte, all bool) int diff --git a/libgo/go/runtime/debug/stack.go b/libgo/go/runtime/debug/stack.go index a533a5c3bf4..fc74e537b75 100644 --- a/libgo/go/runtime/debug/stack.go +++ b/libgo/go/runtime/debug/stack.go @@ -8,6 +8,7 @@ package debug import ( "bytes" + _ "debug/elf" "fmt" "io/ioutil" "os" diff --git a/libgo/go/runtime/error.go b/libgo/go/runtime/error.go index c5168a74be7..d3913ec27b8 100644 --- a/libgo/go/runtime/error.go +++ b/libgo/go/runtime/error.go @@ -17,9 +17,6 @@ type Error interface { // A TypeAssertionError explains a failed type assertion. type TypeAssertionError struct { - interfaceType *Type // interface had this type - concreteType *Type // concrete value had this type - assertedType *Type // asserted type interfaceString string concreteString string assertedString string @@ -33,7 +30,7 @@ func (e *TypeAssertionError) Error() string { if inter == "" { inter = "interface" } - if e.concreteType == nil { + if e.concreteString == "" { return "interface conversion: " + inter + " is nil, not " + e.assertedString } if e.missingMethod == "" { @@ -44,40 +41,10 @@ func (e *TypeAssertionError) Error() string { ": missing method " + e.missingMethod } -// Concrete returns the type of the concrete value in the failed type assertion. -// If the interface value was nil, Concrete returns nil. -func (e *TypeAssertionError) Concrete() *Type { - return e.concreteType -} - -// Asserted returns the type incorrectly asserted by the type assertion. -func (e *TypeAssertionError) Asserted() *Type { - return e.assertedType -} - -// If the type assertion is to an interface type, MissingMethod returns the -// name of a method needed to satisfy that interface type but not implemented -// by Concrete. If there are multiple such methods, -// MissingMethod returns one; which one is unspecified. -// If the type assertion is not to an interface type, MissingMethod returns an empty string. -func (e *TypeAssertionError) MissingMethod() string { - return e.missingMethod -} - // For calling from C. -func NewTypeAssertionError(pt1, pt2, pt3 *Type, ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) { - var t1, t2, t3 *Type +func NewTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) { var s1, s2, s3, meth string - if pt1 != nil { - t1 = pt1 - } - if pt2 != nil { - t2 = pt2 - } - if pt3 != nil { - t3 = pt3 - } if ps1 != nil { s1 = *ps1 } @@ -90,7 +57,7 @@ func NewTypeAssertionError(pt1, pt2, pt3 *Type, ps1, ps2, ps3 *string, pmeth *st if pmeth != nil { meth = *pmeth } - *ret = &TypeAssertionError{t1, t2, t3, s1, s2, s3, meth} + *ret = &TypeAssertionError{s1, s2, s3, meth} } // An errorString represents a runtime error described by a single string. diff --git a/libgo/go/runtime/extern.go b/libgo/go/runtime/extern.go index eafa2f19f19..2c097b0c013 100644 --- a/libgo/go/runtime/extern.go +++ b/libgo/go/runtime/extern.go @@ -32,16 +32,8 @@ func Caller(skip int) (pc uintptr, file string, line int, ok bool) func Callers(skip int, pc []uintptr) int type Func struct { // Keep in sync with runtime.h:struct Func - name string - typ string // go type string - src string // src file name - pcln []byte // pc/ln tab for this func - entry uintptr // entry pc - pc0 uintptr // starting pc, ln for table - ln0 int32 - frame int32 // stack frame size - args int32 // number of 32-bit in/out args - locals int32 // number of 32-bit locals + name string + entry uintptr // entry pc } // FuncForPC returns a *Func describing the function that contains the @@ -65,20 +57,13 @@ func (f *Func) FileLine(pc uintptr) (file string, line int) { // implemented in symtab.c func funcline_go(*Func, uintptr) (string, int) +// A gccgo specific hook to use debug info to get file/line info. +func RegisterDebugLookup(func(pc uintptr, function *string, file *string, line *int) bool, + func(sym string, val *uintptr) bool) + // mid returns the current os thread (m) id. func mid() uint32 -// Semacquire waits until *s > 0 and then atomically decrements it. -// It is intended as a simple sleep primitive for use by the synchronization -// library and should not be used directly. -func Semacquire(s *uint32) - -// Semrelease atomically increments *s and notifies a waiting goroutine -// if one is blocked in Semacquire. -// It is intended as a simple wakeup primitive for use by the synchronization -// library and should not be used directly. -func Semrelease(s *uint32) - // SetFinalizer sets the finalizer associated with x to f. // When the garbage collector finds an unreachable block // with an associated finalizer, it clears the association and runs @@ -141,10 +126,10 @@ func Version() string { return theVersion } -// GOOS is the Go tree's operating system target: +// GOOS is the running program's operating system target: // one of darwin, freebsd, linux, and so on. const GOOS string = theGoos -// GOARCH is the Go tree's architecture target: +// GOARCH is the running program's architecture target: // 386, amd64, or arm. const GOARCH string = theGoarch diff --git a/libgo/go/runtime/gc_test.go b/libgo/go/runtime/gc_test.go index 739ebcba2ff..65894a6fd01 100644 --- a/libgo/go/runtime/gc_test.go +++ b/libgo/go/runtime/gc_test.go @@ -15,7 +15,11 @@ func TestGcSys(t *testing.T) { runtime.ReadMemStats(memstats) sys := memstats.Sys - for i := 0; i < 1000000; i++ { + itercount := 1000000 + if testing.Short() { + itercount = 100000 + } + for i := 0; i < itercount; i++ { workthegc() } diff --git a/libgo/go/runtime/malloc1.go b/libgo/go/runtime/malloc1.go new file mode 100644 index 00000000000..da92f4c2fbf --- /dev/null +++ b/libgo/go/runtime/malloc1.go @@ -0,0 +1,26 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// trivial malloc test + +package main + +import ( + "flag" + "fmt" + "runtime" +) + +var chatty = flag.Bool("v", false, "chatty") + +func main() { + memstats := new(runtime.MemStats) + runtime.Free(runtime.Alloc(1)) + runtime.ReadMemStats(memstats) + if *chatty { + fmt.Printf("%+v %v\n", memstats, uint64(0)) + } +} diff --git a/libgo/go/runtime/mallocrand.go b/libgo/go/runtime/mallocrand.go new file mode 100644 index 00000000000..f1bcb89cfa4 --- /dev/null +++ b/libgo/go/runtime/mallocrand.go @@ -0,0 +1,93 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Random malloc test. + +package main + +import ( + "flag" + "math/rand" + "runtime" + "unsafe" +) + +var chatty = flag.Bool("v", false, "chatty") + +var footprint uint64 +var allocated uint64 + +func bigger() { + memstats := new(runtime.MemStats) + runtime.ReadMemStats(memstats) + if f := memstats.Sys; footprint < f { + footprint = f + if *chatty { + println("Footprint", footprint, " for ", allocated) + } + if footprint > 1e9 { + println("too big") + panic("fail") + } + } +} + +// Prime the data structures by allocating one of +// each block in order. After this, there should be +// little reason to ask for more memory from the OS. +func prime() { + for i := 0; i < 16; i++ { + b := runtime.Alloc(1 << uint(i)) + runtime.Free(b) + } + for i := uintptr(0); i < 256; i++ { + b := runtime.Alloc(i << 12) + runtime.Free(b) + } +} + +func memset(b *byte, c byte, n uintptr) { + np := uintptr(n) + for i := uintptr(0); i < np; i++ { + *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(b)) + i)) = c + } +} + +func main() { + flag.Parse() + // prime() + var blocks [1]struct { + base *byte + siz uintptr + } + for i := 0; i < 1<<10; i++ { + if i%(1<<10) == 0 && *chatty { + println(i) + } + b := rand.Int() % len(blocks) + if blocks[b].base != nil { + // println("Free", blocks[b].siz, blocks[b].base) + runtime.Free(blocks[b].base) + blocks[b].base = nil + allocated -= uint64(blocks[b].siz) + continue + } + siz := uintptr(rand.Int() >> (11 + rand.Uint32()%20)) + base := runtime.Alloc(siz) + // ptr := uintptr(syscall.BytePtr(base))+uintptr(siz/2) + // obj, size, ref, ok := allocator.find(ptr) + // if obj != base || *ref != 0 || !ok { + // println("find", siz, obj, ref, ok) + // panic("fail") + // } + blocks[b].base = base + blocks[b].siz = siz + allocated += uint64(siz) + // println("Alloc", siz, base) + memset(base, 0xbb, siz) + bigger() + } +} diff --git a/libgo/go/runtime/mallocrep.go b/libgo/go/runtime/mallocrep.go new file mode 100644 index 00000000000..03ee71edb42 --- /dev/null +++ b/libgo/go/runtime/mallocrep.go @@ -0,0 +1,72 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Repeated malloc test. + +// +build ignore + +package main + +import ( + "flag" + "runtime" +) + +var chatty = flag.Bool("v", false, "chatty") + +var oldsys uint64 +var memstats runtime.MemStats + +func bigger() { + st := &memstats + runtime.ReadMemStats(st) + if oldsys < st.Sys { + oldsys = st.Sys + if *chatty { + println(st.Sys, " system bytes for ", st.Alloc, " Go bytes") + } + if st.Sys > 1e9 { + println("too big") + panic("fail") + } + } +} + +func main() { + runtime.GC() // clean up garbage from init + runtime.ReadMemStats(&memstats) // first call can do some allocations + runtime.MemProfileRate = 0 // disable profiler + stacks := memstats.Alloc // ignore stacks + flag.Parse() + for i := 0; i < 1<<7; i++ { + for j := 1; j <= 1<<22; j <<= 1 { + if i == 0 && *chatty { + println("First alloc:", j) + } + if a := memstats.Alloc - stacks; a != 0 { + println("no allocations but stats report", a, "bytes allocated") + panic("fail") + } + b := runtime.Alloc(uintptr(j)) + runtime.ReadMemStats(&memstats) + during := memstats.Alloc - stacks + runtime.Free(b) + runtime.ReadMemStats(&memstats) + if a := memstats.Alloc - stacks; a != 0 { + println("allocated ", j, ": wrong stats: during=", during, " after=", a, " (want 0)") + panic("fail") + } + bigger() + } + if i%(1<<10) == 0 && *chatty { + println(i) + } + if i == 0 { + if *chatty { + println("Primed", i) + } + // runtime.frozen = true + } + } +} diff --git a/libgo/go/runtime/mallocrep1.go b/libgo/go/runtime/mallocrep1.go new file mode 100644 index 00000000000..41c104c0ba7 --- /dev/null +++ b/libgo/go/runtime/mallocrep1.go @@ -0,0 +1,143 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Repeated malloc test. + +package main + +import ( + "flag" + "fmt" + "runtime" + "strconv" +) + +var chatty = flag.Bool("v", false, "chatty") +var reverse = flag.Bool("r", false, "reverse") +var longtest = flag.Bool("l", false, "long test") + +var b []*byte +var stats = new(runtime.MemStats) + +func OkAmount(size, n uintptr) bool { + if n < size { + return false + } + if size < 16*8 { + if n > size+16 { + return false + } + } else { + if n > size*9/8 { + return false + } + } + return true +} + +func AllocAndFree(size, count int) { + if *chatty { + fmt.Printf("size=%d count=%d ...\n", size, count) + } + runtime.ReadMemStats(stats) + n1 := stats.Alloc + for i := 0; i < count; i++ { + b[i] = runtime.Alloc(uintptr(size)) + base, n := runtime.Lookup(b[i]) + if base != b[i] || !OkAmount(uintptr(size), n) { + println("lookup failed: got", base, n, "for", b[i]) + panic("fail") + } + runtime.ReadMemStats(stats) + if stats.Sys > 1e9 { + println("too much memory allocated") + panic("fail") + } + } + runtime.ReadMemStats(stats) + n2 := stats.Alloc + if *chatty { + fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats) + } + n3 := stats.Alloc + for j := 0; j < count; j++ { + i := j + if *reverse { + i = count - 1 - j + } + alloc := uintptr(stats.Alloc) + base, n := runtime.Lookup(b[i]) + if base != b[i] || !OkAmount(uintptr(size), n) { + println("lookup failed: got", base, n, "for", b[i]) + panic("fail") + } + runtime.Free(b[i]) + runtime.ReadMemStats(stats) + if stats.Alloc != uint64(alloc-n) { + println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n) + panic("fail") + } + if stats.Sys > 1e9 { + println("too much memory allocated") + panic("fail") + } + } + runtime.ReadMemStats(stats) + n4 := stats.Alloc + + if *chatty { + fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats) + } + if n2-n1 != n3-n4 { + println("wrong alloc count: ", n2-n1, n3-n4) + panic("fail") + } +} + +func atoi(s string) int { + i, _ := strconv.Atoi(s) + return i +} + +func main() { + runtime.MemProfileRate = 0 // disable profiler + flag.Parse() + b = make([]*byte, 10000) + if flag.NArg() > 0 { + AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1))) + return + } + maxb := 1 << 22 + if !*longtest { + maxb = 1 << 19 + } + for j := 1; j <= maxb; j <<= 1 { + n := len(b) + max := uintptr(1 << 28) + if !*longtest { + max = uintptr(maxb) + } + if uintptr(j)*uintptr(n) > max { + n = int(max / uintptr(j)) + } + if n < 10 { + n = 10 + } + for m := 1; m <= n; { + AllocAndFree(j, m) + if m == n { + break + } + m = 5 * m / 4 + if m < 4 { + m++ + } + if m > n { + m = n + } + } + } +} diff --git a/libgo/go/runtime/mem.go b/libgo/go/runtime/mem.go index 1301674c027..95e8aa7a533 100644 --- a/libgo/go/runtime/mem.go +++ b/libgo/go/runtime/mem.go @@ -17,11 +17,12 @@ type MemStats struct { Frees uint64 // number of frees // Main allocation heap statistics. - HeapAlloc uint64 // bytes allocated and still in use - HeapSys uint64 // bytes obtained from system - HeapIdle uint64 // bytes in idle spans - HeapInuse uint64 // bytes in non-idle span - HeapObjects uint64 // total number of allocated objects + HeapAlloc uint64 // bytes allocated and still in use + HeapSys uint64 // bytes obtained from system + HeapIdle uint64 // bytes in idle spans + HeapInuse uint64 // bytes in non-idle span + HeapReleased uint64 // bytes released to the OS + HeapObjects uint64 // total number of allocated objects // Low-level fixed-size structure allocator statistics. // Inuse is bytes used now. @@ -35,7 +36,8 @@ type MemStats struct { BuckHashSys uint64 // profiling bucket hash table // Garbage collector statistics. - NextGC uint64 + NextGC uint64 // next run in HeapAlloc time (bytes) + LastGC uint64 // last run in absolute time (ns) PauseTotalNs uint64 PauseNs [256]uint64 // most recent GC pause times NumGC uint32 diff --git a/libgo/go/runtime/pprof/pprof.go b/libgo/go/runtime/pprof/pprof.go index a8e78e0ea75..87f17d2db12 100644 --- a/libgo/go/runtime/pprof/pprof.go +++ b/libgo/go/runtime/pprof/pprof.go @@ -10,19 +10,355 @@ package pprof import ( "bufio" + "bytes" + _ "debug/elf" "fmt" "io" "runtime" + "sort" + "strings" "sync" + "text/tabwriter" ) -// BUG(rsc): CPU profiling is broken on OS X, due to an Apple kernel bug. -// For details, see http://code.google.com/p/go/source/detail?r=35b716c94225. +// BUG(rsc): A bug in the OS X Snow Leopard 64-bit kernel prevents +// CPU profiling from giving accurate results on that system. -// WriteHeapProfile writes a pprof-formatted heap profile to w. -// If a write to w returns an error, WriteHeapProfile returns that error. -// Otherwise, WriteHeapProfile returns nil. +// A Profile is a collection of stack traces showing the call sequences +// that led to instances of a particular event, such as allocation. +// Packages can create and maintain their own profiles; the most common +// use is for tracking resources that must be explicitly closed, such as files +// or network connections. +// +// A Profile's methods can be called from multiple goroutines simultaneously. +// +// Each Profile has a unique name. A few profiles are predefined: +// +// goroutine - stack traces of all current goroutines +// heap - a sampling of all heap allocations +// threadcreate - stack traces that led to the creation of new OS threads +// +// These predefine profiles maintain themselves and panic on an explicit +// Add or Remove method call. +// +// The CPU profile is not available as a Profile. It has a special API, +// the StartCPUProfile and StopCPUProfile functions, because it streams +// output to a writer during profiling. +// +type Profile struct { + name string + mu sync.Mutex + m map[interface{}][]uintptr + count func() int + write func(io.Writer, int) error +} + +// profiles records all registered profiles. +var profiles struct { + mu sync.Mutex + m map[string]*Profile +} + +var goroutineProfile = &Profile{ + name: "goroutine", + count: countGoroutine, + write: writeGoroutine, +} + +var threadcreateProfile = &Profile{ + name: "threadcreate", + count: countThreadCreate, + write: writeThreadCreate, +} + +var heapProfile = &Profile{ + name: "heap", + count: countHeap, + write: writeHeap, +} + +func lockProfiles() { + profiles.mu.Lock() + if profiles.m == nil { + // Initial built-in profiles. + profiles.m = map[string]*Profile{ + "goroutine": goroutineProfile, + "threadcreate": threadcreateProfile, + "heap": heapProfile, + } + } +} + +func unlockProfiles() { + profiles.mu.Unlock() +} + +// NewProfile creates a new profile with the given name. +// If a profile with that name already exists, NewProfile panics. +// The convention is to use a 'import/path.' prefix to create +// separate name spaces for each package. +func NewProfile(name string) *Profile { + lockProfiles() + defer unlockProfiles() + if name == "" { + panic("pprof: NewProfile with empty name") + } + if profiles.m[name] != nil { + panic("pprof: NewProfile name already in use: " + name) + } + p := &Profile{ + name: name, + m: map[interface{}][]uintptr{}, + } + profiles.m[name] = p + return p +} + +// Lookup returns the profile with the given name, or nil if no such profile exists. +func Lookup(name string) *Profile { + lockProfiles() + defer unlockProfiles() + return profiles.m[name] +} + +// Profiles returns a slice of all the known profiles, sorted by name. +func Profiles() []*Profile { + lockProfiles() + defer unlockProfiles() + + var all []*Profile + for _, p := range profiles.m { + all = append(all, p) + } + + sort.Sort(byName(all)) + return all +} + +type byName []*Profile + +func (x byName) Len() int { return len(x) } +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byName) Less(i, j int) bool { return x[i].name < x[j].name } + +// Name returns this profile's name, which can be passed to Lookup to reobtain the profile. +func (p *Profile) Name() string { + return p.name +} + +// Count returns the number of execution stacks currently in the profile. +func (p *Profile) Count() int { + p.mu.Lock() + defer p.mu.Unlock() + if p.count != nil { + return p.count() + } + return len(p.m) +} + +// Add adds the current execution stack to the profile, associated with value. +// Add stores value in an internal map, so value must be suitable for use as +// a map key and will not be garbage collected until the corresponding +// call to Remove. Add panics if the profile already contains a stack for value. +// +// The skip parameter has the same meaning as runtime.Caller's skip +// and controls where the stack trace begins. Passing skip=0 begins the +// trace in the function calling Add. For example, given this +// execution stack: +// +// Add +// called from rpc.NewClient +// called from mypkg.Run +// called from main.main +// +// Passing skip=0 begins the stack trace at the call to Add inside rpc.NewClient. +// Passing skip=1 begins the stack trace at the call to NewClient inside mypkg.Run. +// +func (p *Profile) Add(value interface{}, skip int) { + if p.name == "" { + panic("pprof: use of uninitialized Profile") + } + if p.write != nil { + panic("pprof: Add called on built-in Profile " + p.name) + } + + stk := make([]uintptr, 32) + n := runtime.Callers(skip+1, stk[:]) + + p.mu.Lock() + defer p.mu.Unlock() + if p.m[value] != nil { + panic("pprof: Profile.Add of duplicate value") + } + p.m[value] = stk[:n] +} + +// Remove removes the execution stack associated with value from the profile. +// It is a no-op if the value is not in the profile. +func (p *Profile) Remove(value interface{}) { + p.mu.Lock() + defer p.mu.Unlock() + delete(p.m, value) +} + +// WriteTo writes a pprof-formatted snapshot of the profile to w. +// If a write to w returns an error, WriteTo returns that error. +// Otherwise, WriteTo returns nil. +// +// The debug parameter enables additional output. +// Passing debug=0 prints only the hexadecimal addresses that pprof needs. +// Passing debug=1 adds comments translating addresses to function names +// and line numbers, so that a programmer can read the profile without tools. +// +// The predefined profiles may assign meaning to other debug values; +// for example, when printing the "goroutine" profile, debug=2 means to +// print the goroutine stacks in the same form that a Go program uses +// when dying due to an unrecovered panic. +func (p *Profile) WriteTo(w io.Writer, debug int) error { + if p.name == "" { + panic("pprof: use of zero Profile") + } + if p.write != nil { + return p.write(w, debug) + } + + // Obtain consistent snapshot under lock; then process without lock. + var all [][]uintptr + p.mu.Lock() + for _, stk := range p.m { + all = append(all, stk) + } + p.mu.Unlock() + + // Map order is non-deterministic; make output deterministic. + sort.Sort(stackProfile(all)) + + return printCountProfile(w, debug, p.name, stackProfile(all)) +} + +type stackProfile [][]uintptr + +func (x stackProfile) Len() int { return len(x) } +func (x stackProfile) Stack(i int) []uintptr { return x[i] } +func (x stackProfile) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x stackProfile) Less(i, j int) bool { + t, u := x[i], x[j] + for k := 0; k < len(t) && k < len(u); k++ { + if t[k] != u[k] { + return t[k] < u[k] + } + } + return len(t) < len(u) +} + +// A countProfile is a set of stack traces to be printed as counts +// grouped by stack trace. There are multiple implementations: +// all that matters is that we can find out how many traces there are +// and obtain each trace in turn. +type countProfile interface { + Len() int + Stack(i int) []uintptr +} + +// printCountProfile prints a countProfile at the specified debug level. +func printCountProfile(w io.Writer, debug int, name string, p countProfile) error { + b := bufio.NewWriter(w) + var tw *tabwriter.Writer + w = b + if debug > 0 { + tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0) + w = tw + } + + fmt.Fprintf(w, "%s profile: total %d\n", name, p.Len()) + + // Build count of each stack. + var buf bytes.Buffer + key := func(stk []uintptr) string { + buf.Reset() + fmt.Fprintf(&buf, "@") + for _, pc := range stk { + fmt.Fprintf(&buf, " %#x", pc) + } + return buf.String() + } + m := map[string]int{} + n := p.Len() + for i := 0; i < n; i++ { + m[key(p.Stack(i))]++ + } + + // Print stacks, listing count on first occurrence of a unique stack. + for i := 0; i < n; i++ { + stk := p.Stack(i) + s := key(stk) + if count := m[s]; count != 0 { + fmt.Fprintf(w, "%d %s\n", count, s) + if debug > 0 { + printStackRecord(w, stk, false) + } + delete(m, s) + } + } + + if tw != nil { + tw.Flush() + } + return b.Flush() +} + +// printStackRecord prints the function + source line information +// for a single stack trace. +func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) { + show := allFrames + for _, pc := range stk { + f := runtime.FuncForPC(pc) + if f == nil { + show = true + fmt.Fprintf(w, "#\t%#x\n", pc) + } else { + file, line := f.FileLine(pc) + name := f.Name() + // Hide runtime.goexit and any runtime functions at the beginning. + // This is useful mainly for allocation traces. + if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") { + continue + } + show = true + fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, f.Name(), pc-f.Entry(), file, line) + } + } + if !show { + // We didn't print anything; do it again, + // and this time include runtime functions. + printStackRecord(w, stk, true) + return + } + fmt.Fprintf(w, "\n") +} + +// Interface to system profiles. + +type byInUseBytes []runtime.MemProfileRecord + +func (x byInUseBytes) Len() int { return len(x) } +func (x byInUseBytes) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byInUseBytes) Less(i, j int) bool { return x[i].InUseBytes() > x[j].InUseBytes() } + +// WriteHeapProfile is shorthand for Lookup("heap").WriteTo(w, 0). +// It is preserved for backwards compatibility. func WriteHeapProfile(w io.Writer) error { + return writeHeap(w, 0) +} + +// countHeap returns the number of records in the heap profile. +func countHeap() int { + n, _ := runtime.MemProfile(nil, false) + return n +} + +// writeHeapProfile writes the current runtime heap profile to w. +func writeHeap(w io.Writer, debug int) error { // Find out how many records there are (MemProfile(nil, false)), // allocate that many records, and get the data. // There's a race—more records might be added between @@ -44,6 +380,16 @@ func WriteHeapProfile(w io.Writer) error { // Profile grew; try again. } + sort.Sort(byInUseBytes(p)) + + b := bufio.NewWriter(w) + var tw *tabwriter.Writer + w = b + if debug > 0 { + tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0) + w = tw + } + var total runtime.MemProfileRecord for i := range p { r := &p[i] @@ -56,60 +402,135 @@ func WriteHeapProfile(w io.Writer) error { // Technically the rate is MemProfileRate not 2*MemProfileRate, // but early versions of the C++ heap profiler reported 2*MemProfileRate, // so that's what pprof has come to expect. - b := bufio.NewWriter(w) - fmt.Fprintf(b, "heap profile: %d: %d [%d: %d] @ heap/%d\n", + fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n", total.InUseObjects(), total.InUseBytes(), total.AllocObjects, total.AllocBytes, 2*runtime.MemProfileRate) for i := range p { r := &p[i] - fmt.Fprintf(b, "%d: %d [%d: %d] @", + fmt.Fprintf(w, "%d: %d [%d: %d] @", r.InUseObjects(), r.InUseBytes(), r.AllocObjects, r.AllocBytes) for _, pc := range r.Stack() { - fmt.Fprintf(b, " %#x", pc) + fmt.Fprintf(w, " %#x", pc) + } + fmt.Fprintf(w, "\n") + if debug > 0 { + printStackRecord(w, r.Stack(), false) } - fmt.Fprintf(b, "\n") } // Print memstats information too. - // Pprof will ignore, but useful for people. - s := new(runtime.MemStats) - runtime.ReadMemStats(s) - fmt.Fprintf(b, "\n# runtime.MemStats\n") - fmt.Fprintf(b, "# Alloc = %d\n", s.Alloc) - fmt.Fprintf(b, "# TotalAlloc = %d\n", s.TotalAlloc) - fmt.Fprintf(b, "# Sys = %d\n", s.Sys) - fmt.Fprintf(b, "# Lookups = %d\n", s.Lookups) - fmt.Fprintf(b, "# Mallocs = %d\n", s.Mallocs) - - fmt.Fprintf(b, "# HeapAlloc = %d\n", s.HeapAlloc) - fmt.Fprintf(b, "# HeapSys = %d\n", s.HeapSys) - fmt.Fprintf(b, "# HeapIdle = %d\n", s.HeapIdle) - fmt.Fprintf(b, "# HeapInuse = %d\n", s.HeapInuse) - - fmt.Fprintf(b, "# Stack = %d / %d\n", s.StackInuse, s.StackSys) - fmt.Fprintf(b, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys) - fmt.Fprintf(b, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys) - fmt.Fprintf(b, "# BuckHashSys = %d\n", s.BuckHashSys) - - fmt.Fprintf(b, "# NextGC = %d\n", s.NextGC) - fmt.Fprintf(b, "# PauseNs = %d\n", s.PauseNs) - fmt.Fprintf(b, "# NumGC = %d\n", s.NumGC) - fmt.Fprintf(b, "# EnableGC = %v\n", s.EnableGC) - fmt.Fprintf(b, "# DebugGC = %v\n", s.DebugGC) - - fmt.Fprintf(b, "# BySize = Size * (Active = Mallocs - Frees)\n") - fmt.Fprintf(b, "# (Excluding large blocks.)\n") - for _, t := range s.BySize { - if t.Mallocs > 0 { - fmt.Fprintf(b, "# %d * (%d = %d - %d)\n", t.Size, t.Mallocs-t.Frees, t.Mallocs, t.Frees) - } + // Pprof will ignore, but useful for people + if debug > 0 { + s := new(runtime.MemStats) + runtime.ReadMemStats(s) + fmt.Fprintf(w, "\n# runtime.MemStats\n") + fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc) + fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc) + fmt.Fprintf(w, "# Sys = %d\n", s.Sys) + fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups) + fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs) + + fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc) + fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys) + fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle) + fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse) + + fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys) + fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys) + fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys) + fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys) + + fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC) + fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs) + fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC) + fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC) + fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC) + } + + if tw != nil { + tw.Flush() } return b.Flush() } +// countThreadCreate returns the size of the current ThreadCreateProfile. +func countThreadCreate() int { + n, _ := runtime.ThreadCreateProfile(nil) + return n +} + +// writeThreadCreate writes the current runtime ThreadCreateProfile to w. +func writeThreadCreate(w io.Writer, debug int) error { + return writeRuntimeProfile(w, debug, "threadcreate", runtime.ThreadCreateProfile) +} + +// countGoroutine returns the number of goroutines. +func countGoroutine() int { + return runtime.NumGoroutine() +} + +// writeGoroutine writes the current runtime GoroutineProfile to w. +func writeGoroutine(w io.Writer, debug int) error { + if debug >= 2 { + return writeGoroutineStacks(w) + } + return writeRuntimeProfile(w, debug, "goroutine", runtime.GoroutineProfile) +} + +func writeGoroutineStacks(w io.Writer) error { + // We don't know how big the buffer needs to be to collect + // all the goroutines. Start with 1 MB and try a few times, doubling each time. + // Give up and use a truncated trace if 64 MB is not enough. + buf := make([]byte, 1<<20) + for i := 0; ; i++ { + n := runtime.Stack(buf, true) + if n < len(buf) { + buf = buf[:n] + break + } + if len(buf) >= 64<<20 { + // Filled 64 MB - stop there. + break + } + buf = make([]byte, 2*len(buf)) + } + _, err := w.Write(buf) + return err +} + +func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord) (int, bool)) error { + // Find out how many records there are (fetch(nil)), + // allocate that many records, and get the data. + // There's a race—more records might be added between + // the two calls—so allocate a few extra records for safety + // and also try again if we're very unlucky. + // The loop should only execute one iteration in the common case. + var p []runtime.StackRecord + n, ok := fetch(nil) + for { + // Allocate room for a slightly bigger profile, + // in case a few more entries have been added + // since the call to ThreadProfile. + p = make([]runtime.StackRecord, n+10) + n, ok = fetch(p) + if ok { + p = p[0:n] + break + } + // Profile grew; try again. + } + + return printCountProfile(w, debug, name, runtimeProfile(p)) +} + +type runtimeProfile []runtime.StackRecord + +func (p runtimeProfile) Len() int { return len(p) } +func (p runtimeProfile) Stack(i int) []uintptr { return p[i].Stack() } + var cpu struct { sync.Mutex profiling bool diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go index 5f128c01cf1..2dc7aef7e96 100644 --- a/libgo/go/runtime/pprof/pprof_test.go +++ b/libgo/go/runtime/pprof/pprof_test.go @@ -7,6 +7,7 @@ package pprof_test import ( "bytes" "hash/crc32" + "os/exec" "runtime" . "runtime/pprof" "strings" @@ -17,8 +18,16 @@ import ( func TestCPUProfile(t *testing.T) { switch runtime.GOOS { case "darwin": - // see Apple Bug Report #9177434 (copied into change description) - return + out, err := exec.Command("uname", "-a").CombinedOutput() + if err != nil { + t.Fatal(err) + } + vers := string(out) + t.Logf("uname -a: %v", vers) + if strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64") { + t.Logf("skipping test on known-broken kernel (64-bit Snow Leopard)") + return + } case "plan9": // unimplemented return diff --git a/libgo/go/runtime/runtime_test.go b/libgo/go/runtime/runtime_test.go new file mode 100644 index 00000000000..d68b363e998 --- /dev/null +++ b/libgo/go/runtime/runtime_test.go @@ -0,0 +1,40 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "io" + "testing" +) + +var errf error + +func errfn() error { + return errf +} + +func errfn1() error { + return io.EOF +} + +func BenchmarkIfaceCmp100(b *testing.B) { + for i := 0; i < b.N; i++ { + for j := 0; j < 100; j++ { + if errfn() == io.EOF { + b.Fatal("bad comparison") + } + } + } +} + +func BenchmarkIfaceCmpNil100(b *testing.B) { + for i := 0; i < b.N; i++ { + for j := 0; j < 100; j++ { + if errfn1() == nil { + b.Fatal("bad comparison") + } + } + } +} diff --git a/libgo/go/runtime/sig.go b/libgo/go/runtime/sig.go deleted file mode 100644 index 6d560b90077..00000000000 --- a/libgo/go/runtime/sig.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package runtime - -// Sigrecv returns a bitmask of signals that have arrived since the last call to Sigrecv. -// It blocks until at least one signal arrives. -func Sigrecv() uint32 - -// Signame returns a string describing the signal, or "" if the signal is unknown. -func Signame(sig int32) string - -// Siginit enables receipt of signals via Sigrecv. It should typically -// be called during initialization. -func Siginit() diff --git a/libgo/go/runtime/softfloat64.go b/libgo/go/runtime/softfloat64.go index e0c3b7b738d..4fcf8f26901 100644 --- a/libgo/go/runtime/softfloat64.go +++ b/libgo/go/runtime/softfloat64.go @@ -4,7 +4,7 @@ // Software IEEE754 64-bit floating point. // Only referred to (and thus linked in) by arm port -// and by gotest in this directory. +// and by tests in this directory. package runtime diff --git a/libgo/go/runtime/type.go b/libgo/go/runtime/type.go index b59f2e4c383..c15c1c10c85 100644 --- a/libgo/go/runtime/type.go +++ b/libgo/go/runtime/type.go @@ -4,205 +4,52 @@ /* * Runtime type representation. - * - * The following files know the exact layout of these - * data structures and must be kept in sync with this file: - * - * ../../cmd/gc/reflect.c - * ../../cmd/ld/dwarf.c decodetype_* - * ../reflect/type.go - * type.h + * This file exists only to provide types that 6l can turn into + * DWARF information for use by gdb. Nothing else uses these. + * They should match the same types in ../reflect/type.go. + * For comments see ../reflect/type.go. */ package runtime import "unsafe" -// All types begin with a few common fields needed for -// the interface runtime. type commonType struct { - Kind uint8 // type kind - align uint8 // alignment of variable with this type - fieldAlign uint8 // alignment of struct field with this type - size uintptr // size in bytes - hash uint32 // hash of type; avoids computation in hash tables + Kind uint8 + align uint8 + fieldAlign uint8 + size uintptr + hash uint32 - hashfn func(unsafe.Pointer, uintptr) uintptr // hash function - equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) bool // equality function + hashfn func(unsafe.Pointer, uintptr) uintptr + equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) bool - string *string // string form; unnecessary but undeniably useful - *uncommonType // (relatively) uncommon fields - ptrToThis *Type // pointer to this type, if used in binary or has methods + string *string + *uncommonType + ptrToThis *commonType } -// Values for commonType.kind. -const ( - kindBool = 1 + iota - kindInt - kindInt8 - kindInt16 - kindInt32 - kindInt64 - kindUint - kindUint8 - kindUint16 - kindUint32 - kindUint64 - kindUintptr - kindFloat32 - kindFloat64 - kindComplex64 - kindComplex128 - kindArray - kindChan - kindFunc - kindInterface - kindMap - kindPtr - kindSlice - kindString - kindStruct - kindUnsafePointer - - // Not currently generated by gccgo. - // kindNoPointers = 1 << 7 // OR'ed into kind -) - -// Externally visible name. -type Type commonType - -// Method on non-interface type -type _method struct { // underscore is to avoid collision with C - name *string // name of method - pkgPath *string // nil for exported Names; otherwise import path - mtyp *Type // method type (without receiver) - typ *Type // .(*FuncType) underneath (with receiver) - tfn unsafe.Pointer // fn used for normal method call +type _method struct { + name *string + pkgPath *string + mtyp *commonType + typ *commonType + tfn unsafe.Pointer } -// uncommonType is present only for types with names or methods -// (if T is a named type, the uncommonTypes for T and *T have methods). -// Using a pointer to this struct reduces the overall size required -// to describe an unnamed type with no methods. type uncommonType struct { - name *string // name of type - pkgPath *string // import path; nil for built-in types like int, string - methods []_method // methods associated with type -} - -// BoolType represents a boolean type. -type BoolType commonType - -// FloatType represents a float type. -type FloatType commonType - -// ComplexType represents a complex type. -type ComplexType commonType - -// IntType represents an int type. -type IntType commonType - -// UintType represents a uint type. -type UintType commonType - -// StringType represents a string type. -type StringType commonType - -// UintptrType represents a uintptr type. -type UintptrType commonType - -// UnsafePointerType represents an unsafe.Pointer type. -type UnsafePointerType commonType - -// ArrayType represents a fixed array type. -type ArrayType struct { - commonType - elem *Type // array element type - slice *Type // slice type - len uintptr -} - -// SliceType represents a slice type. -type SliceType struct { - commonType - elem *Type // slice element type -} - -// ChanDir represents a channel type's direction. -type ChanDir int - -const ( - RecvDir ChanDir = 1 << iota // <-chan - SendDir // chan<- - BothDir = RecvDir | SendDir // chan -) - -// ChanType represents a channel type. -type ChanType struct { - commonType - elem *Type // channel element type - dir uintptr // channel direction (ChanDir) -} - -// FuncType represents a function type. -type FuncType struct { - commonType - dotdotdot bool // last input parameter is ... - in []*Type // input parameter types - out []*Type // output parameter types -} - -// Method on interface type -type _imethod struct { // underscore is to avoid collision with C - name *string // name of method - pkgPath *string // nil for exported Names; otherwise import path - typ *Type // .(*FuncType) underneath -} - -// InterfaceType represents an interface type. -type InterfaceType struct { - commonType - methods []_imethod // sorted by hash + name *string + pkgPath *string + methods []_method } -// MapType represents a map type. -type MapType struct { - commonType - key *Type // map key type - elem *Type // map element (value) type -} - -// PtrType represents a pointer type. -type PtrType struct { - commonType - elem *Type // pointer element (pointed at) type -} - -// Struct field -type structField struct { - name *string // nil for embedded fields - pkgPath *string // nil for exported Names; otherwise import path - typ *Type // type of field - tag *string // nil if no tag - offset uintptr // byte offset of field within struct +type _imethod struct { + name *string + pkgPath *string + typ *commonType } -// StructType represents a struct type. -type StructType struct { +type interfaceType struct { commonType - fields []structField // sorted by offset -} - -/* - * Must match iface.c:/Itab and compilers. - * NOTE: this is the version used by the reflection code, there is another - * one in iface_defs.go that is closer to the original C version. - */ -type Itable struct { - Itype *Type // (*tab.inter).(*InterfaceType) is the interface type - Type *Type - link *Itable - bad int32 - unused int32 - Fn [100000]uintptr // bigger than we'll ever see + methods []_imethod } diff --git a/libgo/go/sort/example_interface_test.go b/libgo/go/sort/example_interface_test.go new file mode 100644 index 00000000000..4c88821be7c --- /dev/null +++ b/libgo/go/sort/example_interface_test.go @@ -0,0 +1,77 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sort_test + +import ( + "fmt" + "sort" +) + +type Grams int + +func (g Grams) String() string { return fmt.Sprintf("%dg", int(g)) } + +type Organ struct { + Name string + Weight Grams +} + +type Organs []*Organ + +func (s Organs) Len() int { return len(s) } +func (s Organs) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// ByName implements sort.Interface by providing Less and using the Len and +// Swap methods of the embedded Organs value. +type ByName struct{ Organs } + +func (s ByName) Less(i, j int) bool { return s.Organs[i].Name < s.Organs[j].Name } + +// ByWeight implements sort.Interface by providing Less and using the Len and +// Swap methods of the embedded Organs value. +type ByWeight struct{ Organs } + +func (s ByWeight) Less(i, j int) bool { return s.Organs[i].Weight < s.Organs[j].Weight } + +func ExampleInterface() { + s := []*Organ{ + {"brain", 1340}, + {"heart", 290}, + {"liver", 1494}, + {"pancreas", 131}, + {"prostate", 62}, + {"spleen", 162}, + } + + sort.Sort(ByWeight{s}) + fmt.Println("Organs by weight:") + printOrgans(s) + + sort.Sort(ByName{s}) + fmt.Println("Organs by name:") + printOrgans(s) + + // Output: + // Organs by weight: + // prostate (62g) + // pancreas (131g) + // spleen (162g) + // heart (290g) + // brain (1340g) + // liver (1494g) + // Organs by name: + // brain (1340g) + // heart (290g) + // liver (1494g) + // pancreas (131g) + // prostate (62g) + // spleen (162g) +} + +func printOrgans(s []*Organ) { + for _, o := range s { + fmt.Printf("%-8s (%v)\n", o.Name, o.Weight) + } +} diff --git a/libgo/go/sort/example_reverse_test.go b/libgo/go/sort/example_reverse_test.go new file mode 100644 index 00000000000..7c7f05bf3a2 --- /dev/null +++ b/libgo/go/sort/example_reverse_test.go @@ -0,0 +1,30 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sort_test + +import ( + "fmt" + "sort" +) + +// Reverse embeds a sort.Interface value and implements a reverse sort over +// that value. +type Reverse struct { + // This embedded Interface permits Reverse to use the methods of + // another Interface implementation. + sort.Interface +} + +// Less returns the opposite of the embedded implementation's Less method. +func (r Reverse) Less(i, j int) bool { + return r.Interface.Less(j, i) +} + +func ExampleInterface_reverse() { + s := []int{5, 2, 6, 3, 1, 4} // unsorted + sort.Sort(Reverse{sort.IntSlice(s)}) + fmt.Println(s) + // Output: [6 5 4 3 2 1] +} diff --git a/libgo/go/sort/example_test.go b/libgo/go/sort/example_test.go index 2224db7e13c..f57d02546f7 100644 --- a/libgo/go/sort/example_test.go +++ b/libgo/go/sort/example_test.go @@ -9,9 +9,9 @@ import ( "sort" ) -// [1 2 3 4 5 6] func ExampleInts() { s := []int{5, 2, 6, 3, 1, 4} // unsorted sort.Ints(s) fmt.Println(s) + // Output: [1 2 3 4 5 6] } diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index 42fc431db8a..d99117bed1d 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -13,6 +13,7 @@ package strconv // 3) Multiply by 2^precision and round to get mantissa. import "math" +import "runtime" var optimize = true // can change for testing @@ -52,10 +53,10 @@ func special(s string) (f float64, ok bool) { return } -// TODO(rsc): Better truncation handling. func (b *decimal) set(s string) (ok bool) { i := 0 b.neg = false + b.trunc = false // optional sign if i >= len(s) { @@ -88,8 +89,12 @@ func (b *decimal) set(s string) (ok bool) { b.dp-- continue } - b.d[b.nd] = s[i] - b.nd++ + if b.nd < len(b.d) { + b.d[b.nd] = s[i] + b.nd++ + } else if s[i] != '0' { + b.trunc = true + } continue } break @@ -296,6 +301,11 @@ func (d *decimal) atof64() (f float64, ok bool) { if d.nd > 15 { return } + // gccgo gets this wrong on 32-bit i386 when not using -msse. + // See TestRoundTrip in atof_test.go for a test case. + if runtime.GOARCH == "386" { + return + } switch { case d.dp == d.nd: // int f := d.atof64int() diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go index 3fa637d2bc6..59950238230 100644 --- a/libgo/go/strconv/atof_test.go +++ b/libgo/go/strconv/atof_test.go @@ -9,6 +9,7 @@ import ( "math/rand" "reflect" . "strconv" + "strings" "testing" "time" ) @@ -117,6 +118,20 @@ var atoftests = []atofTest{ // A very large number (initially wrongly parsed by the fast algorithm). {"4.630813248087435e+307", "4.630813248087435e+307", nil}, + + // A different kind of very large number. + {"22.222222222222222", "22.22222222222222", nil}, + {"2." + strings.Repeat("2", 4000) + "e+1", "22.22222222222222", nil}, + + // Exactly halfway between 1 and math.Nextafter(1, 2). + // Round to even (down). + {"1.00000000000000011102230246251565404236316680908203125", "1", nil}, + // Slightly lower; still round down. + {"1.00000000000000011102230246251565404236316680908203124", "1", nil}, + // Slightly higher; round up. + {"1.00000000000000011102230246251565404236316680908203126", "1.0000000000000002", nil}, + // Slightly higher, but you have to read all the way to the end. + {"1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1", "1.0000000000000002", nil}, } type atofSimpleTest struct { @@ -211,6 +226,44 @@ func TestAtofRandom(t *testing.T) { t.Logf("tested %d random numbers", len(atofRandomTests)) } +var roundTripCases = []struct { + f float64 + s string +}{ + // Issue 2917. + // This test will break the optimized conversion if the + // FPU is using 80-bit registers instead of 64-bit registers, + // usually because the operating system initialized the + // thread with 80-bit precision and the Go runtime didn't + // fix the FP control word. + {8865794286000691 << 39, "4.87402195346389e+27"}, + {8865794286000692 << 39, "4.8740219534638903e+27"}, +} + +func TestRoundTrip(t *testing.T) { + for _, tt := range roundTripCases { + old := SetOptimize(false) + s := FormatFloat(tt.f, 'g', -1, 64) + if s != tt.s { + t.Errorf("no-opt FormatFloat(%b) = %s, want %s", tt.f, s, tt.s) + } + f, err := ParseFloat(tt.s, 64) + if f != tt.f || err != nil { + t.Errorf("no-opt ParseFloat(%s) = %b, %v want %b, nil", tt.s, f, err, tt.f) + } + SetOptimize(true) + s = FormatFloat(tt.f, 'g', -1, 64) + if s != tt.s { + t.Errorf("opt FormatFloat(%b) = %s, want %s", tt.f, s, tt.s) + } + f, err = ParseFloat(tt.s, 64) + if f != tt.f || err != nil { + t.Errorf("opt ParseFloat(%s) = %b, %v want %b, nil", tt.s, f, err, tt.f) + } + SetOptimize(old) + } +} + func BenchmarkAtof64Decimal(b *testing.B) { for i := 0; i < b.N; i++ { ParseFloat("33909", 64) diff --git a/libgo/go/strconv/decimal.go b/libgo/go/strconv/decimal.go index cc5591a8d8f..a75071dcc46 100644 --- a/libgo/go/strconv/decimal.go +++ b/libgo/go/strconv/decimal.go @@ -12,12 +12,11 @@ package strconv type decimal struct { - // TODO(rsc): Can make d[] a bit smaller and add - // truncated bool; - d [800]byte // digits - nd int // number of digits used - dp int // decimal point - neg bool + d [800]byte // digits + nd int // number of digits used + dp int // decimal point + neg bool + trunc bool // discarded nonzero digits beyond d[:nd] } func (a *decimal) String() string { @@ -145,8 +144,12 @@ func rightShift(a *decimal, k uint) { for n > 0 { dig := n >> k n -= dig << k - a.d[w] = byte(dig + '0') - w++ + if w < len(a.d) { + a.d[w] = byte(dig + '0') + w++ + } else if dig > 0 { + a.trunc = true + } n = n * 10 } @@ -242,7 +245,11 @@ func leftShift(a *decimal, k uint) { quo := n / 10 rem := n - 10*quo w-- - a.d[w] = byte(rem + '0') + if w < len(a.d) { + a.d[w] = byte(rem + '0') + } else if rem != 0 { + a.trunc = true + } n = quo } @@ -251,11 +258,18 @@ func leftShift(a *decimal, k uint) { quo := n / 10 rem := n - 10*quo w-- - a.d[w] = byte(rem + '0') + if w < len(a.d) { + a.d[w] = byte(rem + '0') + } else if rem != 0 { + a.trunc = true + } n = quo } a.nd += delta + if a.nd >= len(a.d) { + a.nd = len(a.d) + } a.dp += delta trim(a) } @@ -286,6 +300,10 @@ func shouldRoundUp(a *decimal, nd int) bool { return false } if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even + // if we truncated, a little higher than what's recorded - always round up + if a.trunc { + return true + } return nd > 0 && (a.d[nd-1]-'0')%2 != 0 } // not halfway - digit tells all @@ -293,7 +311,6 @@ func shouldRoundUp(a *decimal, nd int) bool { } // Round a to nd digits (or fewer). -// Returns receiver for convenience. // If nd is zero, it means we're rounding // just to the left of the digits, as in // 0.09 -> 0.1. @@ -309,7 +326,6 @@ func (a *decimal) Round(nd int) { } // Round a down to nd digits (or fewer). -// Returns receiver for convenience. func (a *decimal) RoundDown(nd int) { if nd < 0 || nd >= a.nd { return @@ -319,7 +335,6 @@ func (a *decimal) RoundDown(nd int) { } // Round a up to nd digits (or fewer). -// Returns receiver for convenience. func (a *decimal) RoundUp(nd int) { if nd < 0 || nd >= a.nd { return diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go index 64ab84f4554..aa5e5607ca0 100644 --- a/libgo/go/strconv/extfloat.go +++ b/libgo/go/strconv/extfloat.go @@ -477,7 +477,7 @@ func (f *extFloat) ShortestDecimal(d *decimal, lower, upper *extFloat) bool { // all data is known with a error estimate of ulpBinary*ε. func adjustLastDigit(d *decimal, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool { if ulpDecimal < 2*ulpBinary { - // Appromixation is too wide. + // Approximation is too wide. return false } for currentDiff+ulpDecimal/2+ulpBinary < targetDiff { diff --git a/libgo/go/strconv/itoa_test.go b/libgo/go/strconv/itoa_test.go index bac23e6ea67..63d2fa44e02 100644 --- a/libgo/go/strconv/itoa_test.go +++ b/libgo/go/strconv/itoa_test.go @@ -127,6 +127,7 @@ func TestUitoa(t *testing.T) { } func numAllocations(f func()) int { + runtime.GC() memstats := new(runtime.MemStats) runtime.ReadMemStats(memstats) n0 := memstats.Mallocs diff --git a/libgo/go/strings/example_test.go b/libgo/go/strings/example_test.go index 16e53678b20..daeb85ef6bb 100644 --- a/libgo/go/strings/example_test.go +++ b/libgo/go/strings/example_test.go @@ -9,7 +9,174 @@ import ( "strings" ) -// Fields are: ["foo" "bar" "baz"] func ExampleFields() { fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz ")) + // Output: Fields are: ["foo" "bar" "baz"] +} + +func ExampleContains() { + fmt.Println(strings.Contains("seafood", "foo")) + fmt.Println(strings.Contains("seafood", "bar")) + fmt.Println(strings.Contains("seafood", "")) + fmt.Println(strings.Contains("", "")) + // Output: + // true + // false + // true + // true +} + +func ExampleContainsAny() { + fmt.Println(strings.ContainsAny("team", "i")) + fmt.Println(strings.ContainsAny("failure", "u & i")) + fmt.Println(strings.ContainsAny("foo", "")) + fmt.Println(strings.ContainsAny("", "")) + // Output: + // false + // true + // false + // false +} + +func ExampleCount() { + fmt.Println(strings.Count("cheese", "e")) + fmt.Println(strings.Count("five", "")) // before & after each rune + + // Output: + // 3 + // 5 +} + +func ExampleEqualFold() { + fmt.Println(strings.EqualFold("Go", "go")) + // Output: true +} + +func ExampleIndex() { + fmt.Println(strings.Index("chicken", "ken")) + fmt.Println(strings.Index("chicken", "dmr")) + // Output: + // 4 + // -1 +} + +func ExampleRune() { + fmt.Println(strings.IndexRune("chicken", 'k')) + fmt.Println(strings.IndexRune("chicken", 'd')) + // Output: + // 4 + // -1 +} + +func ExampleLastIndex() { + fmt.Println(strings.Index("go gopher", "go")) + fmt.Println(strings.LastIndex("go gopher", "go")) + fmt.Println(strings.LastIndex("go gopher", "rodent")) + // Output: + // 0 + // 3 + // -1 +} + +func ExampleJoin() { + s := []string{"foo", "bar", "baz"} + fmt.Println(strings.Join(s, ", ")) + // Output: foo, bar, baz +} + +func ExampleRepeat() { + fmt.Println("ba" + strings.Repeat("na", 2)) + // Output: banana +} + +func ExampleReplace() { + fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2)) + fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1)) + // Output: + // oinky oinky oink + // moo moo moo +} + +func ExampleSplit() { + fmt.Printf("%q\n", strings.Split("a,b,c", ",")) + fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a ")) + fmt.Printf("%q\n", strings.Split(" xyz ", "")) + fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins")) + // Output: + // ["a" "b" "c"] + // ["" "man " "plan " "canal panama"] + // [" " "x" "y" "z" " "] + // [""] +} + +func ExampleSplitN() { + fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2)) + z := strings.SplitN("a,b,c", ",", 0) + fmt.Printf("%q (nil = %v)\n", z, z == nil) + // Output: + // ["a" "b,c"] + // [] (nil = true) +} + +func ExampleSplitAfter() { + fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ",")) + // Output: ["a," "b," "c"] +} + +func ExampleSplitAfterN() { + fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2)) + // Output: ["a," "b,c"] +} + +func ExampleTitle() { + fmt.Println(strings.Title("her royal highness")) + // Output: Her Royal Highness +} + +func ExampleToTitle() { + fmt.Println(strings.ToTitle("loud noises")) + fmt.Println(strings.ToTitle("хлеб")) + // Output: + // LOUD NOISES + // ХЛЕБ +} + +func ExampleTrim() { + fmt.Printf("[%q]", strings.Trim(" !!! Achtung !!! ", "! ")) + // Output: ["Achtung"] +} + +func ExampleMap() { + rot13 := func(r rune) rune { + switch { + case r >= 'A' && r <= 'Z': + return 'A' + (r-'A'+13)%26 + case r >= 'a' && r <= 'z': + return 'a' + (r-'a'+13)%26 + } + return r + } + fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher...")) + // Output: 'Gjnf oevyyvt naq gur fyvgul tbcure... +} + +func ExampleTrimSpace() { + fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n")) + // Output: a lone gopher +} + +func ExampleNewReplacer() { + r := strings.NewReplacer("<", "<", ">", ">") + fmt.Println(r.Replace("This is <b>HTML</b>!")) + // Output: This is <b>HTML</b>! +} + +func ExampleToUpper() { + fmt.Println(strings.ToUpper("Gopher")) + // Output: GOPHER +} + +func ExampleToLower() { + fmt.Println(strings.ToLower("Gopher")) + // Output: gopher } diff --git a/libgo/go/strings/reader.go b/libgo/go/strings/reader.go index 8ff851f36a8..8569805552d 100644 --- a/libgo/go/strings/reader.go +++ b/libgo/go/strings/reader.go @@ -10,8 +10,9 @@ import ( "unicode/utf8" ) -// A Reader implements the io.Reader, io.ByteScanner, and -// io.RuneScanner interfaces by reading from a string. +// A Reader implements the io.Reader, io.ReaderAt, io.Seeker, +// io.ByteScanner, and io.RuneScanner interfaces by reading +// from a string. type Reader struct { s string i int // current reading index @@ -21,10 +22,16 @@ type Reader struct { // Len returns the number of bytes of the unread portion of the // string. func (r *Reader) Len() int { + if r.i >= len(r.s) { + return 0 + } return len(r.s) - r.i } func (r *Reader) Read(b []byte) (n int, err error) { + if len(b) == 0 { + return 0, nil + } if r.i >= len(r.s) { return 0, io.EOF } @@ -34,6 +41,20 @@ func (r *Reader) Read(b []byte) (n int, err error) { return } +func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) { + if off < 0 { + return 0, errors.New("strings: invalid offset") + } + if off >= int64(len(r.s)) { + return 0, io.EOF + } + n = copy(b, r.s[int(off):]) + if n < len(b) { + err = io.EOF + } + return +} + func (r *Reader) ReadByte() (b byte, err error) { if r.i >= len(r.s) { return 0, io.EOF @@ -44,9 +65,6 @@ func (r *Reader) ReadByte() (b byte, err error) { return } -// UnreadByte moves the reading position back by one byte. -// It is an error to call UnreadByte if nothing has been -// read yet. func (r *Reader) UnreadByte() error { if r.i <= 0 { return errors.New("strings.Reader: at beginning of string") @@ -56,11 +74,6 @@ func (r *Reader) UnreadByte() error { return nil } -// ReadRune reads and returns the next UTF-8-encoded -// Unicode code point from the buffer. -// If no bytes are available, the error returned is io.EOF. -// If the bytes are an erroneous UTF-8 encoding, it -// consumes one byte and returns U+FFFD, 1. func (r *Reader) ReadRune() (ch rune, size int, err error) { if r.i >= len(r.s) { return 0, 0, io.EOF @@ -75,9 +88,6 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) { return } -// UnreadRune causes the next call to ReadRune to return the same rune -// as the previous call to ReadRune. -// The last method called on r must have been ReadRune. func (r *Reader) UnreadRune() error { if r.prevRune < 0 { return errors.New("strings.Reader: previous operation was not ReadRune") @@ -87,6 +97,29 @@ func (r *Reader) UnreadRune() error { return nil } +// Seek implements the io.Seeker interface. +func (r *Reader) Seek(offset int64, whence int) (int64, error) { + var abs int64 + switch whence { + case 0: + abs = offset + case 1: + abs = int64(r.i) + offset + case 2: + abs = int64(len(r.s)) + offset + default: + return 0, errors.New("strings: invalid whence") + } + if abs < 0 { + return 0, errors.New("strings: negative position") + } + if abs >= 1<<31 { + return 0, errors.New("strings: position out of range") + } + r.i = int(abs) + return abs, nil +} + // NewReader returns a new Reader reading from s. // It is similar to bytes.NewBufferString but more efficient and read-only. func NewReader(s string) *Reader { return &Reader{s, 0, -1} } diff --git a/libgo/go/strings/reader_test.go b/libgo/go/strings/reader_test.go new file mode 100644 index 00000000000..a99ae2a0ea6 --- /dev/null +++ b/libgo/go/strings/reader_test.go @@ -0,0 +1,88 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strings_test + +import ( + "fmt" + "io" + "os" + "strings" + "testing" +) + +func TestReader(t *testing.T) { + r := strings.NewReader("0123456789") + tests := []struct { + off int64 + seek int + n int + want string + wantpos int64 + seekerr string + }{ + {seek: os.SEEK_SET, off: 0, n: 20, want: "0123456789"}, + {seek: os.SEEK_SET, off: 1, n: 1, want: "1"}, + {seek: os.SEEK_CUR, off: 1, wantpos: 3, n: 2, want: "34"}, + {seek: os.SEEK_SET, off: -1, seekerr: "strings: negative position"}, + {seek: os.SEEK_SET, off: 1<<31 - 1}, + {seek: os.SEEK_CUR, off: 1, seekerr: "strings: position out of range"}, + {seek: os.SEEK_SET, n: 5, want: "01234"}, + {seek: os.SEEK_CUR, n: 5, want: "56789"}, + {seek: os.SEEK_END, off: -1, n: 1, wantpos: 9, want: "9"}, + } + + for i, tt := range tests { + pos, err := r.Seek(tt.off, tt.seek) + if err == nil && tt.seekerr != "" { + t.Errorf("%d. want seek error %q", i, tt.seekerr) + continue + } + if err != nil && err.Error() != tt.seekerr { + t.Errorf("%d. seek error = %q; want %q", i, err.Error(), tt.seekerr) + continue + } + if tt.wantpos != 0 && tt.wantpos != pos { + t.Errorf("%d. pos = %d, want %d", i, pos, tt.wantpos) + } + buf := make([]byte, tt.n) + n, err := r.Read(buf) + if err != nil { + t.Errorf("%d. read = %v", i, err) + continue + } + got := string(buf[:n]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + } +} + +func TestReaderAt(t *testing.T) { + r := strings.NewReader("0123456789") + tests := []struct { + off int64 + n int + want string + wanterr interface{} + }{ + {0, 10, "0123456789", nil}, + {1, 10, "123456789", io.EOF}, + {1, 9, "123456789", nil}, + {11, 10, "", io.EOF}, + {0, 0, "", nil}, + {-1, 0, "", "strings: invalid offset"}, + } + for i, tt := range tests { + b := make([]byte, tt.n) + rn, err := r.ReadAt(b, tt.off) + got := string(b[:rn]) + if got != tt.want { + t.Errorf("%d. got %q; want %q", i, got, tt.want) + } + if fmt.Sprintf("%v", err) != fmt.Sprintf("%v", tt.wanterr) { + t.Errorf("%d. got error = %v; want %v", i, err, tt.wanterr) + } + } +} diff --git a/libgo/go/sync/cond.go b/libgo/go/sync/cond.go index 75494b53536..1fc3deaf1e0 100644 --- a/libgo/go/sync/cond.go +++ b/libgo/go/sync/cond.go @@ -4,8 +4,6 @@ package sync -import "runtime" - // Cond implements a condition variable, a rendezvous point // for goroutines waiting for or announcing the occurrence // of an event. @@ -43,9 +41,10 @@ func NewCond(l Locker) *Cond { // Wait atomically unlocks c.L and suspends execution // of the calling goroutine. After later resuming execution, -// Wait locks c.L before returning. +// Wait locks c.L before returning. Unlike in other systems, +// Wait cannot return unless awoken by Broadcast or Signal. // -// Because L is not locked when Wait first resumes, the caller +// Because c.L is not locked when Wait first resumes, the caller // typically cannot assume that the condition is true when // Wait returns. Instead, the caller should Wait in a loop: // @@ -65,7 +64,7 @@ func (c *Cond) Wait() { c.newWaiters++ c.m.Unlock() c.L.Unlock() - runtime.Semacquire(s) + runtime_Semacquire(s) c.L.Lock() } @@ -84,7 +83,7 @@ func (c *Cond) Signal() { } if c.oldWaiters > 0 { c.oldWaiters-- - runtime.Semrelease(c.oldSema) + runtime_Semrelease(c.oldSema) } c.m.Unlock() } @@ -98,13 +97,13 @@ func (c *Cond) Broadcast() { // Wake both generations. if c.oldWaiters > 0 { for i := 0; i < c.oldWaiters; i++ { - runtime.Semrelease(c.oldSema) + runtime_Semrelease(c.oldSema) } c.oldWaiters = 0 } if c.newWaiters > 0 { for i := 0; i < c.newWaiters; i++ { - runtime.Semrelease(c.newSema) + runtime_Semrelease(c.newSema) } c.newWaiters = 0 c.newSema = nil diff --git a/libgo/go/sync/example_test.go b/libgo/go/sync/example_test.go new file mode 100644 index 00000000000..15649240035 --- /dev/null +++ b/libgo/go/sync/example_test.go @@ -0,0 +1,54 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync_test + +import ( + "fmt" + "net/http" + "sync" +) + +// This example fetches several URLs concurrently, +// using a WaitGroup to block until all the fetches are complete. +func ExampleWaitGroup() { + var wg sync.WaitGroup + var urls = []string{ + "http://www.golang.org/", + "http://www.google.com/", + "http://www.somestupidname.com/", + } + for _, url := range urls { + // Increment the WaitGroup counter. + wg.Add(1) + // Launch a goroutine to fetch the URL. + go func(url string) { + // Fetch the URL. + http.Get(url) + // Decrement the counter. + wg.Done() + }(url) + } + // Wait for all HTTP fetches to complete. + wg.Wait() +} + +func ExampleOnce() { + var once sync.Once + onceBody := func() { + fmt.Printf("Only once\n") + } + done := make(chan bool) + for i := 0; i < 10; i++ { + go func() { + once.Do(onceBody) + done <- true + }() + } + for i := 0; i < 10; i++ { + <-done + } + // Output: + // Only once +} diff --git a/libgo/go/sync/export_test.go b/libgo/go/sync/export_test.go new file mode 100644 index 00000000000..fa5983a2d1e --- /dev/null +++ b/libgo/go/sync/export_test.go @@ -0,0 +1,9 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync + +// Export for testing. +var Runtime_Semacquire = runtime_Semacquire +var Runtime_Semrelease = runtime_Semrelease diff --git a/libgo/go/sync/mutex.go b/libgo/go/sync/mutex.go index 4fc02743c6e..9494cc3f826 100644 --- a/libgo/go/sync/mutex.go +++ b/libgo/go/sync/mutex.go @@ -10,10 +10,7 @@ // Values containing the types defined in this package should not be copied. package sync -import ( - "runtime" - "sync/atomic" -) +import "sync/atomic" // A Mutex is a mutual exclusion lock. // Mutexes can be created as part of other structures; @@ -60,7 +57,7 @@ func (m *Mutex) Lock() { if old&mutexLocked == 0 { break } - runtime.Semacquire(&m.sema) + runtime_Semacquire(&m.sema) awoke = true } } @@ -89,7 +86,7 @@ func (m *Mutex) Unlock() { // Grab the right to wake someone. new = (old - 1<<mutexWaiterShift) | mutexWoken if atomic.CompareAndSwapInt32(&m.state, old, new) { - runtime.Semrelease(&m.sema) + runtime_Semrelease(&m.sema) return } old = m.state diff --git a/libgo/go/sync/mutex_test.go b/libgo/go/sync/mutex_test.go index 47758844f27..bf78c6f609c 100644 --- a/libgo/go/sync/mutex_test.go +++ b/libgo/go/sync/mutex_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// GOMAXPROCS=10 gotest +// GOMAXPROCS=10 go test package sync_test @@ -15,8 +15,8 @@ import ( func HammerSemaphore(s *uint32, loops int, cdone chan bool) { for i := 0; i < loops; i++ { - runtime.Semacquire(s) - runtime.Semrelease(s) + Runtime_Semacquire(s) + Runtime_Semrelease(s) } cdone <- true } diff --git a/libgo/go/sync/runtime.go b/libgo/go/sync/runtime.go new file mode 100644 index 00000000000..e99599c11ae --- /dev/null +++ b/libgo/go/sync/runtime.go @@ -0,0 +1,18 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync + +// defined in package runtime + +// Semacquire waits until *s > 0 and then atomically decrements it. +// It is intended as a simple sleep primitive for use by the synchronization +// library and should not be used directly. +func runtime_Semacquire(s *uint32) + +// Semrelease atomically increments *s and notifies a waiting goroutine +// if one is blocked in Semacquire. +// It is intended as a simple wakeup primitive for use by the synchronization +// library and should not be used directly. +func runtime_Semrelease(s *uint32) diff --git a/libgo/go/runtime/sema_test.go b/libgo/go/sync/runtime_sema_test.go index d95bb1ec58f..57a8dbee783 100644 --- a/libgo/go/runtime/sema_test.go +++ b/libgo/go/sync/runtime_sema_test.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package runtime_test +package sync_test import ( "runtime" + . "sync" "sync/atomic" "testing" ) @@ -25,8 +26,8 @@ func BenchmarkSemaUncontended(b *testing.B) { for atomic.AddInt32(&N, -1) >= 0 { runtime.Gosched() for g := 0; g < CallsPerSched; g++ { - runtime.Semrelease(&sem.sem) - runtime.Semacquire(&sem.sem) + Runtime_Semrelease(&sem.sem) + Runtime_Semacquire(&sem.sem) } } c <- true @@ -48,7 +49,7 @@ func benchmarkSema(b *testing.B, block, work bool) { if block { for p := 0; p < procs/2; p++ { go func() { - runtime.Semacquire(&sem) + Runtime_Semacquire(&sem) c2 <- true }() } @@ -59,18 +60,18 @@ func benchmarkSema(b *testing.B, block, work bool) { for atomic.AddInt32(&N, -1) >= 0 { runtime.Gosched() for g := 0; g < CallsPerSched; g++ { - runtime.Semrelease(&sem) + Runtime_Semrelease(&sem) if work { for i := 0; i < LocalWork; i++ { foo *= 2 foo /= 2 } } - runtime.Semacquire(&sem) + Runtime_Semacquire(&sem) } } c <- foo == 42 - runtime.Semrelease(&sem) + Runtime_Semrelease(&sem) }() } if block { diff --git a/libgo/go/sync/rwmutex.go b/libgo/go/sync/rwmutex.go index cb1a47720b2..782a9c31968 100644 --- a/libgo/go/sync/rwmutex.go +++ b/libgo/go/sync/rwmutex.go @@ -4,10 +4,7 @@ package sync -import ( - "runtime" - "sync/atomic" -) +import "sync/atomic" // An RWMutex is a reader/writer mutual exclusion lock. // The lock can be held by an arbitrary number of readers @@ -29,7 +26,7 @@ const rwmutexMaxReaders = 1 << 30 func (rw *RWMutex) RLock() { if atomic.AddInt32(&rw.readerCount, 1) < 0 { // A writer is pending, wait for it. - runtime.Semacquire(&rw.readerSem) + runtime_Semacquire(&rw.readerSem) } } @@ -42,7 +39,7 @@ func (rw *RWMutex) RUnlock() { // A writer is pending. if atomic.AddInt32(&rw.readerWait, -1) == 0 { // The last reader unblocks the writer. - runtime.Semrelease(&rw.writerSem) + runtime_Semrelease(&rw.writerSem) } } } @@ -60,7 +57,7 @@ func (rw *RWMutex) Lock() { r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders // Wait for active readers. if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 { - runtime.Semacquire(&rw.writerSem) + runtime_Semacquire(&rw.writerSem) } } @@ -75,7 +72,7 @@ func (rw *RWMutex) Unlock() { r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders) // Unblock blocked readers, if any. for i := 0; i < int(r); i++ { - runtime.Semrelease(&rw.readerSem) + runtime_Semrelease(&rw.readerSem) } // Allow other writers to proceed. rw.w.Unlock() diff --git a/libgo/go/sync/rwmutex_test.go b/libgo/go/sync/rwmutex_test.go index dc8ce9653ce..39d5d6540de 100644 --- a/libgo/go/sync/rwmutex_test.go +++ b/libgo/go/sync/rwmutex_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// GOMAXPROCS=10 gotest +// GOMAXPROCS=10 go test package sync_test diff --git a/libgo/go/sync/waitgroup.go b/libgo/go/sync/waitgroup.go index a4c9b7e43cd..0165b1ffb2b 100644 --- a/libgo/go/sync/waitgroup.go +++ b/libgo/go/sync/waitgroup.go @@ -4,31 +4,13 @@ package sync -import ( - "runtime" - "sync/atomic" -) +import "sync/atomic" // A WaitGroup waits for a collection of goroutines to finish. // The main goroutine calls Add to set the number of // goroutines to wait for. Then each of the goroutines // runs and calls Done when finished. At the same time, // Wait can be used to block until all goroutines have finished. -// -// For example: -// -// for i := 0; i < n; i++ { -// if !condition(i) { -// continue -// } -// wg.Add(1) -// go func() { -// // Do something. -// wg.Done() -// }() -// } -// wg.Wait() -// type WaitGroup struct { m Mutex counter int32 @@ -60,7 +42,7 @@ func (wg *WaitGroup) Add(delta int) { } wg.m.Lock() for i := int32(0); i < wg.waiters; i++ { - runtime.Semrelease(wg.sema) + runtime_Semrelease(wg.sema) } wg.waiters = 0 wg.sema = nil @@ -93,5 +75,5 @@ func (wg *WaitGroup) Wait() { } s := wg.sema wg.m.Unlock() - runtime.Semacquire(s) + runtime_Semacquire(s) } diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go index 68143536182..f1f7a188de2 100644 --- a/libgo/go/syscall/exec_bsd.go +++ b/libgo/go/syscall/exec_bsd.go @@ -38,8 +38,10 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr i int ) - // guard against side effects of shuffling fds below. - fd := append([]int(nil), attr.Files...) + fd := make([]int, len(attr.Files)) + for i, ufd := range attr.Files { + fd[i] = int(ufd) + } // About to call fork. // No more allocation or calls of non-assembly functions. diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go index cc3cfdb0805..a6c4427a59f 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -21,7 +21,7 @@ type SysProcAttr struct { Setpgid bool // Set process group ID to new pid (SYSV setpgrp) Setctty bool // Set controlling terminal to fd 0 Noctty bool // Detach fd 0 from controlling terminal - Pdeathsig int // Signal that the process will get when its parent dies (Linux only) + Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only) } // Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child. @@ -43,7 +43,10 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr ) // guard against side effects of shuffling fds below. - fd := append([]int(nil), attr.Files...) + fd := make([]int, len(attr.Files)) + for i, ufd := range attr.Files { + fd[i] = int(ufd) + } // About to call fork. // No more allocation or calls of non-assembly functions. @@ -61,7 +64,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // Parent death signal if sys.Pdeathsig != 0 { - _, err1 = raw_prctl(PR_SET_PDEATHSIG, sys.Pdeathsig, 0, 0, 0) + _, err1 = raw_prctl(PR_SET_PDEATHSIG, int(sys.Pdeathsig), 0, 0, 0) if err1 != 0 { goto childerror } diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index 49441f8e1c4..664908d1310 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -141,9 +141,9 @@ type Credential struct { // ProcAttr holds attributes that will be applied to a new process started // by StartProcess. type ProcAttr struct { - Dir string // Current working directory. - Env []string // Environment. - Files []int // File descriptors. + Dir string // Current working directory. + Env []string // Environment. + Files []uintptr // File descriptors. Sys *SysProcAttr } diff --git a/libgo/go/syscall/exec_windows.go b/libgo/go/syscall/exec_windows.go index 6cb25a7d00a..4dc4d059d7e 100644 --- a/libgo/go/syscall/exec_windows.go +++ b/libgo/go/syscall/exec_windows.go @@ -220,7 +220,7 @@ func joinExeDirAndFName(dir, p string) (name string, err error) { type ProcAttr struct { Dir string Env []string - Files []Handle + Files []uintptr Sys *SysProcAttr } diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index aa1440118e3..bb960731f75 100644 --- a/libgo/go/syscall/libcall_linux.go +++ b/libgo/go/syscall/libcall_linux.go @@ -160,27 +160,23 @@ func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } -// FIXME: mksysinfo needs to produce LINUX_REBOOT_MAGIC[12]. - -// //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) -// //reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int -// func Reboot(cmd int) (err error) { -// return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") -// } +//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) +//reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int +func Reboot(cmd int) (err error) { + return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") +} //sys Acct(path string) (err error) //acct(path *byte) int -// FIXME: mksysinfo Timex -// //sys Adjtimex(buf *Timex) (state int, err error) -// //adjtimex(buf *Timex) int +//sys Adjtimex(buf *Timex) (state int, err error) +//adjtimex(buf *Timex) int //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) //faccessat(dirfd int, pathname *byte, mode int, flags int) int -// FIXME: Only in glibc 2.10 and later. -// //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) -// //fallocate(fd int, mode int, offset Offset_t, len Offset_t) int +//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) +//fallocate(fd int, mode int, offset Offset_t, len Offset_t) int //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //fchmodat(dirfd int, pathname *byte, mode Mode_t, flags int) int @@ -191,19 +187,64 @@ func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) //sys Flock(fd int, how int) (err error) //flock(fd int, how int) int -// FIXME: mksysinfo statfs -// //sys Fstatfs(fd int, buf *Statfs_t) (err error) -// //fstatfs(fd int, buf *Statfs_t) int +//sys Fstatfs(fd int, buf *Statfs_t) (err error) +//fstatfs(fd int, buf *Statfs_t) int func Gettid() (tid int) { r1, _, _ := Syscall(SYS_GETTID, 0, 0, 0) return int(r1) } -// FIXME: mksysinfo linux_dirent -// Or just abandon this function. -// //sys Getdents(fd int, buf []byte) (n int, err error) -// //getdents64(fd int, buf *byte, count uint) +func Getdents(fd int, buf []byte) (n int, err error) { + var p *byte + if len(buf) > 0 { + p = &buf[0] + } else { + p = (*byte)(unsafe.Pointer(&_zero)) + } + entersyscall() + r1, _, errno := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf))) + n = int(r1) + if n < 0 { + err = errno + } + exitsyscall() + return +} + +func clen(n []byte) int { + for i := 0; i < len(n); i++ { + if n[i] == 0 { + return i + } + } + return len(n) +} + +func ReadDirent(fd int, buf []byte) (n int, err error) { + return Getdents(fd, buf) +} + +func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { + origlen := len(buf) + count = 0 + for max != 0 && len(buf) > 0 { + dirent := (*Dirent)(unsafe.Pointer(&buf[0])) + buf = buf[dirent.Reclen:] + if dirent.Ino == 0 { // File absent in directory. + continue + } + bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) + var name = string(bytes[0:clen(bytes[:])]) + if name == "." || name == ".." { // Useless names + continue + } + max-- + count++ + names = append(names, name) + } + return origlen - len(buf), count, names +} //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) //inotify_add_watch(fd int, pathname *byte, mask uint32) int @@ -211,9 +252,8 @@ func Gettid() (tid int) { //sysnb InotifyInit() (fd int, err error) //inotify_init() int -// FIXME: Only in glibc 2.9 and later. -// //sysnb InotifyInit1(flags int) (fd int, err error) -// //inotify_init1(flags int) int +//sysnb InotifyInit1(flags int) (fd int, err error) +//inotify_init1(flags int) int //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) //inotify_rm_watch(fd int, wd uint32) int @@ -283,24 +323,25 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i return } -// FIXME: mksysinfo statfs -// //sys Statfs(path string, buf *Statfs_t) (err error) -// //statfs(path *byte, buf *Statfs_t) int +//sys Statfs(path string, buf *Statfs_t) (err error) +//statfs(path *byte, buf *Statfs_t) int -// FIXME: Only in glibc 2.6 and later. -// //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) -// //sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int +//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) +//sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int -// FIXME: mksysinfo Sysinfo_t -// //sysnb Sysinfo(info *Sysinfo_t) (err error) -// //sysinfo(info *Sysinfo_t) int +//sysnb Sysinfo(info *Sysinfo_t) (err error) +//sysinfo(info *Sysinfo_t) int //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) //tee(rfd int, wfd int, len Size_t, flags uint) Ssize_t -// FIXME: Only available as a syscall. -// //sysnb Tgkill(tgid int, tid int, sig int) (err error) -// //tgkill(tgid int, tid int, sig int) int +func Tgkill(tgid, tid, sig Signal) error { + r1, _, errno := Syscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) + if r1 < 0 { + return errno + } + return nil +} //sys unlinkat(dirfd int, path string, flags int) (err error) //unlinkat(dirfd int, path *byte, flags int) int @@ -315,6 +356,5 @@ func Unlinkat(dirfd int, path string) (err error) { //sys Unshare(flags int) (err error) //unshare(flags int) int -// FIXME: mksysinfo Ustat_t -// //sys Ustat(dev int, ubuf *Ustat_t) (err error) -// //ustat(dev _dev_t, ubuf *Ustat_t) int +//sys Ustat(dev int, ubuf *Ustat_t) (err error) +//ustat(dev _dev_t, ubuf *Ustat_t) int diff --git a/libgo/go/syscall/libcall_posix.go b/libgo/go/syscall/libcall_posix.go index 1226c1cfbd4..92feae0c102 100644 --- a/libgo/go/syscall/libcall_posix.go +++ b/libgo/go/syscall/libcall_posix.go @@ -61,6 +61,18 @@ func Getwd() (ret string, err error) { } } +func Getcwd(buf []byte) (n int, err error) { + err = getcwd(&buf[0], Size_t(len(buf))) + if err == nil { + i := 0 + for buf[i] != 0 { + i++ + } + n = i + 1 + } + return +} + //sysnb getgroups(size int, list *Gid_t) (nn int, err error) //getgroups(size int, list *Gid_t) int @@ -116,8 +128,8 @@ func (w WaitStatus) Stopped() bool func (w WaitStatus) Continued() bool func (w WaitStatus) CoreDump() bool func (w WaitStatus) ExitStatus() int -func (w WaitStatus) Signal() int -func (w WaitStatus) StopSignal() int +func (w WaitStatus) Signal() Signal +func (w WaitStatus) StopSignal() Signal func (w WaitStatus) TrapCause() int //sys Mkfifo(path string, mode uint32) (err error) @@ -226,9 +238,8 @@ func FDZero(set *FdSet) { //sysnb Getppid() (ppid int) //getppid() Pid_t -// FIXME: mksysinfo Rlimit -// //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) -// //getrlimit(resource int, rlim *Rlimit) int +//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) +//getrlimit(resource int, rlim *Rlimit) int //sysnb Getrusage(who int, rusage *Rusage) (err error) //getrusage(who int, rusage *Rusage) int @@ -242,7 +253,7 @@ func Gettimeofday(tv *Timeval) (err error) { //sysnb Getuid() (uid int) //getuid() Uid_t -//sysnb Kill(pid int, sig int) (err error) +//sysnb Kill(pid int, sig Signal) (err error) //kill(pid Pid_t, sig int) int //sys Lchown(path string, uid int, gid int) (err error) @@ -296,9 +307,8 @@ func Gettimeofday(tv *Timeval) (err error) { //sysnb Setreuid(ruid int, euid int) (err error) //setreuid(ruid Uid_t, euid Uid_t) int -// FIXME: mksysinfo Rlimit -// //sysnb Setrlimit(resource int, rlim *Rlimit) (err error) -// //setrlimit(resource int, rlim *Rlimit) int +//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) +//setrlimit(resource int, rlim *Rlimit) int //sysnb Setsid() (pid int, err error) //setsid() Pid_t @@ -319,9 +329,8 @@ func Settimeofday(tv *Timeval) (err error) { //sys Sync() //sync() -// FIXME: mksysinfo Time_t -// //sysnb Time(t *Time_t) (tt Time_t, err error) -// //time(t *Time_t) Time_t +//sysnb Time(t *Time_t) (tt Time_t, err error) +//time(t *Time_t) Time_t //sysnb Times(tms *Tms) (ticks uintptr, err error) //times(tms *Tms) _clock_t @@ -332,9 +341,8 @@ func Settimeofday(tv *Timeval) (err error) { //sys Unlink(path string) (err error) //unlink(path *byte) int -// FIXME: mksysinfo Utimbuf -// //sys Utime(path string, buf *Utimbuf) (err error) -// //utime(path *byte, buf *Utimbuf) int +//sys Utime(path string, buf *Utimbuf) (err error) +//utime(path *byte, buf *Utimbuf) int //sys Write(fd int, p []byte) (n int, err error) //write(fd int, buf *byte, count Size_t) Ssize_t diff --git a/libgo/go/syscall/lsf_linux.go b/libgo/go/syscall/lsf_linux.go index 05d653b4aa0..5296cec9c6e 100644 --- a/libgo/go/syscall/lsf_linux.go +++ b/libgo/go/syscall/lsf_linux.go @@ -69,10 +69,10 @@ func AttachLsf(fd int, i []SockFilter) error { var p SockFprog p.Len = uint16(len(i)) p.Filter = (*SockFilter)(unsafe.Pointer(&i[0])) - return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, uintptr(unsafe.Pointer(&p)), unsafe.Sizeof(p)) + return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, (*byte)(unsafe.Pointer(&p)), Socklen_t(unsafe.Sizeof(p))) } func DetachLsf(fd int) error { var dummy int - return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, uintptr(unsafe.Pointer(&dummy)), unsafe.Sizeof(dummy)) + return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, (*byte)(unsafe.Pointer(&dummy)), Socklen_t(unsafe.Sizeof(dummy))) } diff --git a/libgo/go/syscall/signame.c b/libgo/go/syscall/signame.c new file mode 100644 index 00000000000..f2ff85a9a02 --- /dev/null +++ b/libgo/go/syscall/signame.c @@ -0,0 +1,40 @@ +/* signame.c -- get the name of a signal + + Copyright 2012 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. */ + +#include <string.h> + +#include "config.h" +#include "runtime.h" +#include "arch.h" +#include "malloc.h" + +String Signame (int sig) asm ("libgo_syscall.syscall.Signame"); + +String +Signame (int sig) +{ + const char* s = NULL; + char buf[100]; + size_t len; + unsigned char *data; + String ret; + +#if defined(HAVE_STRSIGNAL) + s = strsignal (sig); +#endif + + if (s == NULL) + { + snprintf(buf, sizeof buf, "signal %d", sig); + s = buf; + } + len = __builtin_strlen (s); + data = runtime_mallocgc (len, FlagNoPointers, 0, 0); + __builtin_memcpy (data, s, len); + ret.__data = data; + ret.__length = len; + return ret; +} diff --git a/libgo/go/syscall/socket.go b/libgo/go/syscall/socket.go index 7a2e95ca2a2..6d36e3985f3 100644 --- a/libgo/go/syscall/socket.go +++ b/libgo/go/syscall/socket.go @@ -217,6 +217,13 @@ func Socketpair(domain, typ, proto int) (fd [2]int, err error) { //sys getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error) //getsockopt(s int, level int, name int, val *byte, vallen *Socklen_t) int +func GetsockoptByte(fd, level, opt int) (value byte, err error) { + var n byte + vallen := Socklen_t(1) + err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen) + return n, err +} + func GetsockoptInt(fd, level, opt int) (value int, err error) { var n int32 vallen := Socklen_t(4) @@ -254,6 +261,11 @@ func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { //sys setsockopt(s int, level int, name int, val *byte, vallen Socklen_t) (err error) //setsockopt(s int, level int, optname int, val *byte, vallen Socklen_t) int +func SetsockoptByte(fd, level, opt int, value byte) (err error) { + var n = byte(value) + return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 1) +} + func SetsockoptInt(fd, level, opt int, value int) (err error) { var n = int32(value) return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 4) diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index 98e7d689f77..85182b764b0 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -163,3 +163,15 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e func Munmap(b []byte) (err error) { return mapper.Munmap(b) } + +// A Signal is a number describing a process signal. +// It implements the os.Signal interface. +type Signal int + +func (s Signal) Signal() {} + +func Signame(s Signal) string + +func (s Signal) String() string { + return Signame(s) +} diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go index 0bf567b7c4d..41290594ee2 100644 --- a/libgo/go/testing/benchmark.go +++ b/libgo/go/testing/benchmark.go @@ -16,7 +16,7 @@ var matchBenchmarks = flag.String("test.bench", "", "regular expression to selec var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds") // An internal type but exported because it is cross-package; part of the implementation -// of gotest. +// of the "go test" command. type InternalBenchmark struct { Name string F func(b *B) @@ -213,7 +213,7 @@ func (r BenchmarkResult) String() string { } // An internal function but exported because it is cross-package; part of the implementation -// of gotest. +// of the "go test" command. func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) { // If no flag was specified, don't run benchmarks. if len(*matchBenchmarks) == 0 { @@ -281,7 +281,7 @@ func (b *B) trimOutput() { } // Benchmark benchmarks a single function. Useful for creating -// custom benchmarks that do not use gotest. +// custom benchmarks that do not use the "go test" command. func Benchmark(f func(b *B)) BenchmarkResult { b := &B{ common: common{ diff --git a/libgo/go/testing/example.go b/libgo/go/testing/example.go index 7f8ff2d0541..671c798760b 100644 --- a/libgo/go/testing/example.go +++ b/libgo/go/testing/example.go @@ -19,7 +19,7 @@ type InternalExample struct { Output string } -func RunExamples(examples []InternalExample) (ok bool) { +func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) { ok = true var eg InternalExample @@ -27,6 +27,14 @@ func RunExamples(examples []InternalExample) (ok bool) { stdout, stderr := os.Stdout, os.Stderr for _, eg = range examples { + matched, err := matchString(*match, eg.Name) + if err != nil { + fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err) + os.Exit(1) + } + if !matched { + continue + } if *chatty { fmt.Printf("=== RUN: %s\n", eg.Name) } diff --git a/libgo/go/testing/iotest/reader.go b/libgo/go/testing/iotest/reader.go index ab8dc31a1f7..441b9102d94 100644 --- a/libgo/go/testing/iotest/reader.go +++ b/libgo/go/testing/iotest/reader.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package iotest implements Readers and Writers useful only for testing. +// Package iotest implements Readers and Writers useful mainly for testing. package iotest import ( diff --git a/libgo/go/testing/quick/quick.go b/libgo/go/testing/quick/quick.go index f94c541f2ba..24270982281 100644 --- a/libgo/go/testing/quick/quick.go +++ b/libgo/go/testing/quick/quick.go @@ -50,7 +50,7 @@ const complexSize = 50 // Value returns an arbitrary value of the given type. // If the type implements the Generator interface, that will be used. -// Note: in order to create arbitrary values for structs, all the members must be public. +// Note: To create arbitrary values for structs, all the fields must be exported. func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { if m, ok := reflect.Zero(t).Interface().(Generator); ok { return m.Generate(rand, complexSize), true @@ -155,9 +155,10 @@ type Config struct { // If non-nil, rand is a source of random numbers. Otherwise a default // pseudo-random source will be used. Rand *rand.Rand - // If non-nil, Values is a function which generates a slice of arbitrary - // Values that are congruent with the arguments to the function being - // tested. Otherwise, Values is used to generate the values. + // If non-nil, the Values function generates a slice of arbitrary + // reflect.Values that are congruent with the arguments to the function + // being tested. Otherwise, the top-level Values function is used + // to generate them. Values func([]reflect.Value, *rand.Rand) } diff --git a/libgo/go/testing/script/script.go b/libgo/go/testing/script/script.go deleted file mode 100644 index d8f8093af90..00000000000 --- a/libgo/go/testing/script/script.go +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package script aids in the testing of code that uses channels. -package script - -import ( - "fmt" - "math/rand" - "reflect" - "strings" -) - -// An Event is an element in a partially ordered set that either sends a value -// to a channel or expects a value from a channel. -type Event struct { - name string - occurred bool - predecessors []*Event - action action -} - -type action interface { - // getSend returns nil if the action is not a send action. - getSend() sendAction - // getRecv returns nil if the action is not a receive action. - getRecv() recvAction - // getChannel returns the channel that the action operates on. - getChannel() interface{} -} - -type recvAction interface { - recvMatch(interface{}) bool -} - -type sendAction interface { - send() -} - -// isReady returns true if all the predecessors of an Event have occurred. -func (e Event) isReady() bool { - for _, predecessor := range e.predecessors { - if !predecessor.occurred { - return false - } - } - - return true -} - -// A Recv action reads a value from a channel and uses reflect.DeepMatch to -// compare it with an expected value. -type Recv struct { - Channel interface{} - Expected interface{} -} - -func (r Recv) getRecv() recvAction { return r } - -func (Recv) getSend() sendAction { return nil } - -func (r Recv) getChannel() interface{} { return r.Channel } - -func (r Recv) recvMatch(chanEvent interface{}) bool { - c, ok := chanEvent.(channelRecv) - if !ok || c.channel != r.Channel { - return false - } - - return reflect.DeepEqual(c.value, r.Expected) -} - -// A RecvMatch action reads a value from a channel and calls a function to -// determine if the value matches. -type RecvMatch struct { - Channel interface{} - Match func(interface{}) bool -} - -func (r RecvMatch) getRecv() recvAction { return r } - -func (RecvMatch) getSend() sendAction { return nil } - -func (r RecvMatch) getChannel() interface{} { return r.Channel } - -func (r RecvMatch) recvMatch(chanEvent interface{}) bool { - c, ok := chanEvent.(channelRecv) - if !ok || c.channel != r.Channel { - return false - } - - return r.Match(c.value) -} - -// A Closed action matches if the given channel is closed. The closing is -// treated as an event, not a state, thus Closed will only match once for a -// given channel. -type Closed struct { - Channel interface{} -} - -func (r Closed) getRecv() recvAction { return r } - -func (Closed) getSend() sendAction { return nil } - -func (r Closed) getChannel() interface{} { return r.Channel } - -func (r Closed) recvMatch(chanEvent interface{}) bool { - c, ok := chanEvent.(channelClosed) - if !ok || c.channel != r.Channel { - return false - } - - return true -} - -// A Send action sends a value to a channel. The value must match the -// type of the channel exactly unless the channel if of type chan interface{}. -type Send struct { - Channel interface{} - Value interface{} -} - -func (Send) getRecv() recvAction { return nil } - -func (s Send) getSend() sendAction { return s } - -func (s Send) getChannel() interface{} { return s.Channel } - -type empty struct { - x interface{} -} - -func newEmptyInterface(e empty) reflect.Value { - return reflect.ValueOf(e).Field(0) -} - -func (s Send) send() { - // With reflect.ChanValue.Send, we must match the types exactly. So, if - // s.Channel is a chan interface{} we convert s.Value to an interface{} - // first. - c := reflect.ValueOf(s.Channel) - var v reflect.Value - if iface := c.Type().Elem(); iface.Kind() == reflect.Interface && iface.NumMethod() == 0 { - v = newEmptyInterface(empty{s.Value}) - } else { - v = reflect.ValueOf(s.Value) - } - c.Send(v) -} - -// A Close action closes the given channel. -type Close struct { - Channel interface{} -} - -func (Close) getRecv() recvAction { return nil } - -func (s Close) getSend() sendAction { return s } - -func (s Close) getChannel() interface{} { return s.Channel } - -func (s Close) send() { reflect.ValueOf(s.Channel).Close() } - -// A ReceivedUnexpected error results if no active Events match a value -// received from a channel. -type ReceivedUnexpected struct { - Value interface{} - ready []*Event -} - -func (r ReceivedUnexpected) Error() string { - names := make([]string, len(r.ready)) - for i, v := range r.ready { - names[i] = v.name - } - return fmt.Sprintf("received unexpected value on one of the channels: %#v. Runnable events: %s", r.Value, strings.Join(names, ", ")) -} - -// A SetupError results if there is a error with the configuration of a set of -// Events. -type SetupError string - -func (s SetupError) Error() string { return string(s) } - -func NewEvent(name string, predecessors []*Event, action action) *Event { - e := &Event{name, false, predecessors, action} - return e -} - -// Given a set of Events, Perform repeatedly iterates over the set and finds the -// subset of ready Events (that is, all of their predecessors have -// occurred). From that subset, it pseudo-randomly selects an Event to perform. -// If the Event is a send event, the send occurs and Perform recalculates the ready -// set. If the event is a receive event, Perform waits for a value from any of the -// channels that are contained in any of the events. That value is then matched -// against the ready events. The first event that matches is considered to -// have occurred and Perform recalculates the ready set. -// -// Perform continues this until all Events have occurred. -// -// Note that uncollected goroutines may still be reading from any of the -// channels read from after Perform returns. -// -// For example, consider the problem of testing a function that reads values on -// one channel and echos them to two output channels. To test this we would -// create three events: a send event and two receive events. Each of the -// receive events must list the send event as a predecessor but there is no -// ordering between the receive events. -// -// send := NewEvent("send", nil, Send{c, 1}) -// recv1 := NewEvent("recv 1", []*Event{send}, Recv{c, 1}) -// recv2 := NewEvent("recv 2", []*Event{send}, Recv{c, 1}) -// Perform(0, []*Event{send, recv1, recv2}) -// -// At first, only the send event would be in the ready set and thus Perform will -// send a value to the input channel. Now the two receive events are ready and -// Perform will match each of them against the values read from the output channels. -// -// It would be invalid to list one of the receive events as a predecessor of -// the other. At each receive step, all the receive channels are considered, -// thus Perform may see a value from a channel that is not in the current ready -// set and fail. -func Perform(seed int64, events []*Event) (err error) { - r := rand.New(rand.NewSource(seed)) - - channels, err := getChannels(events) - if err != nil { - return - } - multiplex := make(chan interface{}) - for _, channel := range channels { - go recvValues(multiplex, channel) - } - -Outer: - for { - ready, err := readyEvents(events) - if err != nil { - return err - } - - if len(ready) == 0 { - // All events occurred. - break - } - - event := ready[r.Intn(len(ready))] - if send := event.action.getSend(); send != nil { - send.send() - event.occurred = true - continue - } - - v := <-multiplex - for _, event := range ready { - if recv := event.action.getRecv(); recv != nil && recv.recvMatch(v) { - event.occurred = true - continue Outer - } - } - - return ReceivedUnexpected{v, ready} - } - - return nil -} - -// getChannels returns all the channels listed in any receive events. -func getChannels(events []*Event) ([]interface{}, error) { - channels := make([]interface{}, len(events)) - - j := 0 - for _, event := range events { - if recv := event.action.getRecv(); recv == nil { - continue - } - c := event.action.getChannel() - if reflect.ValueOf(c).Kind() != reflect.Chan { - return nil, SetupError("one of the channel values is not a channel") - } - - duplicate := false - for _, other := range channels[0:j] { - if c == other { - duplicate = true - break - } - } - - if !duplicate { - channels[j] = c - j++ - } - } - - return channels[0:j], nil -} - -// recvValues is a multiplexing helper function. It reads values from the given -// channel repeatedly, wrapping them up as either a channelRecv or -// channelClosed structure, and forwards them to the multiplex channel. -func recvValues(multiplex chan<- interface{}, channel interface{}) { - c := reflect.ValueOf(channel) - - for { - v, ok := c.Recv() - if !ok { - multiplex <- channelClosed{channel} - return - } - - multiplex <- channelRecv{channel, v.Interface()} - } -} - -type channelClosed struct { - channel interface{} -} - -type channelRecv struct { - channel interface{} - value interface{} -} - -// readyEvents returns the subset of events that are ready. -func readyEvents(events []*Event) ([]*Event, error) { - ready := make([]*Event, len(events)) - - j := 0 - eventsWaiting := false - for _, event := range events { - if event.occurred { - continue - } - - eventsWaiting = true - if event.isReady() { - ready[j] = event - j++ - } - } - - if j == 0 && eventsWaiting { - names := make([]string, len(events)) - for _, event := range events { - if event.occurred { - continue - } - names[j] = event.name - } - - return nil, SetupError("dependency cycle in events. These events are waiting to run but cannot: " + strings.Join(names, ", ")) - } - - return ready[0:j], nil -} diff --git a/libgo/go/testing/script/script_test.go b/libgo/go/testing/script/script_test.go deleted file mode 100644 index e9ab142c2b1..00000000000 --- a/libgo/go/testing/script/script_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package script - -import ( - "testing" -) - -func TestNoop(t *testing.T) { - err := Perform(0, nil) - if err != nil { - t.Errorf("Got error: %s", err) - } -} - -func TestSimple(t *testing.T) { - c := make(chan int) - defer close(c) - - a := NewEvent("send", nil, Send{c, 1}) - b := NewEvent("recv", []*Event{a}, Recv{c, 1}) - - err := Perform(0, []*Event{a, b}) - if err != nil { - t.Errorf("Got error: %s", err) - } -} - -func TestFail(t *testing.T) { - c := make(chan int) - defer close(c) - - a := NewEvent("send", nil, Send{c, 2}) - b := NewEvent("recv", []*Event{a}, Recv{c, 1}) - - err := Perform(0, []*Event{a, b}) - if err == nil { - t.Errorf("Failed to get expected error") - } else if _, ok := err.(ReceivedUnexpected); !ok { - t.Errorf("Error returned was of the wrong type: %s", err) - } -} - -func TestClose(t *testing.T) { - c := make(chan int) - - a := NewEvent("close", nil, Close{c}) - b := NewEvent("closed", []*Event{a}, Closed{c}) - - err := Perform(0, []*Event{a, b}) - if err != nil { - t.Errorf("Got error: %s", err) - } -} - -func matchOne(v interface{}) bool { - if i, ok := v.(int); ok && i == 1 { - return true - } - return false -} - -func TestRecvMatch(t *testing.T) { - c := make(chan int) - - a := NewEvent("send", nil, Send{c, 1}) - b := NewEvent("recv", []*Event{a}, RecvMatch{c, matchOne}) - - err := Perform(0, []*Event{a, b}) - if err != nil { - t.Errorf("Got error: %s", err) - } -} diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index 68ecebb36f4..7072262a91d 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -12,8 +12,8 @@ // // Functions of the form // func BenchmarkXxx(*testing.B) -// are considered benchmarks, and are executed by gotest when the -test.bench -// flag is provided. +// are considered benchmarks, and are executed by the "go test" command when +// the -test.bench flag is provided. // // A sample benchmark function looks like this: // func BenchmarkHello(b *testing.B) { @@ -38,16 +38,25 @@ // } // } // -// The package also runs and verifies example code. Example functions -// include an introductory comment that is compared with the standard output -// of the function when the tests are run, as in this example of an example: +// The package also runs and verifies example code. Example functions may +// include a concluding comment that begins with "Output:" and is compared with +// the standard output of the function when the tests are run, as in these +// examples of an example: // -// // hello // func ExampleHello() { // fmt.Println("hello") +// // Output: hello // } // -// Example functions without comments are compiled but not executed. +// func ExampleSalutations() { +// fmt.Println("hello, and") +// fmt.Println("goodbye") +// // Output: +// // hello, and +// // goodbye +// } +// +// Example functions without output comments are compiled but not executed. // // The naming convention to declare examples for a function F, a type T and // method M on type T are: @@ -64,9 +73,13 @@ // func ExampleT_suffix() { ... } // func ExampleT_M_suffix() { ... } // +// The entire test file is presented as the example when it contains a single +// example function, at least one other function, type, variable, or constant +// declaration, and no test or benchmark functions. package testing import ( + _ "debug/elf" "flag" "fmt" "os" @@ -81,13 +94,13 @@ var ( // The short flag requests that tests run more quickly, but its functionality // is provided by test writers themselves. The testing package is just its // home. The all.bash installation script sets it to make installation more - // efficient, but by default the flag is off so a plain "gotest" will do a + // efficient, but by default the flag is off so a plain "go test" will do a // full test of the package. short = flag.Bool("test.short", false, "run smaller test suite to save time") // Report as tests are run; default is silent for success. chatty = flag.Bool("test.v", false, "verbose: print additional output") - match = flag.String("test.run", "", "regular expression to select tests to run") + match = flag.String("test.run", "", "regular expression to select tests and examples to run") memProfile = flag.String("test.memprofile", "", "write a memory profile to the named file after execution") memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate") cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution") @@ -162,7 +175,7 @@ func (c *common) Fail() { c.failed = true } func (c *common) Failed() bool { return c.failed } // FailNow marks the function as having failed and stops its execution. -// Execution will continue at the next Test. +// Execution will continue at the next test or benchmark. func (c *common) FailNow() { c.Fail() @@ -225,19 +238,6 @@ func (c *common) Fatalf(format string, args ...interface{}) { c.FailNow() } -// TODO(dsymonds): Consider hooking into runtime·traceback instead. -func (c *common) stack() { - for i := 2; ; i++ { // Caller we care about is the user, 2 frames up - pc, file, line, ok := runtime.Caller(i) - f := runtime.FuncForPC(pc) - if !ok || f == nil { - break - } - c.Logf("%s:%d (0x%x)", file, line, pc) - c.Logf("\t%s", f.Name()) - } -} - // Parallel signals that this test is to be run in parallel with (and only with) // other parallel tests in this CPU group. func (t *T) Parallel() { @@ -246,7 +246,7 @@ func (t *T) Parallel() { } // An internal type but exported because it is cross-package; part of the implementation -// of gotest. +// of the "go test" command. type InternalTest struct { Name string F func(*T) @@ -260,14 +260,12 @@ func tRunner(t *T, test *InternalTest) { // a call to runtime.Goexit, record the duration and send // a signal saying that the test is done. defer func() { - // Consider any uncaught panic a failure. + t.duration = time.Now().Sub(t.start) + // If the test panicked, print any test output before dying. if err := recover(); err != nil { - t.failed = true - t.Log(err) - t.stack() + t.report() + panic(err) } - - t.duration = time.Now().Sub(t.start) t.signal <- t }() @@ -275,7 +273,7 @@ func tRunner(t *T, test *InternalTest) { } // An internal function but exported because it is cross-package; part of the implementation -// of gotest. +// of the "go test" command. func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) { flag.Parse() parseCpuList() @@ -283,7 +281,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, before() startAlarm() testOk := RunTests(matchString, tests) - exampleOk := RunExamples(examples) + exampleOk := RunExamples(matchString, examples) if !testOk || !exampleOk { fmt.Println("FAIL") os.Exit(1) diff --git a/libgo/go/text/scanner/scanner.go b/libgo/go/text/scanner/scanner.go index f46f63d0ee6..565650edf9c 100644 --- a/libgo/go/text/scanner/scanner.go +++ b/libgo/go/text/scanner/scanner.go @@ -5,8 +5,7 @@ // Package scanner provides a scanner and tokenizer for UTF-8-encoded text. // It takes an io.Reader providing the source, which then can be tokenized // through repeated calls to the Scan function. For compatibility with -// existing tools, the NUL character is not allowed (implementation -// restriction). +// existing tools, the NUL character is not allowed. // // By default, a Scanner skips white space and Go comments and recognizes all // literals as defined by the Go language specification. It may be @@ -104,7 +103,7 @@ var tokenString = map[rune]string{ Comment: "Comment", } -// TokenString returns a (visible) string for a token or Unicode character. +// TokenString returns a printable string for a token or Unicode character. func TokenString(tok rune) string { if s, found := tokenString[tok]; found { return s @@ -287,7 +286,7 @@ func (s *Scanner) next() rune { // special situations switch ch { case 0: - // implementation restriction for compatibility with other tools + // for compatibility with other tools s.error("illegal character NUL") case '\n': s.line++ diff --git a/libgo/go/text/tabwriter/example_test.go b/libgo/go/text/tabwriter/example_test.go new file mode 100644 index 00000000000..20443cb1ffb --- /dev/null +++ b/libgo/go/text/tabwriter/example_test.go @@ -0,0 +1,38 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tabwriter_test + +import ( + "fmt" + "os" + "text/tabwriter" +) + +func ExampleWriter_Init() { + w := new(tabwriter.Writer) + + // Format in tab-separated columns with a tab stop of 8. + w.Init(os.Stdout, 0, 8, 0, '\t', 0) + fmt.Fprintln(w, "a\tb\tc\td\t.") + fmt.Fprintln(w, "123\t12345\t1234567\t123456789\t.") + fmt.Fprintln(w) + w.Flush() + + // Format right-aligned in space-separated columns of minimal width 5 + // and at least one blank of padding (so wider column entries do not + // touch each other). + w.Init(os.Stdout, 5, 0, 1, ' ', tabwriter.AlignRight) + fmt.Fprintln(w, "a\tb\tc\td\t.") + fmt.Fprintln(w, "123\t12345\t1234567\t123456789\t.") + fmt.Fprintln(w) + w.Flush() + + // output: + // a b c d . + // 123 12345 1234567 123456789 . + // + // a b c d. + // 123 12345 1234567 123456789. +} diff --git a/libgo/go/text/tabwriter/tabwriter.go b/libgo/go/text/tabwriter/tabwriter.go index ea7c4008111..ce84600d604 100644 --- a/libgo/go/text/tabwriter/tabwriter.go +++ b/libgo/go/text/tabwriter/tabwriter.go @@ -169,12 +169,6 @@ const ( // to the tab width in the viewer displaying the result) // flags formatting control // -// To format in tab-separated columns with a tab stop of 8: -// b.Init(w, 8, 1, 8, '\t', 0); -// -// To format in space-separated columns with at least 4 spaces between columns: -// b.Init(w, 0, 4, 8, ' ', 0); -// func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer { if minwidth < 0 || tabwidth < 0 || padding < 0 { panic("negative minwidth, tabwidth, or padding") diff --git a/libgo/go/text/tabwriter/tabwriter_test.go b/libgo/go/text/tabwriter/tabwriter_test.go index 1ffb330d432..ace53564737 100644 --- a/libgo/go/text/tabwriter/tabwriter_test.go +++ b/libgo/go/text/tabwriter/tabwriter_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package tabwriter +package tabwriter_test import ( "io" "testing" + . "text/tabwriter" ) type buffer struct { diff --git a/libgo/go/text/template/doc.go b/libgo/go/text/template/doc.go index 3be1ec44e69..10e0f7fc373 100644 --- a/libgo/go/text/template/doc.go +++ b/libgo/go/text/template/doc.go @@ -3,8 +3,10 @@ // license that can be found in the LICENSE file. /* -Package template implements data-driven templates for generating textual output -such as HTML. +Package template implements data-driven templates for generating textual output. + +To generate HTML output, see package html/template, which has the same interface +as this package but automatically secures HTML output against certain attacks. Templates are executed by applying them to a data structure. Annotations in the template refer to elements of the data structure (typically a field of a struct @@ -20,6 +22,20 @@ Actions may not span newlines, although comments can. Once constructed, a template may be executed safely in parallel. +Here is a trivial example that prints "17 items are made of wool". + + type Inventory struct { + Material string + Count uint + } + sweaters := Inventory{"wool", 17} + tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}") + if err != nil { panic(err) } + err = tmpl.Execute(os.Stdout, sweaters) + if err != nil { panic(err) } + +More intricate examples appear below. + Actions Here is the list of actions. "Arguments" and "pipelines" are evaluations of @@ -134,6 +150,10 @@ An argument is a simple value, denoted by one of the following. Arguments may evaluate to any type; if they are pointers the implementation automatically indirects to the base type when required. +If an evaluation yields a function value, such as a function-valued +field of a struct, the function is not invoked automatically, but it +can be used as a truth value for an if action and the like. To invoke +it, use the call function, defined below. A pipeline is a possibly chained sequence of "commands". A command is a simple value (argument) or a function or method call, possibly with multiple arguments: @@ -233,6 +253,17 @@ Predefined global functions are named as follows. first empty argument or the last argument, that is, "and x y" behaves as "if x then y else x". All the arguments are evaluated. + call + Returns the result of calling the first argument, which + must be a function, with the remaining arguments as parameters. + Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where + Y is a func-valued field, map entry, or the like. + The first argument must be the result of an evaluation + that yields a value of function type (as distinct from + a predefined function such as print). The function must + return either one or two result values, the second of which + is of type error. If the arguments don't match the function + or the returned error value is non-nil, execution stops. html Returns the escaped HTML equivalent of the textual representation of its arguments. @@ -301,7 +332,7 @@ produce the text By construction, a template may reside in only one association. If it's necessary to have a template addressable from multiple associations, the template definition must be parsed multiple times to create distinct *Template -values. +values, or must be copied with the Clone or AddParseTree method. Parse may be called multiple times to assemble the various associated templates; see the ParseFiles and ParseGlob functions and methods for simple ways to parse diff --git a/libgo/go/text/template/exec.go b/libgo/go/text/template/exec.go index 973189a8a62..ad0118e4e68 100644 --- a/libgo/go/text/template/exec.go +++ b/libgo/go/text/template/exec.go @@ -419,10 +419,11 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node tField, ok := receiver.Type().FieldByName(fieldName) if ok { field := receiver.FieldByIndex(tField.Index) - if hasArgs { - s.errorf("%s is not a method but has arguments", fieldName) - } if tField.PkgPath == "" { // field is exported + // If it's a function, we must call it. + if hasArgs { + s.errorf("%s has arguments but cannot be invoked as function", fieldName) + } return field } } diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go index 2070cefde73..70ab39cad20 100644 --- a/libgo/go/text/template/exec_test.go +++ b/libgo/go/text/template/exec_test.go @@ -9,7 +9,6 @@ import ( "errors" "flag" "fmt" - "os" "reflect" "strings" "testing" @@ -60,6 +59,10 @@ type T struct { PI *int PSI *[]int NIL *int + // Function (not method) + BinaryFunc func(string, string) string + VariadicFunc func(...string) string + VariadicFuncInt func(int, ...string) string // Template to test evaluation of templates. Tmpl *Template } @@ -119,6 +122,9 @@ var tVal = &T{ Err: errors.New("erroozle"), PI: newInt(23), PSI: newIntSlice(21, 22, 23), + BinaryFunc: func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) }, + VariadicFunc: func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") }, + VariadicFuncInt: func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") }, Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X } @@ -168,10 +174,12 @@ func (t *T) MAdd(a int, b []int) []int { return v } -// EPERM returns a value and an error according to its argument. -func (t *T) EPERM(error bool) (bool, error) { +var myError = errors.New("my error") + +// MyError returns a value and an error according to its argument. +func (t *T) MyError(error bool) (bool, error) { if error { - return true, os.EPERM + return true, myError } return false, nil } @@ -296,8 +304,26 @@ var execTests = []execTest{ "{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}", "true", tVal, true}, + // Function call builtin. + {".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true}, + {".VariadicFunc0", "{{call .VariadicFunc}}", "<>", tVal, true}, + {".VariadicFunc2", "{{call .VariadicFunc `he` `llo`}}", "<he+llo>", tVal, true}, + {".VariadicFuncInt", "{{call .VariadicFuncInt 33 `he` `llo`}}", "33=<he+llo>", tVal, true}, + {"if .BinaryFunc call", "{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}", "[1=2]", tVal, true}, + {"if not .BinaryFunc call", "{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}", "No", tVal, true}, + + // Erroneous function calls (check args). + {".BinaryFuncTooFew", "{{call .BinaryFunc `1`}}", "", tVal, false}, + {".BinaryFuncTooMany", "{{call .BinaryFunc `1` `2` `3`}}", "", tVal, false}, + {".BinaryFuncBad0", "{{call .BinaryFunc 1 3}}", "", tVal, false}, + {".BinaryFuncBad1", "{{call .BinaryFunc `1` 3}}", "", tVal, false}, + {".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false}, + {".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false}, + {".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false}, + // Pipelines. {"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true}, + {"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true}, // If. {"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true}, @@ -417,8 +443,8 @@ var execTests = []execTest{ {"or as if false", `{{or .SIEmpty "slice is empty"}}`, "slice is empty", tVal, true}, // Error handling. - {"error method, error", "{{.EPERM true}}", "", tVal, false}, - {"error method, no error", "{{.EPERM false}}", "false", tVal, true}, + {"error method, error", "{{.MyError true}}", "", tVal, false}, + {"error method, no error", "{{.MyError false}}", "false", tVal, true}, // Fixed bugs. // Must separate dot and receiver; otherwise args are evaluated with dot set to variable. @@ -565,18 +591,18 @@ func TestDelims(t *testing.T) { func TestExecuteError(t *testing.T) { b := new(bytes.Buffer) tmpl := New("error") - _, err := tmpl.Parse("{{.EPERM true}}") + _, err := tmpl.Parse("{{.MyError true}}") if err != nil { t.Fatalf("parse error: %s", err) } err = tmpl.Execute(b, tVal) if err == nil { t.Errorf("expected error; got none") - } else if !strings.Contains(err.Error(), os.EPERM.Error()) { + } else if !strings.Contains(err.Error(), myError.Error()) { if *debug { fmt.Printf("test execute error: %s\n", err) } - t.Errorf("expected os.EPERM; got %s", err) + t.Errorf("expected myError; got %s", err) } } diff --git a/libgo/go/text/template/funcs.go b/libgo/go/text/template/funcs.go index d6e4bf1a216..525179cb499 100644 --- a/libgo/go/text/template/funcs.go +++ b/libgo/go/text/template/funcs.go @@ -24,6 +24,7 @@ type FuncMap map[string]interface{} var builtins = FuncMap{ "and": and, + "call": call, "html": HTMLEscaper, "index": index, "js": JSEscaper, @@ -151,6 +152,53 @@ func length(item interface{}) (int, error) { return 0, fmt.Errorf("len of type %s", v.Type()) } +// Function invocation + +// call returns the result of evaluating the the first argument as a function. +// The function must return 1 result, or 2 results, the second of which is an error. +func call(fn interface{}, args ...interface{}) (interface{}, error) { + v := reflect.ValueOf(fn) + typ := v.Type() + if typ.Kind() != reflect.Func { + return nil, fmt.Errorf("non-function of type %s", typ) + } + if !goodFunc(typ) { + return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut()) + } + numIn := typ.NumIn() + var dddType reflect.Type + if typ.IsVariadic() { + if len(args) < numIn-1 { + return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1) + } + dddType = typ.In(numIn - 1).Elem() + } else { + if len(args) != numIn { + return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn) + } + } + argv := make([]reflect.Value, len(args)) + for i, arg := range args { + value := reflect.ValueOf(arg) + // Compute the expected type. Clumsy because of variadics. + var argType reflect.Type + if !typ.IsVariadic() || i < numIn-1 { + argType = typ.In(i) + } else { + argType = dddType + } + if !value.Type().AssignableTo(argType) { + return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType) + } + argv[i] = reflect.ValueOf(arg) + } + result := v.Call(argv) + if len(result) == 2 { + return result[0].Interface(), result[1].Interface().(error) + } + return result[0].Interface(), nil +} + // Boolean logic. func truth(a interface{}) bool { diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go index 274f5ef1477..22dedc4f839 100644 --- a/libgo/go/text/template/multi_test.go +++ b/libgo/go/text/template/multi_test.go @@ -193,7 +193,7 @@ func TestClone(t *testing.T) { if err != nil { t.Fatal(err) } - clone := root.Clone() + clone := Must(root.Clone()) // Add variants to both. _, err = root.Parse(cloneText3) if err != nil { @@ -265,6 +265,12 @@ func TestRedefinition(t *testing.T) { if tmpl, err = New("tmpl1").Parse(`{{define "test"}}foo{{end}}`); err != nil { t.Fatalf("parse 1: %v", err) } + if _, err = tmpl.Parse(`{{define "test"}}bar{{end}}`); err == nil { + t.Fatal("expected error") + } + if !strings.Contains(err.Error(), "redefinition") { + t.Fatalf("expected redefinition error; got %v", err) + } if _, err = tmpl.New("tmpl2").Parse(`{{define "test"}}bar{{end}}`); err == nil { t.Fatal("expected error") } diff --git a/libgo/go/text/template/parse/lex.go b/libgo/go/text/template/parse/lex.go index 97c19a160b0..54e75ee0ca2 100644 --- a/libgo/go/text/template/parse/lex.go +++ b/libgo/go/text/template/parse/lex.go @@ -187,7 +187,7 @@ func (l *lexer) lineNumber() int { } // error returns an error token and terminates the scan by passing -// back a nil pointer that will be the next state, terminating l.run. +// back a nil pointer that will be the next state, terminating l.nextItem. func (l *lexer) errorf(format string, args ...interface{}) stateFn { l.items <- item{itemError, fmt.Sprintf(format, args...)} return nil diff --git a/libgo/go/text/template/parse/node.go b/libgo/go/text/template/parse/node.go index 0d030b8b4be..db645624c56 100644 --- a/libgo/go/text/template/parse/node.go +++ b/libgo/go/text/template/parse/node.go @@ -17,6 +17,10 @@ import ( type Node interface { Type() NodeType String() string + // Copy does a deep copy of the Node and all its components. + // To avoid type assertions, some XxxNodes also have specialized + // CopyXxx methods that return *XxxNode. + Copy() Node } // NodeType identifies the type of a parse tree node. @@ -73,6 +77,21 @@ func (l *ListNode) String() string { return b.String() } +func (l *ListNode) CopyList() *ListNode { + if l == nil { + return l + } + n := newList() + for _, elem := range l.Nodes { + n.append(elem.Copy()) + } + return n +} + +func (l *ListNode) Copy() Node { + return l.CopyList() +} + // TextNode holds plain text. type TextNode struct { NodeType @@ -87,6 +106,10 @@ func (t *TextNode) String() string { return fmt.Sprintf("%q", t.Text) } +func (t *TextNode) Copy() Node { + return &TextNode{NodeType: NodeText, Text: append([]byte{}, t.Text...)} +} + // PipeNode holds a pipeline with optional declaration type PipeNode struct { NodeType @@ -123,6 +146,25 @@ func (p *PipeNode) String() string { return s } +func (p *PipeNode) CopyPipe() *PipeNode { + if p == nil { + return p + } + var decl []*VariableNode + for _, d := range p.Decl { + decl = append(decl, d.Copy().(*VariableNode)) + } + n := newPipeline(p.Line, decl) + for _, c := range p.Cmds { + n.append(c.Copy().(*CommandNode)) + } + return n +} + +func (p *PipeNode) Copy() Node { + return p.CopyPipe() +} + // ActionNode holds an action (something bounded by delimiters). // Control actions have their own nodes; ActionNode represents simple // ones such as field evaluations. @@ -141,6 +183,11 @@ func (a *ActionNode) String() string { } +func (a *ActionNode) Copy() Node { + return newAction(a.Line, a.Pipe.CopyPipe()) + +} + // CommandNode holds a command (a pipeline inside an evaluating action). type CommandNode struct { NodeType @@ -166,6 +213,17 @@ func (c *CommandNode) String() string { return s } +func (c *CommandNode) Copy() Node { + if c == nil { + return c + } + n := newCommand() + for _, c := range c.Args { + n.append(c.Copy()) + } + return n +} + // IdentifierNode holds an identifier. type IdentifierNode struct { NodeType @@ -181,6 +239,10 @@ func (i *IdentifierNode) String() string { return i.Ident } +func (i *IdentifierNode) Copy() Node { + return NewIdentifier(i.Ident) +} + // VariableNode holds a list of variable names. The dollar sign is // part of the name. type VariableNode struct { @@ -203,6 +265,10 @@ func (v *VariableNode) String() string { return s } +func (v *VariableNode) Copy() Node { + return &VariableNode{NodeType: NodeVariable, Ident: append([]string{}, v.Ident...)} +} + // DotNode holds the special identifier '.'. It is represented by a nil pointer. type DotNode bool @@ -218,6 +284,10 @@ func (d *DotNode) String() string { return "." } +func (d *DotNode) Copy() Node { + return newDot() +} + // FieldNode holds a field (identifier starting with '.'). // The names may be chained ('.x.y'). // The period is dropped from each ident. @@ -238,6 +308,10 @@ func (f *FieldNode) String() string { return s } +func (f *FieldNode) Copy() Node { + return &FieldNode{NodeType: NodeField, Ident: append([]string{}, f.Ident...)} +} + // BoolNode holds a boolean constant. type BoolNode struct { NodeType @@ -255,6 +329,10 @@ func (b *BoolNode) String() string { return "false" } +func (b *BoolNode) Copy() Node { + return newBool(b.True) +} + // NumberNode holds a number: signed or unsigned integer, float, or complex. // The value is parsed and stored under all the types that can represent the value. // This simulates in a small amount of code the behavior of Go's ideal constants. @@ -373,6 +451,12 @@ func (n *NumberNode) String() string { return n.Text } +func (n *NumberNode) Copy() Node { + nn := new(NumberNode) + *nn = *n // Easy, fast, correct. + return nn +} + // StringNode holds a string constant. The value has been "unquoted". type StringNode struct { NodeType @@ -388,6 +472,10 @@ func (s *StringNode) String() string { return s.Quoted } +func (s *StringNode) Copy() Node { + return newString(s.Quoted, s.Text) +} + // endNode represents an {{end}} action. It is represented by a nil pointer. // It does not appear in the final parse tree. type endNode bool @@ -404,6 +492,10 @@ func (e *endNode) String() string { return "{{end}}" } +func (e *endNode) Copy() Node { + return newEnd() +} + // elseNode represents an {{else}} action. Does not appear in the final tree. type elseNode struct { NodeType @@ -422,6 +514,10 @@ func (e *elseNode) String() string { return "{{else}}" } +func (e *elseNode) Copy() Node { + return newElse(e.Line) +} + // BranchNode is the common representation of if, range, and with. type BranchNode struct { NodeType @@ -458,6 +554,10 @@ func newIf(line int, pipe *PipeNode, list, elseList *ListNode) *IfNode { return &IfNode{BranchNode{NodeType: NodeIf, Line: line, Pipe: pipe, List: list, ElseList: elseList}} } +func (i *IfNode) Copy() Node { + return newIf(i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList()) +} + // RangeNode represents a {{range}} action and its commands. type RangeNode struct { BranchNode @@ -467,6 +567,10 @@ func newRange(line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode { return &RangeNode{BranchNode{NodeType: NodeRange, Line: line, Pipe: pipe, List: list, ElseList: elseList}} } +func (r *RangeNode) Copy() Node { + return newRange(r.Line, r.Pipe.CopyPipe(), r.List.CopyList(), r.ElseList.CopyList()) +} + // WithNode represents a {{with}} action and its commands. type WithNode struct { BranchNode @@ -476,6 +580,10 @@ func newWith(line int, pipe *PipeNode, list, elseList *ListNode) *WithNode { return &WithNode{BranchNode{NodeType: NodeWith, Line: line, Pipe: pipe, List: list, ElseList: elseList}} } +func (w *WithNode) Copy() Node { + return newWith(w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList()) +} + // TemplateNode represents a {{template}} action. type TemplateNode struct { NodeType @@ -494,3 +602,7 @@ func (t *TemplateNode) String() string { } return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe) } + +func (t *TemplateNode) Copy() Node { + return newTemplate(t.Line, t.Name, t.Pipe.CopyPipe()) +} diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go index 4da756657d5..d67b3888085 100644 --- a/libgo/go/text/template/parse/parse.go +++ b/libgo/go/text/template/parse/parse.go @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package parse builds parse trees for templates. The grammar is defined -// in the documents for the template package. +// Package parse builds parse trees for templates as defined by text/template +// and html/template. Clients should use those packages to construct templates +// rather than this one, which provides shared internal data structures not +// intended for general use. package parse import ( @@ -191,6 +193,8 @@ func (t *Tree) add(treeSet map[string]*Tree) { // IsEmptyTree reports whether this tree (node) is empty of everything but space. func IsEmptyTree(n Node) bool { switch n := n.(type) { + case nil: + return true case *ActionNode: case *IfNode: case *ListNode: diff --git a/libgo/go/text/template/parse/parse_test.go b/libgo/go/text/template/parse/parse_test.go index 13c5548abbf..18c0a8b835e 100644 --- a/libgo/go/text/template/parse/parse_test.go +++ b/libgo/go/text/template/parse/parse_test.go @@ -232,7 +232,7 @@ var builtins = map[string]interface{}{ "printf": fmt.Sprintf, } -func TestParse(t *testing.T) { +func testParse(doCopy bool, t *testing.T) { for _, test := range parseTests { tmpl, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree), builtins) switch { @@ -249,13 +249,27 @@ func TestParse(t *testing.T) { } continue } - result := tmpl.Root.String() + var result string + if doCopy { + result = tmpl.Root.Copy().String() + } else { + result = tmpl.Root.String() + } if result != test.result { t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result) } } } +func TestParse(t *testing.T) { + testParse(false, t) +} + +// Same as TestParse, but we copy the node first +func TestParseCopy(t *testing.T) { + testParse(true, t) +} + type isEmptyTest struct { name string input string @@ -273,6 +287,9 @@ var isEmptyTests = []isEmptyTest{ } func TestIsEmpty(t *testing.T) { + if !IsEmptyTree(nil) { + t.Errorf("nil tree is not empty") + } for _, test := range isEmptyTests { tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil) if err != nil { diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go index 87e39d3af74..82fc9e5e39d 100644 --- a/libgo/go/text/template/template.go +++ b/libgo/go/text/template/template.go @@ -69,9 +69,9 @@ func (t *Template) init() { // templates. The actual representation is not copied, but the name space of // associated templates is, so further calls to Parse in the copy will add // templates to the copy but not to the original. Clone can be used to prepare -// common templates and use them with variant definitions for other templates by -// adding the variants after the clone is made. -func (t *Template) Clone() *Template { +// common templates and use them with variant definitions for other templates +// by adding the variants after the clone is made. +func (t *Template) Clone() (*Template, error) { nt := t.copy(nil) nt.init() nt.tmpl[t.name] = nt @@ -89,7 +89,7 @@ func (t *Template) Clone() *Template { for k, v := range t.execFuncs { nt.execFuncs[k] = v } - return nt + return nt, nil } // copy returns a shallow copy of t, with common set to the argument. @@ -178,10 +178,11 @@ func (t *Template) Parse(text string) (*Template, error) { tmpl = t.New(name) } // Even if t == tmpl, we need to install it in the common.tmpl map. - if err := t.associate(tmpl); err != nil { + if replace, err := t.associate(tmpl, tree); err != nil { return nil, err + } else if replace { + tmpl.Tree = tree } - tmpl.Tree = tree tmpl.leftDelim = t.leftDelim tmpl.rightDelim = t.rightDelim } @@ -191,22 +192,23 @@ func (t *Template) Parse(text string) (*Template, error) { // associate installs the new template into the group of templates associated // with t. It is an error to reuse a name except to overwrite an empty // template. The two are already known to share the common structure. -func (t *Template) associate(new *Template) error { +// The boolean return value reports wither to store this tree as t.Tree. +func (t *Template) associate(new *Template, tree *parse.Tree) (bool, error) { if new.common != t.common { panic("internal error: associate not common") } name := new.name if old := t.tmpl[name]; old != nil { oldIsEmpty := parse.IsEmptyTree(old.Root) - newIsEmpty := new.Tree != nil && parse.IsEmptyTree(new.Root) - if !oldIsEmpty && !newIsEmpty { - return fmt.Errorf("template: redefinition of template %q", name) - } + newIsEmpty := parse.IsEmptyTree(tree.Root) if newIsEmpty { // Whether old is empty or not, new is empty; no reason to replace old. - return nil + return false, nil + } + if !oldIsEmpty { + return false, fmt.Errorf("template: redefinition of template %q", name) } } t.tmpl[name] = new - return nil + return true, nil } diff --git a/libgo/go/time/example_test.go b/libgo/go/time/example_test.go index 153b1a3b660..944cc789c31 100644 --- a/libgo/go/time/example_test.go +++ b/libgo/go/time/example_test.go @@ -51,8 +51,8 @@ func ExampleMonth() { } } -// Go launched at Tue Nov 10 15:00:00 -0800 PST 2009 func ExampleDate() { t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) fmt.Printf("Go launched at %s\n", t.Local()) + // Output: Go launched at 2009-11-10 15:00:00 -0800 PST } diff --git a/libgo/go/time/format.go b/libgo/go/time/format.go index 76bf6ff4194..ad52bab216f 100644 --- a/libgo/go/time/format.go +++ b/libgo/go/time/format.go @@ -6,28 +6,25 @@ package time import "errors" -const ( - numeric = iota - alphabetic - separator - plus - minus -) - // These are predefined layouts for use in Time.Format. // The standard time used in the layouts is: -// Mon Jan 2 15:04:05 MST 2006 (MST is GMT-0700) -// which is Unix time 1136243045. -// (Think of it as 01/02 03:04:05PM '06 -0700.) -// To define your own format, write down what the standard -// time would look like formatted your way. +// Mon Jan 2 15:04:05 MST 2006 +// which is Unix time 1136243045. Since MST is GMT-0700, +// the standard time can be thought of as +// 01/02 03:04:05PM '06 -0700 +// To define your own format, write down what the standard time would look +// like formatted your way; see the values of constants like ANSIC, +// StampMicro or Kitchen for examples. // // Within the format string, an underscore _ represents a space that may be // replaced by a digit if the following number (a day) has two digits; for // compatibility with fixed-width Unix time formats. // // A decimal point followed by one or more zeros represents a fractional -// second. When parsing (only), the input may contain a fractional second +// second, printed to the given number of decimal places. A decimal point +// followed by one or more nines represents a fractional second, printed to +// the given number of decimal places, with trailing zeros removed. +// When parsing (only), the input may contain a fractional second // field immediately after the seconds field, even if the layout does not // signify its presence. In that case a decimal point followed by a maximal // series of digits is parsed as a fractional second. @@ -41,16 +38,17 @@ const ( // Z0700 Z or ±hhmm // Z07:00 Z or ±hh:mm const ( - ANSIC = "Mon Jan _2 15:04:05 2006" - UnixDate = "Mon Jan _2 15:04:05 MST 2006" - RubyDate = "Mon Jan 02 15:04:05 -0700 2006" - RFC822 = "02 Jan 06 1504 MST" - RFC822Z = "02 Jan 06 1504 -0700" // RFC822 with numeric zone - RFC850 = "Monday, 02-Jan-06 15:04:05 MST" - RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" - RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone - RFC3339 = "2006-01-02T15:04:05Z07:00" - Kitchen = "3:04PM" + ANSIC = "Mon Jan _2 15:04:05 2006" + UnixDate = "Mon Jan _2 15:04:05 MST 2006" + RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + RFC822 = "02 Jan 06 1504 MST" + RFC822Z = "02 Jan 06 1504 -0700" // RFC822 with numeric zone + RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone + RFC3339 = "2006-01-02T15:04:05Z07:00" + RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + Kitchen = "3:04PM" // Handy time stamps. Stamp = "Jan _2 15:04:05" StampMilli = "Jan _2 15:04:05.000" @@ -165,15 +163,17 @@ func nextStdChunk(layout string) (prefix, std, suffix string) { if len(layout) >= i+6 && layout[i:i+6] == stdISO8601ColonTZ { return layout[0:i], layout[i : i+6], layout[i+6:] } - case '.': // .000 - multiple digits of zeros (only) for fractional seconds. - numZeros := 0 - var j int - for j = i + 1; j < len(layout) && layout[j] == '0'; j++ { - numZeros++ - } - // String of digits must end here - only fractional second is all zeros. - if numZeros > 0 && !isDigit(layout, j) { - return layout[0:i], layout[i : i+1+numZeros], layout[i+1+numZeros:] + case '.': // .000 or .999 - repeated digits for fractional seconds. + if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') { + ch := layout[i+1] + j := i + 1 + for j < len(layout) && layout[j] == ch { + j++ + } + // String of digits must end here - only fractional second is all digits. + if !isDigit(layout, j) { + return layout[0:i], layout[i:j], layout[j:] + } } } } @@ -313,7 +313,7 @@ func pad(i int, padding string) string { func zeroPad(i int) string { return pad(i, "0") } // formatNano formats a fractional second, as nanoseconds. -func formatNano(nanosec, n int) string { +func formatNano(nanosec, n int, trim bool) string { // User might give us bad data. Make sure it's positive and in range. // They'll get nonsense output but it will have the right format. s := itoa(int(uint(nanosec) % 1e9)) @@ -324,13 +324,21 @@ func formatNano(nanosec, n int) string { if n > 9 { n = 9 } + if trim { + for n > 0 && s[n-1] == '0' { + n-- + } + if n == 0 { + return "" + } + } return "." + s[:n] } // String returns the time formatted using the format string -// "Mon Jan _2 15:04:05 -0700 MST 2006" +// "2006-01-02 15:04:05.999999999 -0700 MST" func (t Time) String() string { - return t.Format("Mon Jan _2 15:04:05 -0700 MST 2006") + return t.Format("2006-01-02 15:04:05.999999999 -0700 MST") } type buffer []byte @@ -345,10 +353,12 @@ func (b *buffer) String() string { // Format returns a textual representation of the time value formatted // according to layout. The layout defines the format by showing the -// representation of a standard time, which is then used to describe -// the time to be formatted. Predefined layouts ANSIC, UnixDate, -// RFC3339 and others describe standard representations. For more -// information about the formats, see the documentation for ANSIC. +// representation of the standard time, +// Mon Jan 2 15:04:05 -0700 MST 2006 +// which is then used to describe the time to be formatted. Predefined +// layouts ANSIC, UnixDate, RFC3339 and others describe standard +// representations. For more information about the formats and the +// definition of the standard time, see the documentation for ANSIC. func (t Time) Format(layout string) string { var ( year int = -1 @@ -388,7 +398,24 @@ func (t Time) Format(layout string) string { case stdYear: p = zeroPad(year % 100) case stdLongYear: + // Pad year to at least 4 digits. p = itoa(year) + switch { + case year <= -1000: + // ok + case year <= -100: + p = p[:1] + "0" + p[1:] + case year <= -10: + p = p[:1] + "00" + p[1:] + case year < 0: + p = p[:1] + "000" + p[1:] + case year < 10: + p = "000" + p + case year < 100: + p = "00" + p + case year < 1000: + p = "0" + p + } case stdMonth: p = month.String()[:3] case stdLongMonth: @@ -481,8 +508,8 @@ func (t Time) Format(layout string) string { p += zeroPad(zone % 60) } default: - if len(std) >= 2 && std[0:2] == ".0" { - p = formatNano(t.Nanosecond(), len(std)-1) + if len(std) >= 2 && (std[0:2] == ".0" || std[0:2] == ".9") { + p = formatNano(t.Nanosecond(), len(std)-1, std[1] == '9') } } b.WriteString(p) @@ -574,13 +601,15 @@ func skip(value, prefix string) (string, error) { } // Parse parses a formatted string and returns the time value it represents. -// The layout defines the format by showing the representation of a standard -// time, which is then used to describe the string to be parsed. Predefined -// layouts ANSIC, UnixDate, RFC3339 and others describe standard -// representations.For more information about the formats, see the -// documentation for ANSIC. +// The layout defines the format by showing the representation of the +// standard time, +// Mon Jan 2 15:04:05 -0700 MST 2006 +// which is then used to describe the string to be parsed. Predefined layouts +// ANSIC, UnixDate, RFC3339 and others describe standard representations. For +// more information about the formats and the definition of the standard +// time, see the documentation for ANSIC. // -// Elements omitted from the value are assumed to be zero, or when +// Elements omitted from the value are assumed to be zero or, when // zero is impossible, one, so parsing "3:04pm" returns the time // corresponding to Jan 1, year 0, 15:04:00 UTC. // Years must be in the range 0000..9999. The day of the week is checked diff --git a/libgo/go/time/sleep_test.go b/libgo/go/time/sleep_test.go index 3cb088c319f..440d3b42f12 100644 --- a/libgo/go/time/sleep_test.go +++ b/libgo/go/time/sleep_test.go @@ -108,10 +108,11 @@ func TestAfter(t *testing.T) { } func TestAfterTick(t *testing.T) { - const ( - Delta = 100 * Millisecond - Count = 10 - ) + const Count = 10 + Delta := 100 * Millisecond + if testing.Short() { + Delta = 10 * Millisecond + } t0 := Now() for i := 0; i < Count; i++ { <-After(Delta) @@ -119,8 +120,11 @@ func TestAfterTick(t *testing.T) { t1 := Now() d := t1.Sub(t0) target := Delta * Count - if d < target*9/10 || d > target*30/10 { - t.Fatalf("%d ticks of %s took %s, expected %s", Count, Delta, d, target) + if d < target*9/10 { + t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target) + } + if !testing.Short() && d > target*30/10 { + t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target) } } @@ -165,7 +169,7 @@ func TestAfterQueuing(t *testing.T) { } // For gccgo omit 0 for now because it can take too long to start the -var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8 /*0*/ } +var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8 /*0*/} type afterResult struct { slot int @@ -177,9 +181,10 @@ func await(slot int, result chan<- afterResult, ac <-chan Time) { } func testAfterQueuing(t *testing.T) error { - const ( - Delta = 100 * Millisecond - ) + Delta := 100 * Millisecond + if testing.Short() { + Delta = 20 * Millisecond + } // make the result channel buffered because we don't want // to depend on channel queueing semantics that might // possibly change in the future. diff --git a/libgo/go/time/sys_plan9.go b/libgo/go/time/sys_plan9.go index c7cfa792a29..8484729448e 100644 --- a/libgo/go/time/sys_plan9.go +++ b/libgo/go/time/sys_plan9.go @@ -6,7 +6,10 @@ package time -import "syscall" +import ( + "errors" + "syscall" +) // for testing: whatever interrupts a sleep func interrupt() { @@ -38,3 +41,36 @@ func readFile(name string) ([]byte, error) { } return ret, err } + +func open(name string) (uintptr, error) { + fd, err := syscall.Open(name, syscall.O_RDONLY) + if err != nil { + return 0, err + } + return uintptr(fd), nil +} + +func closefd(fd uintptr) { + syscall.Close(int(fd)) +} + +func preadn(fd uintptr, buf []byte, off int) error { + whence := 0 + if off < 0 { + whence = 2 + } + if _, err := syscall.Seek(int(fd), int64(off), whence); err != nil { + return err + } + for len(buf) > 0 { + m, err := syscall.Read(int(fd), buf) + if m <= 0 { + if err == nil { + return errors.New("short read") + } + return err + } + buf = buf[m:] + } + return nil +} diff --git a/libgo/go/time/sys_unix.go b/libgo/go/time/sys_unix.go index 56a7414e0ce..7f69b492c9f 100644 --- a/libgo/go/time/sys_unix.go +++ b/libgo/go/time/sys_unix.go @@ -6,7 +6,10 @@ package time -import "syscall" +import ( + "errors" + "syscall" +) // for testing: whatever interrupts a sleep func interrupt() { @@ -38,3 +41,36 @@ func readFile(name string) ([]byte, error) { } return ret, err } + +func open(name string) (uintptr, error) { + fd, err := syscall.Open(name, syscall.O_RDONLY, 0) + if err != nil { + return 0, err + } + return uintptr(fd), nil +} + +func closefd(fd uintptr) { + syscall.Close(int(fd)) +} + +func preadn(fd uintptr, buf []byte, off int) error { + whence := 0 + if off < 0 { + whence = 2 + } + if _, err := syscall.Seek(int(fd), int64(off), whence); err != nil { + return err + } + for len(buf) > 0 { + m, err := syscall.Read(int(fd), buf) + if m <= 0 { + if err == nil { + return errors.New("short read") + } + return err + } + buf = buf[m:] + } + return nil +} diff --git a/libgo/go/time/sys_windows.go b/libgo/go/time/sys_windows.go index 8c7242f4275..de63b4bf4bb 100644 --- a/libgo/go/time/sys_windows.go +++ b/libgo/go/time/sys_windows.go @@ -4,6 +4,70 @@ package time +import ( + "errors" + "syscall" +) + // for testing: whatever interrupts a sleep func interrupt() { } + +// readFile reads and returns the content of the named file. +// It is a trivial implementation of ioutil.ReadFile, reimplemented +// here to avoid depending on io/ioutil or os. +func readFile(name string) ([]byte, error) { + f, err := syscall.Open(name, syscall.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer syscall.Close(f) + var ( + buf [4096]byte + ret []byte + n int + ) + for { + n, err = syscall.Read(f, buf[:]) + if n > 0 { + ret = append(ret, buf[:n]...) + } + if n == 0 || err != nil { + break + } + } + return ret, err +} + +func open(name string) (uintptr, error) { + fd, err := syscall.Open(name, syscall.O_RDONLY, 0) + if err != nil { + return 0, err + } + return uintptr(fd), nil +} + +func closefd(fd uintptr) { + syscall.Close(syscall.Handle(fd)) +} + +func preadn(fd uintptr, buf []byte, off int) error { + whence := 0 + if off < 0 { + whence = 2 + } + if _, err := syscall.Seek(syscall.Handle(fd), int64(off), whence); err != nil { + return err + } + for len(buf) > 0 { + m, err := syscall.Read(syscall.Handle(fd), buf) + if m <= 0 { + if err == nil { + return errors.New("short read") + } + return err + } + buf = buf[m:] + } + return nil +} diff --git a/libgo/go/time/tick_test.go b/libgo/go/time/tick_test.go index 36349349ce0..914f02c861c 100644 --- a/libgo/go/time/tick_test.go +++ b/libgo/go/time/tick_test.go @@ -10,10 +10,8 @@ import ( ) func TestTicker(t *testing.T) { - const ( - Delta = 100 * Millisecond - Count = 10 - ) + const Count = 10 + Delta := 100 * Millisecond ticker := NewTicker(Delta) t0 := Now() for i := 0; i < Count; i++ { @@ -39,8 +37,12 @@ func TestTicker(t *testing.T) { // Test that a bug tearing down a ticker has been fixed. This routine should not deadlock. func TestTeardown(t *testing.T) { + Delta := 100 * Millisecond + if testing.Short() { + Delta = 20 * Millisecond + } for i := 0; i < 3; i++ { - ticker := NewTicker(1e8) + ticker := NewTicker(Delta) <-ticker.C ticker.Stop() } diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go index 39d4b95dd06..f7ded24d292 100644 --- a/libgo/go/time/time.go +++ b/libgo/go/time/time.go @@ -152,7 +152,7 @@ func (d Weekday) String() string { return days[d] } // rely heavily on division and modulus by positive constants. For // calendrical calculations we want these divisions to round down, even // for negative values, so that the remainder is always positive, but -// Go's division (like most hardware divison instructions) rounds to +// Go's division (like most hardware division instructions) rounds to // zero. We can still do those computations and then adjust the result // for a negative numerator, but it's annoying to write the adjustment // over and over. Instead, we can change to a different epoch so long @@ -384,6 +384,15 @@ type Duration int64 // Common durations. There is no definition for units of Day or larger // to avoid confusion across daylight savings time zone transitions. +// +// To count the number of units in a Duration, divide: +// second := time.Second +// fmt.Print(int64(second/time.Millisecond)) // prints 1000 +// +// To convert an integer number of units to a Duration, multiply: +// seconds := 10 +// fmt.Print(time.Duration(seconds)*time.Second) // prints 10s +// const ( Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond @@ -758,10 +767,6 @@ func (t Time) UnixNano() int64 { return (t.sec+internalToUnix)*1e9 + int64(t.nsec) } -type gobError string - -func (g gobError) Error() string { return string(g) } - const timeGobVersion byte = 1 // GobEncode implements the gob.GobEncoder interface. @@ -841,46 +846,17 @@ func (t *Time) GobDecode(buf []byte) error { // MarshalJSON implements the json.Marshaler interface. // Time is formatted as RFC3339. func (t Time) MarshalJSON() ([]byte, error) { - yearInt := t.Year() - if yearInt < 0 || yearInt > 9999 { + if y := t.Year(); y < 0 || y >= 10000 { return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") } - - // We need a four-digit year, but Format produces variable-width years. - year := itoa(yearInt) - year = "0000"[:4-len(year)] + year - - var formattedTime string - if t.nsec == 0 { - // RFC3339, no fractional second - formattedTime = t.Format("-01-02T15:04:05Z07:00") - } else { - // RFC3339 with fractional second - formattedTime = t.Format("-01-02T15:04:05.000000000Z07:00") - - // Trim trailing zeroes from fractional second. - const nanoEnd = 24 // Index of last digit of fractional second - var i int - for i = nanoEnd; formattedTime[i] == '0'; i-- { - // Seek backwards until first significant digit is found. - } - - formattedTime = formattedTime[:i+1] + formattedTime[nanoEnd+1:] - } - - buf := make([]byte, 0, 1+len(year)+len(formattedTime)+1) - buf = append(buf, '"') - buf = append(buf, year...) - buf = append(buf, formattedTime...) - buf = append(buf, '"') - return buf, nil + return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil } // UnmarshalJSON implements the json.Unmarshaler interface. // Time is expected in RFC3339 format. func (t *Time) UnmarshalJSON(data []byte) (err error) { - *t, err = Parse("\""+RFC3339+"\"", string(data)) // Fractional seconds are handled implicitly by Parse. + *t, err = Parse(`"`+RFC3339+`"`, string(data)) return } diff --git a/libgo/go/time/time_test.go b/libgo/go/time/time_test.go index cdc1c39c5f5..3430526b8bf 100644 --- a/libgo/go/time/time_test.go +++ b/libgo/go/time/time_test.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/gob" "encoding/json" + "fmt" "math/rand" "strconv" "strings" @@ -227,6 +228,7 @@ var formatTests = []FormatTest{ {"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"}, {"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"}, {"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"}, + {"RFC3339Nano", RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"}, {"Kitchen", Kitchen, "9:00PM"}, {"am/pm", "3pm", "9pm"}, {"AM/PM", "3PM", "9PM"}, @@ -235,12 +237,12 @@ var formatTests = []FormatTest{ {"Stamp", Stamp, "Feb 4 21:00:57"}, {"StampMilli", StampMilli, "Feb 4 21:00:57.012"}, {"StampMicro", StampMicro, "Feb 4 21:00:57.012345"}, - {"StampNano", StampNano, "Feb 4 21:00:57.012345678"}, + {"StampNano", StampNano, "Feb 4 21:00:57.012345600"}, } func TestFormat(t *testing.T) { - // The numeric time represents Thu Feb 4 21:00:57.012345678 PST 2010 - time := Unix(0, 1233810057012345678) + // The numeric time represents Thu Feb 4 21:00:57.012345600 PST 2010 + time := Unix(0, 1233810057012345600) for _, test := range formatTests { result := time.Format(test.format) if result != test.result { @@ -249,6 +251,38 @@ func TestFormat(t *testing.T) { } } +func TestFormatShortYear(t *testing.T) { + years := []int{ + -100001, -100000, -99999, + -10001, -10000, -9999, + -1001, -1000, -999, + -101, -100, -99, + -11, -10, -9, + -1, 0, 1, + 9, 10, 11, + 99, 100, 101, + 999, 1000, 1001, + 9999, 10000, 10001, + 99999, 100000, 100001, + } + + for _, y := range years { + time := Date(y, January, 1, 0, 0, 0, 0, UTC) + result := time.Format("2006.01.02") + var want string + if y < 0 { + // The 4 in %04d counts the - sign, so print -y instead + // and introduce our own - sign. + want = fmt.Sprintf("-%04d.%02d.%02d", -y, 1, 1) + } else { + want = fmt.Sprintf("%04d.%02d.%02d", y, 1, 1) + } + if result != want { + t.Errorf("(jan 1 %d).Format(\"2006.01.02\") = %q, want %q", y, result, want) + } + } +} + type ParseTest struct { name string format string @@ -782,7 +816,7 @@ func TestTimeJSON(t *testing.T) { if jsonBytes, err := json.Marshal(tt.time); err != nil { t.Errorf("%v json.Marshal error = %v, want nil", tt.time, err) } else if string(jsonBytes) != tt.json { - t.Errorf("%v JSON = %q, want %q", tt.time, string(jsonBytes), tt.json) + t.Errorf("%v JSON = %#q, want %#q", tt.time, string(jsonBytes), tt.json) } else if err = json.Unmarshal(jsonBytes, &jsonTime); err != nil { t.Errorf("%v json.Unmarshal error = %v, want nil", tt.time, err) } else if !equalTimeAndZone(jsonTime, tt.time) { diff --git a/libgo/go/time/zoneinfo.go b/libgo/go/time/zoneinfo.go index aca56e746af..3c57744043e 100644 --- a/libgo/go/time/zoneinfo.go +++ b/libgo/go/time/zoneinfo.go @@ -4,7 +4,10 @@ package time -import "sync" +import ( + "sync" + "syscall" +) // A Location maps time instants to the zone in use at that time. // Typically, the Location represents the collection of time offsets @@ -168,10 +171,7 @@ func (l *Location) lookupOffset(offset int) (name string, isDST bool, ok bool) { // NOTE(rsc): Eventually we will need to accept the POSIX TZ environment // syntax too, but I don't feel like implementing it today. -// NOTE(rsc): Using the IANA names below means ensuring we have access -// to the database. Probably we will ship the files in $GOROOT/lib/zoneinfo/ -// and only look there if there are no system files available (such as on Windows). -// The files total 200 kB. +var zoneinfo, _ = syscall.Getenv("ZONEINFO") // LoadLocation returns the Location with the given name. // @@ -180,6 +180,13 @@ func (l *Location) lookupOffset(offset int) (name string, isDST bool, ok bool) { // // Otherwise, the name is taken to be a location name corresponding to a file // in the IANA Time Zone database, such as "America/New_York". +// +// The time zone database needed by LoadLocation may not be +// present on all systems, especially non-Unix systems. +// LoadLocation looks in the directory or uncompressed zip file +// named by the ZONEINFO environment variable, if any, then looks in +// known installation locations on Unix systems, +// and finally looks in $GOROOT/lib/time/zoneinfo.zip. func LoadLocation(name string) (*Location, error) { if name == "" || name == "UTC" { return UTC, nil @@ -187,5 +194,11 @@ func LoadLocation(name string) (*Location, error) { if name == "Local" { return Local, nil } + if zoneinfo != "" { + if z, err := loadZoneFile(zoneinfo, name); err == nil { + z.name = name + return z, nil + } + } return loadLocation(name) } diff --git a/libgo/go/time/zoneinfo_plan9.go b/libgo/go/time/zoneinfo_plan9.go index 9c052d42cd3..6855238dc84 100644 --- a/libgo/go/time/zoneinfo_plan9.go +++ b/libgo/go/time/zoneinfo_plan9.go @@ -8,11 +8,10 @@ package time import ( "errors" + "runtime" "syscall" ) -var badData = errors.New("malformed time zone information") - func isSpace(r rune) bool { return r == ' ' || r == '\t' || r == '\n' } @@ -51,7 +50,7 @@ func fields(s string) []string { return a } -func loadZoneData(s string) (l *Location, err error) { +func loadZoneDataPlan9(s string) (l *Location, err error) { f := fields(s) if len(f) < 4 { if len(f) == 2 && f[0] == "GMT" { @@ -112,33 +111,32 @@ func loadZoneData(s string) (l *Location, err error) { return l, nil } -func loadZoneFile(name string) (*Location, error) { +func loadZoneFilePlan9(name string) (*Location, error) { b, err := readFile(name) if err != nil { return nil, err } - return loadZoneData(string(b)) + return loadZoneDataPlan9(string(b)) } func initTestingZone() { - if z, err := loadZoneFile("/adm/timezone/US_Pacific"); err == nil { - localLoc = *z - return + z, err := loadLocation("America/Los_Angeles") + if err != nil { + panic("cannot load America/Los_Angeles for testing: " + err.Error()) } - - // Fall back to UTC. - localLoc.name = "UTC" + z.name = "Local" + localLoc = *z } func initLocal() { t, ok := syscall.Getenv("timezone") if ok { - if z, err := loadZoneData(t); err == nil { + if z, err := loadZoneDataPlan9(t); err == nil { localLoc = *z return } } else { - if z, err := loadZoneFile("/adm/timezone/local"); err == nil { + if z, err := loadZoneFilePlan9("/adm/timezone/local"); err == nil { localLoc = *z localLoc.name = "Local" return @@ -150,7 +148,8 @@ func initLocal() { } func loadLocation(name string) (*Location, error) { - if z, err := loadZoneFile("/adm/timezone/" + name); err == nil { + if z, err := loadZoneFile(runtime.GOROOT()+"/lib/time/zoneinfo.zip", name); err == nil { + z.name = name return z, nil } return nil, errors.New("unknown time zone " + name) diff --git a/libgo/go/time/zoneinfo_read.go b/libgo/go/time/zoneinfo_read.go new file mode 100644 index 00000000000..ebb4205a98f --- /dev/null +++ b/libgo/go/time/zoneinfo_read.go @@ -0,0 +1,341 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Parse "zoneinfo" time zone file. +// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others. +// See tzfile(5), http://en.wikipedia.org/wiki/Zoneinfo, +// and ftp://munnari.oz.au/pub/oldtz/ + +package time + +import "errors" + +const ( + headerSize = 4 + 16 + 4*7 +) + +// Simple I/O interface to binary blob of data. +type data struct { + p []byte + error bool +} + +func (d *data) read(n int) []byte { + if len(d.p) < n { + d.p = nil + d.error = true + return nil + } + p := d.p[0:n] + d.p = d.p[n:] + return p +} + +func (d *data) big4() (n uint32, ok bool) { + p := d.read(4) + if len(p) < 4 { + d.error = true + return 0, false + } + return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true +} + +func (d *data) byte() (n byte, ok bool) { + p := d.read(1) + if len(p) < 1 { + d.error = true + return 0, false + } + return p[0], true +} + +// Make a string by stopping at the first NUL +func byteString(p []byte) string { + for i := 0; i < len(p); i++ { + if p[i] == 0 { + return string(p[0:i]) + } + } + return string(p) +} + +var badData = errors.New("malformed time zone information") + +func loadZoneData(bytes []byte) (l *Location, err error) { + d := data{bytes, false} + + // 4-byte magic "TZif" + if magic := d.read(4); string(magic) != "TZif" { + return nil, badData + } + + // 1-byte version, then 15 bytes of padding + var p []byte + if p = d.read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' { + return nil, badData + } + + // six big-endian 32-bit integers: + // number of UTC/local indicators + // number of standard/wall indicators + // number of leap seconds + // number of transition times + // number of local time zones + // number of characters of time zone abbrev strings + const ( + NUTCLocal = iota + NStdWall + NLeap + NTime + NZone + NChar + ) + var n [6]int + for i := 0; i < 6; i++ { + nn, ok := d.big4() + if !ok { + return nil, badData + } + n[i] = int(nn) + } + + // Transition times. + txtimes := data{d.read(n[NTime] * 4), false} + + // Time zone indices for transition times. + txzones := d.read(n[NTime]) + + // Zone info structures + zonedata := data{d.read(n[NZone] * 6), false} + + // Time zone abbreviations. + abbrev := d.read(n[NChar]) + + // Leap-second time pairs + d.read(n[NLeap] * 8) + + // Whether tx times associated with local time types + // are specified as standard time or wall time. + isstd := d.read(n[NStdWall]) + + // Whether tx times associated with local time types + // are specified as UTC or local time. + isutc := d.read(n[NUTCLocal]) + + if d.error { // ran out of data + return nil, badData + } + + // If version == 2, the entire file repeats, this time using + // 8-byte ints for txtimes and leap seconds. + // We won't need those until 2106. + + // Now we can build up a useful data structure. + // First the zone information. + // utcoff[4] isdst[1] nameindex[1] + zone := make([]zone, n[NZone]) + for i := range zone { + var ok bool + var n uint32 + if n, ok = zonedata.big4(); !ok { + return nil, badData + } + zone[i].offset = int(n) + var b byte + if b, ok = zonedata.byte(); !ok { + return nil, badData + } + zone[i].isDST = b != 0 + if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) { + return nil, badData + } + zone[i].name = byteString(abbrev[b:]) + } + + // Now the transition time info. + tx := make([]zoneTrans, n[NTime]) + for i := range tx { + var ok bool + var n uint32 + if n, ok = txtimes.big4(); !ok { + return nil, badData + } + tx[i].when = int64(int32(n)) + if int(txzones[i]) >= len(zone) { + return nil, badData + } + tx[i].index = txzones[i] + if i < len(isstd) { + tx[i].isstd = isstd[i] != 0 + } + if i < len(isutc) { + tx[i].isutc = isutc[i] != 0 + } + } + + // Commited to succeed. + l = &Location{zone: zone, tx: tx} + + // Fill in the cache with information about right now, + // since that will be the most common lookup. + sec, _ := now() + for i := range tx { + if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) { + l.cacheStart = tx[i].when + l.cacheEnd = 1<<63 - 1 + if i+1 < len(tx) { + l.cacheEnd = tx[i+1].when + } + l.cacheZone = &l.zone[tx[i].index] + } + } + + return l, nil +} + +func loadZoneFile(dir, name string) (l *Location, err error) { + if len(dir) > 4 && dir[len(dir)-4:] == ".zip" { + return loadZoneZip(dir, name) + } + if dir != "" { + name = dir + "/" + name + } + buf, err := readFile(name) + if err != nil { + return + } + return loadZoneData(buf) +} + +// There are 500+ zoneinfo files. Rather than distribute them all +// individually, we ship them in an uncompressed zip file. +// Used this way, the zip file format serves as a commonly readable +// container for the individual small files. We choose zip over tar +// because zip files have a contiguous table of contents, making +// individual file lookups faster, and because the per-file overhead +// in a zip file is considerably less than tar's 512 bytes. + +// get4 returns the little-endian 32-bit value in b. +func get4(b []byte) int { + if len(b) < 4 { + return 0 + } + return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24 +} + +// get2 returns the little-endian 16-bit value in b. +func get2(b []byte) int { + if len(b) < 2 { + return 0 + } + return int(b[0]) | int(b[1])<<8 +} + +func loadZoneZip(zipfile, name string) (l *Location, err error) { + fd, err := open(zipfile) + if err != nil { + return nil, errors.New("open " + zipfile + ": " + err.Error()) + } + defer closefd(fd) + + const ( + zecheader = 0x06054b50 + zcheader = 0x02014b50 + ztailsize = 22 + + zheadersize = 30 + zheader = 0x04034b50 + ) + + buf := make([]byte, ztailsize) + if err := preadn(fd, buf, -ztailsize); err != nil || get4(buf) != zecheader { + return nil, errors.New("corrupt zip file " + zipfile) + } + n := get2(buf[10:]) + size := get4(buf[12:]) + off := get4(buf[16:]) + + buf = make([]byte, size) + if err := preadn(fd, buf, off); err != nil { + return nil, errors.New("corrupt zip file " + zipfile) + } + + for i := 0; i < n; i++ { + // zip entry layout: + // 0 magic[4] + // 4 madevers[1] + // 5 madeos[1] + // 6 extvers[1] + // 7 extos[1] + // 8 flags[2] + // 10 meth[2] + // 12 modtime[2] + // 14 moddate[2] + // 16 crc[4] + // 20 csize[4] + // 24 uncsize[4] + // 28 namelen[2] + // 30 xlen[2] + // 32 fclen[2] + // 34 disknum[2] + // 36 iattr[2] + // 38 eattr[4] + // 42 off[4] + // 46 name[namelen] + // 46+namelen+xlen+fclen - next header + // + if get4(buf) != zcheader { + break + } + meth := get2(buf[10:]) + size := get4(buf[24:]) + namelen := get2(buf[28:]) + xlen := get2(buf[30:]) + fclen := get2(buf[32:]) + off := get4(buf[42:]) + zname := buf[46 : 46+namelen] + buf = buf[46+namelen+xlen+fclen:] + if string(zname) != name { + continue + } + if meth != 0 { + return nil, errors.New("unsupported compression for " + name + " in " + zipfile) + } + + // zip per-file header layout: + // 0 magic[4] + // 4 extvers[1] + // 5 extos[1] + // 6 flags[2] + // 8 meth[2] + // 10 modtime[2] + // 12 moddate[2] + // 14 crc[4] + // 18 csize[4] + // 22 uncsize[4] + // 26 namelen[2] + // 28 xlen[2] + // 30 name[namelen] + // 30+namelen+xlen - file data + // + buf = make([]byte, zheadersize+namelen) + if err := preadn(fd, buf, off); err != nil || + get4(buf) != zheader || + get2(buf[8:]) != meth || + get2(buf[26:]) != namelen || + string(buf[30:30+namelen]) != name { + return nil, errors.New("corrupt zip file " + zipfile) + } + xlen = get2(buf[28:]) + + buf = make([]byte, size) + if err := preadn(fd, buf, off+30+namelen+xlen); err != nil { + return nil, errors.New("corrupt zip file " + zipfile) + } + + return loadZoneData(buf) + } + + return nil, errors.New("cannot find " + name + " in zip file " + zipfile) +} diff --git a/libgo/go/time/zoneinfo_unix.go b/libgo/go/time/zoneinfo_unix.go index 540b653c57d..1bf1f11e24f 100644 --- a/libgo/go/time/zoneinfo_unix.go +++ b/libgo/go/time/zoneinfo_unix.go @@ -13,200 +13,10 @@ package time import ( "errors" + "runtime" "syscall" ) -const ( - headerSize = 4 + 16 + 4*7 -) - -// Simple I/O interface to binary blob of data. -type data struct { - p []byte - error bool -} - -func (d *data) read(n int) []byte { - if len(d.p) < n { - d.p = nil - d.error = true - return nil - } - p := d.p[0:n] - d.p = d.p[n:] - return p -} - -func (d *data) big4() (n uint32, ok bool) { - p := d.read(4) - if len(p) < 4 { - d.error = true - return 0, false - } - return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true -} - -func (d *data) byte() (n byte, ok bool) { - p := d.read(1) - if len(p) < 1 { - d.error = true - return 0, false - } - return p[0], true -} - -// Make a string by stopping at the first NUL -func byteString(p []byte) string { - for i := 0; i < len(p); i++ { - if p[i] == 0 { - return string(p[0:i]) - } - } - return string(p) -} - -var badData = errors.New("malformed time zone information") - -func loadZoneData(bytes []byte) (l *Location, err error) { - d := data{bytes, false} - - // 4-byte magic "TZif" - if magic := d.read(4); string(magic) != "TZif" { - return nil, badData - } - - // 1-byte version, then 15 bytes of padding - var p []byte - if p = d.read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' { - return nil, badData - } - - // six big-endian 32-bit integers: - // number of UTC/local indicators - // number of standard/wall indicators - // number of leap seconds - // number of transition times - // number of local time zones - // number of characters of time zone abbrev strings - const ( - NUTCLocal = iota - NStdWall - NLeap - NTime - NZone - NChar - ) - var n [6]int - for i := 0; i < 6; i++ { - nn, ok := d.big4() - if !ok { - return nil, badData - } - n[i] = int(nn) - } - - // Transition times. - txtimes := data{d.read(n[NTime] * 4), false} - - // Time zone indices for transition times. - txzones := d.read(n[NTime]) - - // Zone info structures - zonedata := data{d.read(n[NZone] * 6), false} - - // Time zone abbreviations. - abbrev := d.read(n[NChar]) - - // Leap-second time pairs - d.read(n[NLeap] * 8) - - // Whether tx times associated with local time types - // are specified as standard time or wall time. - isstd := d.read(n[NStdWall]) - - // Whether tx times associated with local time types - // are specified as UTC or local time. - isutc := d.read(n[NUTCLocal]) - - if d.error { // ran out of data - return nil, badData - } - - // If version == 2, the entire file repeats, this time using - // 8-byte ints for txtimes and leap seconds. - // We won't need those until 2106. - - // Now we can build up a useful data structure. - // First the zone information. - // utcoff[4] isdst[1] nameindex[1] - zone := make([]zone, n[NZone]) - for i := range zone { - var ok bool - var n uint32 - if n, ok = zonedata.big4(); !ok { - return nil, badData - } - zone[i].offset = int(n) - var b byte - if b, ok = zonedata.byte(); !ok { - return nil, badData - } - zone[i].isDST = b != 0 - if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) { - return nil, badData - } - zone[i].name = byteString(abbrev[b:]) - } - - // Now the transition time info. - tx := make([]zoneTrans, n[NTime]) - for i := range tx { - var ok bool - var n uint32 - if n, ok = txtimes.big4(); !ok { - return nil, badData - } - tx[i].when = int64(int32(n)) - if int(txzones[i]) >= len(zone) { - return nil, badData - } - tx[i].index = txzones[i] - if i < len(isstd) { - tx[i].isstd = isstd[i] != 0 - } - if i < len(isutc) { - tx[i].isutc = isutc[i] != 0 - } - } - - // Commited to succeed. - l = &Location{zone: zone, tx: tx} - - // Fill in the cache with information about right now, - // since that will be the most common lookup. - sec, _ := now() - for i := range tx { - if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) { - l.cacheStart = tx[i].when - l.cacheEnd = 1<<63 - 1 - if i+1 < len(tx) { - l.cacheEnd = tx[i+1].when - } - l.cacheZone = &l.zone[tx[i].index] - } - } - - return l, nil -} - -func loadZoneFile(name string) (l *Location, err error) { - buf, err := readFile(name) - if err != nil { - return - } - return loadZoneData(buf) -} - func initTestingZone() { syscall.Setenv("TZ", "America/Los_Angeles") initLocal() @@ -218,6 +28,7 @@ var zoneDirs = []string{ "/usr/share/zoneinfo/", "/usr/share/lib/zoneinfo/", "/usr/lib/locale/TZ/", + runtime.GOROOT() + "/lib/time/zoneinfo/", } func initLocal() { @@ -229,7 +40,7 @@ func initLocal() { tz, ok := syscall.Getenv("TZ") switch { case !ok: - z, err := loadZoneFile("/etc/localtime") + z, err := loadZoneFile("", "/etc/localtime") if err == nil { localLoc = *z localLoc.name = "Local" @@ -248,7 +59,7 @@ func initLocal() { func loadLocation(name string) (*Location, error) { for _, zoneDir := range zoneDirs { - if z, err := loadZoneFile(zoneDir + name); err == nil { + if z, err := loadZoneFile(zoneDir, name); err == nil { z.name = name return z, nil } diff --git a/libgo/go/time/zoneinfo_windows.go b/libgo/go/time/zoneinfo_windows.go index beef4de92b0..754e392deca 100644 --- a/libgo/go/time/zoneinfo_windows.go +++ b/libgo/go/time/zoneinfo_windows.go @@ -6,6 +6,7 @@ package time import ( "errors" + "runtime" "syscall" ) @@ -151,7 +152,10 @@ func initLocal() { initLocalFromTZI(&i) } -// TODO(rsc): Implement. func loadLocation(name string) (*Location, error) { + if z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name); err == nil { + z.name = name + return z, nil + } return nil, errors.New("unknown time zone " + name) } diff --git a/libgo/go/unicode/graphic.go b/libgo/go/unicode/graphic.go index 2904da6c6d9..0de90ebd80c 100644 --- a/libgo/go/unicode/graphic.go +++ b/libgo/go/unicode/graphic.go @@ -53,7 +53,6 @@ func IsPrint(r rune) bool { } // IsOneOf reports whether the rune is a member of one of the ranges. -// The rune is known to be above Latin-1. func IsOneOf(set []*RangeTable, r rune) bool { for _, inside := range set { if Is(inside, r) { @@ -65,7 +64,7 @@ func IsOneOf(set []*RangeTable, r rune) bool { // IsControl reports whether the rune is a control character. // The C (Other) Unicode category includes more code points -// such as surrogates; use Is(C, rune) to test for them. +// such as surrogates; use Is(C, r) to test for them. func IsControl(r rune) bool { if uint32(r) <= MaxLatin1 { return properties[uint8(r)]&pC != 0 diff --git a/libgo/go/unicode/letter.go b/libgo/go/unicode/letter.go index dcc160a5b7d..be484553dc4 100644 --- a/libgo/go/unicode/letter.go +++ b/libgo/go/unicode/letter.go @@ -60,8 +60,8 @@ type CaseRange struct { // Methods of SpecialCase customize (by overriding) the standard mappings. type SpecialCase []CaseRange -//BUG(r): Provide a mechanism for full case folding (those that involve -// multiple runes in the input or output). +// BUG(r): There is no mechanism for full case folding, that is, for +// characters that involve multiple runes in the input or output. // Indices into the Delta arrays inside CaseRanges for case mapping. const ( @@ -288,7 +288,7 @@ type foldPair struct { // SimpleFold iterates over Unicode code points equivalent under // the Unicode-defined simple case folding. Among the code points // equivalent to rune (including rune itself), SimpleFold returns the -// smallest r >= rune if one exists, or else the smallest r >= 0. +// smallest rune >= r if one exists, or else the smallest rune >= 0. // // For example: // SimpleFold('A') = 'a' diff --git a/libgo/go/unicode/tables.go b/libgo/go/unicode/tables.go index 978c48ae43e..5009e6b98c8 100644 --- a/libgo/go/unicode/tables.go +++ b/libgo/go/unicode/tables.go @@ -7,7 +7,7 @@ package unicode // Version is the Unicode edition from which the tables are derived. const Version = "6.0.0" -// Categories is the set of Unicode data tables. +// Categories is the set of Unicode category tables. var Categories = map[string]*RangeTable{ "C": C, "Cc": Cc, diff --git a/libgo/go/unicode/utf8/utf8.go b/libgo/go/unicode/utf8/utf8.go index a5f9983b332..631533a5a35 100644 --- a/libgo/go/unicode/utf8/utf8.go +++ b/libgo/go/unicode/utf8/utf8.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package utf8 implements functions and constants to support text encoded in -// UTF-8. This package calls a Unicode character a rune for brevity. +// UTF-8. It includes functions to translate between runes and UTF-8 byte sequences. package utf8 import "unicode" // only needed for a couple of constants @@ -198,19 +198,21 @@ func FullRuneInString(s string) bool { } // DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes. +// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8. func DecodeRune(p []byte) (r rune, size int) { r, size, _ = decodeRuneInternal(p) return } // DecodeRuneInString is like DecodeRune but its input is a string. +// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8. func DecodeRuneInString(s string) (r rune, size int) { r, size, _ = decodeRuneInStringInternal(s) return } -// DecodeLastRune unpacks the last UTF-8 encoding in p -// and returns the rune and its width in bytes. +// DecodeLastRune unpacks the last UTF-8 encoding in p and returns the rune and its width in bytes. +// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8. func DecodeLastRune(p []byte) (r rune, size int) { end := len(p) if end == 0 { @@ -244,6 +246,7 @@ func DecodeLastRune(p []byte) (r rune, size int) { } // DecodeLastRuneInString is like DecodeLastRune but its input is a string. +// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8. func DecodeLastRuneInString(s string) (r rune, size int) { end := len(s) if end == 0 { diff --git a/libgo/merge.sh b/libgo/merge.sh index c8a57ca2816..32652118fe5 100755 --- a/libgo/merge.sh +++ b/libgo/merge.sh @@ -163,7 +163,7 @@ done done done -runtime="chan.c cpuprof.c goc2c.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc" +runtime="chan.c cpuprof.c goc2c.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h signal_unix.c malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc" for f in $runtime; do merge_c $f $f done diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 62296b8af2f..e5f3066e26a 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -78,6 +78,7 @@ cat > sysinfo.c <<EOF #if defined(HAVE_SYS_SELECT_H) #include <sys/select.h> #endif +#include <time.h> #include <unistd.h> #include <netdb.h> #include <pwd.h> @@ -93,6 +94,30 @@ cat > sysinfo.c <<EOF #if defined(HAVE_NET_IF_H) #include <net/if.h> #endif +#if defined(HAVE_SYS_MOUNT_H) +#include <sys/mount.h> +#endif +#if defined(HAVE_SYS_VFS_H) +#include <sys/vfs.h> +#endif +#if defined(HAVE_STATFS_H) +#include <sys/statfs.h> +#endif +#if defined(HAVE_SYS_TIMEX_H) +#include <sys/timex.h> +#endif +#if defined(HAVE_SYS_SYSINFO_H) +#include <sys/sysinfo.h> +#endif +#if defined(HAVE_USTAT_H) +#include <ustat.h> +#endif +#if defined(HAVE_UTIME_H) +#include <utime.h> +#endif +#if defined(HAVE_LINUX_REBOOT_H) +#include <linux/reboot.h> +#endif /* Constants that may only be defined as expressions on some systems, expressions too complex for -fdump-go-spec to handle. These are @@ -147,7 +172,7 @@ fi # The signal numbers. grep '^const _SIG[^_]' gen-sysinfo.go | \ grep -v '^const _SIGEV_' | \ - sed -e 's/^\(const \)_\(SIG[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + sed -e 's/^\(const \)_\(SIG[^= ]*\)\(.*\)$/\1\2 = Signal(_\2)/' >> ${OUT} # The syscall numbers. We force the names to upper case. grep '^const _SYS_' gen-sysinfo.go | \ @@ -166,6 +191,8 @@ grep '^const _PROT_' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(PROT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} grep '^const _MAP_' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(MAP_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +grep '^const _MADV_' gen-sysinfo.go | \ + sed -e 's/^\(const \)_\(MADV_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} # Process status constants. grep '^const _W' gen-sysinfo.go | @@ -330,6 +357,11 @@ if grep "^// type _upad128_t" gen-sysinfo.go > /dev/null 2>&1; then echo "type _upad128_t struct { _l [4]uint32; }" >> ${OUT} fi +# The time_t type. +if grep '^type _time_t ' gen-sysinfo.go > /dev/null 2>&1; then + echo 'type Time_t _time_t' >> ${OUT} +fi + # The time structures need special handling: we need to name the # types, so that we can cast integers to the right types when # assigning to the structures. @@ -703,6 +735,10 @@ grep '^const _IFLA' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFLA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} grep '^const _IFF' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFF[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +grep '^const _IFNAMSIZ' gen-sysinfo.go | \ + sed -e 's/^\(const \)_\(IFNAMSIZ[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +grep '^const _SIOC' gen-sysinfo.go | + sed -e 's/^\(const \)_\(SIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} # The size of the ifinfomsg struct. if grep 'type IfInfomsg ' ${OUT} > /dev/null 2>&1; then @@ -766,4 +802,131 @@ for n in IGNBRK BRKINT IGNPAR PARMRK INPCK ISTRIP INLCR IGNCR ICRNL IUCLC \ sed -e 's/^\(const \)_\([^=]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} done +# The mount flags +grep '^const _MS_' gen-sysinfo.go | + sed -e 's/^\(const \)_\(MS_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + +# The fallocate flags. +grep '^const _FALLOC_' gen-sysinfo.go | + sed -e 's/^\(const \)_\(FALLOC_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + +# The statfs struct. +# Prefer largefile variant if available. +statfs=`grep '^type _statfs64 ' gen-sysinfo.go || true` +if test "$statfs" != ""; then + grep '^type _statfs64 ' gen-sysinfo.go +else + grep '^type _statfs ' gen-sysinfo.go +fi | sed -e 's/type _statfs64/type Statfs_t/' \ + -e 's/type _statfs/type Statfs_t/' \ + -e 's/f_type/Type/' \ + -e 's/f_bsize/Bsize/' \ + -e 's/f_blocks/Blocks/' \ + -e 's/f_bfree/Bfree/' \ + -e 's/f_bavail/Bavail/' \ + -e 's/f_files/Files/' \ + -e 's/f_ffree/Ffree/' \ + -e 's/f_fsid/Fsid/' \ + -e 's/f_namelen/Namelen/' \ + -e 's/f_frsize/Frsize/' \ + -e 's/f_flags/Flags/' \ + -e 's/f_spare/Spare/' \ + >> ${OUT} + +# The timex struct. +grep '^type _timex ' gen-sysinfo.go | \ + sed -e 's/_timex/Timex/' \ + -e 's/modes/Modes/' \ + -e 's/offset/Offset/' \ + -e 's/freq/Freq/' \ + -e 's/maxerror/Maxerror/' \ + -e 's/esterror/Esterror/' \ + -e 's/status/Status/' \ + -e 's/constant/Constant/' \ + -e 's/precision/Precision/' \ + -e 's/tolerance/Tolerance/' \ + -e 's/ time / Time /' \ + -e 's/tick/Tick/' \ + -e 's/ppsfreq/Ppsfreq/' \ + -e 's/jitter/Jitter/' \ + -e 's/shift/Shift/' \ + -e 's/stabil/Stabil/' \ + -e 's/jitcnt/Jitcnt/' \ + -e 's/calcnt/Calcnt/' \ + -e 's/errcnt/Errcnt/' \ + -e 's/stbcnt/Stbcnt/' \ + -e 's/tai/Tai/' \ + -e 's/_timeval/Timeval/' \ + >> ${OUT} + +# The rlimit struct. +grep '^type _rlimit ' gen-sysinfo.go | \ + sed -e 's/_rlimit/Rlimit/' \ + -e 's/rlim_cur/Cur/' \ + -e 's/rlim_max/Max/' \ + >> ${OUT} + +# The RLIMIT constants. +grep '^const _RLIMIT_' gen-sysinfo.go | + sed -e 's/^\(const \)_\(RLIMIT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + +# The sysinfo struct. +grep '^type _sysinfo ' gen-sysinfo.go | \ + sed -e 's/_sysinfo/Sysinfo_t/' \ + -e 's/uptime/Uptime/' \ + -e 's/loads/Loads/' \ + -e 's/totalram/Totalram/' \ + -e 's/freeram/Freeram/' \ + -e 's/sharedram/Sharedram/' \ + -e 's/bufferram/Bufferram/' \ + -e 's/totalswap/Totalswap/' \ + -e 's/freeswap/Freeswap/' \ + -e 's/procs/Procs/' \ + -e 's/totalhigh/Totalhigh/' \ + -e 's/freehigh/Freehigh/' \ + -e 's/mem_unit/Unit/' \ + >> ${OUT} + +# The ustat struct. +grep '^type _ustat ' gen-sysinfo.go | \ + sed -e 's/_ustat/Ustat_t/' \ + -e 's/f_tfree/Tfree/' \ + -e 's/f_tinode/Tinoe/' \ + -e 's/f_fname/Fname/' \ + -e 's/f_fpack/Fpack/' \ + >> ${OUT} +# Force it to be defined, as on some older GNU/Linux systems the +# header file fails when using with <linux/filter.h>. +if ! grep 'type _ustat ' gen-sysinfo.go >/dev/null 2>&1; then + echo 'type Ustat_t struct { Tfree int32; Tinoe uint64; Fname [5+1]int8; Fpack [5+1]int8; }' >> ${OUT} +fi + +# The utimbuf struct. +grep '^type _utimbuf ' gen-sysinfo.go | \ + sed -e 's/_utimbuf/Utimbuf/' \ + -e 's/actime/Actime/' \ + -e 's/modtime/Modtime/' \ + >> ${OUT} + +# The GNU/Linux LINUX_REBOOT flags. +grep '^const _LINUX_REBOOT_' gen-sysinfo.go | + sed -e 's/^\(const \)_\(LINUX_REBOOT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + +# The GNU/Linux sock_filter struct. +grep '^type _sock_filter ' gen-sysinfo.go | \ + sed -e 's/_sock_filter/SockFilter/' \ + -e 's/code/Code/' \ + -e 's/jt/Jt/' \ + -e 's/jf/Jf/' \ + -e 's/k /K /' \ + >> ${OUT} + +# The GNU/Linux sock_fprog struct. +grep '^type _sock_fprog ' gen-sysinfo.go | \ + sed -e 's/_sock_fprog/SockFprog/' \ + -e 's/len/Len/' \ + -e 's/filter/Filter/' \ + -e 's/_sock_filter/SockFilter/' \ + >> ${OUT} + exit $? diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c index 24be9500a8b..db91d2c49ea 100644 --- a/libgo/runtime/chan.c +++ b/libgo/runtime/chan.c @@ -662,6 +662,10 @@ newselect(int32 size, Select **selp) if(size > 1) n = size-1; + // allocate all the memory we need in a single allocation + // start with Select with size cases + // then lockorder with size entries + // then pollorder with size entries sel = runtime_mal(sizeof(*sel) + n*sizeof(sel->scase[0]) + size*sizeof(sel->lockorder[0]) + diff --git a/libgo/runtime/go-assert-interface.c b/libgo/runtime/go-assert-interface.c index 57a092d59b6..94bdaeef429 100644 --- a/libgo/runtime/go-assert-interface.c +++ b/libgo/runtime/go-assert-interface.c @@ -8,6 +8,7 @@ #include "go-assert.h" #include "go-panic.h" #include "interface.h" +#include "runtime.h" /* This is called by the compiler to implement a type assertion from one interface type to another. This returns the value that should @@ -26,14 +27,8 @@ __go_assert_interface (const struct __go_type_descriptor *lhs_descriptor, /* A type assertion is not permitted with a nil interface. */ - newTypeAssertionError (NULL, - NULL, - lhs_descriptor, - NULL, - NULL, - lhs_descriptor->__reflection, - NULL, - &panic_arg); + runtime_newTypeAssertionError (NULL, NULL, lhs_descriptor->__reflection, + NULL, &panic_arg); __go_panic (panic_arg); } diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c index b18759f2f4b..f2bebeba519 100644 --- a/libgo/runtime/go-caller.c +++ b/libgo/runtime/go-caller.c @@ -8,8 +8,64 @@ #include <stdint.h> +#include "runtime.h" #include "go-string.h" +/* Get the function name, file name, and line number for a PC value. + We use the DWARF debug information to get this. Rather than write + a whole new library in C, we use the existing Go library. + Unfortunately, the Go library is only available if the debug/elf + package is imported (we use debug/elf for both ELF and Mach-O, in + this case). We arrange for the debug/elf package to register + itself, and tweak the various packages that need this information + to import debug/elf where possible. */ + +/* The function that returns function/file/line information. */ + +typedef _Bool (*infofn_type) (uintptr_t, struct __go_string *, + struct __go_string *, int *); +static infofn_type infofn; + +/* The function that returns the value of a symbol, used to get the + entry address of a function. */ + +typedef _Bool (*symvalfn_type) (struct __go_string, uintptr_t *); +static symvalfn_type symvalfn; + +/* This is called by debug/elf to register the function that returns + function/file/line information. */ + +void RegisterDebugLookup (infofn_type, symvalfn_type) + __asm__ ("libgo_runtime.runtime.RegisterDebugLookup"); + +void +RegisterDebugLookup (infofn_type pi, symvalfn_type ps) +{ + infofn = pi; + symvalfn = ps; +} + +/* Return function/file/line information for PC. */ + +_Bool +__go_file_line (uintptr_t pc, struct __go_string *fn, struct __go_string *file, + int *line) +{ + if (infofn == NULL) + return 0; + return infofn (pc, fn, file, line); +} + +/* Return the value of a symbol. */ + +_Bool +__go_symbol_value (struct __go_string sym, uintptr_t *val) +{ + if (symvalfn == NULL) + return 0; + return symvalfn (sym, val); +} + /* The values returned by runtime.Caller. */ struct caller_ret @@ -20,32 +76,71 @@ struct caller_ret _Bool ok; }; -/* Implement runtime.Caller. */ - struct caller_ret Caller (int n) asm ("libgo_runtime.runtime.Caller"); +Func *FuncForPC (uintptr_t) asm ("libgo_runtime.runtime.FuncForPC"); + +/* Implement runtime.Caller. */ + struct caller_ret -Caller (int n __attribute__ ((unused))) +Caller (int skip) { struct caller_ret ret; + uintptr pc; + int32 n; + struct __go_string fn; - /* A proper implementation needs to dig through the debugging - information. */ - ret.pc = (uint64_t) (uintptr_t) __builtin_return_address (0); - ret.file.__data = NULL; - ret.file.__length = 0; - ret.line = 0; - ret.ok = 0; - + runtime_memclr (&ret, sizeof ret); + n = runtime_callers (skip + 1, &pc, 1); + if (n < 1) + return ret; + ret.pc = pc; + ret.ok = __go_file_line (pc, &fn, &ret.file, &ret.line); return ret; } /* Implement runtime.FuncForPC. */ -void *FuncForPC (uintptr_t) asm ("libgo_runtime.runtime.FuncForPC"); +Func * +FuncForPC (uintptr_t pc) +{ + Func *ret; + struct __go_string fn; + struct __go_string file; + int line; + uintptr_t val; -void * -FuncForPC(uintptr_t pc __attribute__ ((unused))) + if (!__go_file_line (pc, &fn, &file, &line)) + return NULL; + if (!__go_symbol_value (fn, &val)) + return NULL; + + ret = (Func *) runtime_malloc (sizeof (*ret)); + ret->name = fn; + ret->entry = val; + return ret; +} + +/* Look up the file and line information for a PC within a + function. */ + +struct funcline_go_return { - return NULL; + struct __go_string retfile; + int retline; +}; + +struct funcline_go_return +runtime_funcline_go (Func *f, uintptr targetpc) + __asm__ ("libgo_runtime.runtime.funcline_go"); + +struct funcline_go_return +runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc) +{ + struct funcline_go_return ret; + struct __go_string fn; + + if (!__go_file_line (targetpc, &fn, &ret.retfile, &ret.retline)) + runtime_memclr (&ret, sizeof ret); + return ret; } diff --git a/libgo/runtime/go-callers.c b/libgo/runtime/go-callers.c new file mode 100644 index 00000000000..09556c33c7a --- /dev/null +++ b/libgo/runtime/go-callers.c @@ -0,0 +1,76 @@ +/* go-callers.c -- get callers for Go. + + Copyright 2012 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. */ + +#include "config.h" + +#include "unwind.h" + +#include "runtime.h" + +/* Argument passed to backtrace function. */ + +struct callers_data +{ + int skip; + uintptr *pcbuf; + int index; + int max; +}; + +static _Unwind_Reason_Code +backtrace (struct _Unwind_Context *context, void *varg) +{ + struct callers_data *arg = (struct callers_data *) varg; + uintptr pc; + int ip_before_insn = 0; + +#ifdef HAVE_GETIPINFO + pc = _Unwind_GetIPInfo (context, &ip_before_insn); +#else + pc = _Unwind_GetIP (context); +#endif + + /* FIXME: If PC is in the __morestack routine, we should ignore + it. */ + + if (arg->skip > 0) + --arg->skip; + else if (arg->index >= arg->max) + return _URC_END_OF_STACK; + else + { + /* Here PC will be the return address. We actually want the + address of the call instruction, so back up one byte and + count on the lookup routines handling that correctly. */ + if (!ip_before_insn) + --pc; + arg->pcbuf[arg->index] = pc; + ++arg->index; + } + return _URC_NO_REASON; +} + +int32 +runtime_callers (int32 skip, uintptr *pcbuf, int32 m) +{ + struct callers_data arg; + + arg.skip = skip + 1; + arg.pcbuf = pcbuf; + arg.index = 0; + arg.max = m; + _Unwind_Backtrace (backtrace, &arg); + return arg.index; +} + +int Callers (int, struct __go_open_array) + __asm__ ("libgo_runtime.runtime.Callers"); + +int +Callers (int skip, struct __go_open_array pc) +{ + return runtime_callers (skip, (uintptr *) pc.__values, pc.__count); +} diff --git a/libgo/runtime/go-check-interface.c b/libgo/runtime/go-check-interface.c index d2258a854b7..963559d8ed0 100644 --- a/libgo/runtime/go-check-interface.c +++ b/libgo/runtime/go-check-interface.c @@ -6,6 +6,7 @@ #include "go-panic.h" #include "interface.h" +#include "runtime.h" /* Check that an interface type matches for a conversion to a non-interface type. This panics if the types are bad. The actual @@ -21,8 +22,8 @@ __go_check_interface_type ( { struct __go_empty_interface panic_arg; - newTypeAssertionError(NULL, NULL, lhs_descriptor, NULL, NULL, - lhs_descriptor->__reflection, NULL, &panic_arg); + runtime_newTypeAssertionError(NULL, NULL, lhs_descriptor->__reflection, + NULL, &panic_arg); __go_panic(panic_arg); } @@ -35,12 +36,10 @@ __go_check_interface_type ( { struct __go_empty_interface panic_arg; - newTypeAssertionError(rhs_inter_descriptor, rhs_descriptor, - lhs_descriptor, - rhs_inter_descriptor->__reflection, - rhs_descriptor->__reflection, - lhs_descriptor->__reflection, - NULL, &panic_arg); + runtime_newTypeAssertionError(rhs_inter_descriptor->__reflection, + rhs_descriptor->__reflection, + lhs_descriptor->__reflection, + NULL, &panic_arg); __go_panic(panic_arg); } } diff --git a/libgo/runtime/go-convert-interface.c b/libgo/runtime/go-convert-interface.c index 259456cda16..8ce82ea5ed6 100644 --- a/libgo/runtime/go-convert-interface.c +++ b/libgo/runtime/go-convert-interface.c @@ -8,6 +8,7 @@ #include "go-assert.h" #include "go-panic.h" #include "interface.h" +#include "runtime.h" /* This is called when converting one interface type into another interface type. LHS_DESCRIPTOR is the type descriptor of the @@ -55,14 +56,10 @@ __go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor, if (may_fail) return NULL; - newTypeAssertionError (NULL, - rhs_descriptor, - lhs_descriptor, - NULL, - rhs_descriptor->__reflection, - lhs_descriptor->__reflection, - lhs_methods[0].__name, - &panic_arg); + runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection, + lhs_descriptor->__reflection, + lhs_methods[0].__name, + &panic_arg); __go_panic (panic_arg); } @@ -100,14 +97,9 @@ __go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor, if (may_fail) return NULL; - newTypeAssertionError (NULL, - rhs_descriptor, - lhs_descriptor, - NULL, - rhs_descriptor->__reflection, - lhs_descriptor->__reflection, - p_lhs_method->__name, - &panic_arg); + runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection, + lhs_descriptor->__reflection, + p_lhs_method->__name, &panic_arg); __go_panic (panic_arg); } diff --git a/libgo/runtime/go-main.c b/libgo/runtime/go-main.c index 45467ed06c0..7e8bb9b234f 100644 --- a/libgo/runtime/go-main.c +++ b/libgo/runtime/go-main.c @@ -40,7 +40,7 @@ static void mainstart (void *); int main (int argc, char **argv) { - runtime_initsig (0); + runtime_check (); runtime_args (argc, (byte **) argv); runtime_osinit (); runtime_schedinit (); diff --git a/libgo/runtime/go-nosys.c b/libgo/runtime/go-nosys.c index 6b328544f0d..4a30a57ad25 100644 --- a/libgo/runtime/go-nosys.c +++ b/libgo/runtime/go-nosys.c @@ -48,6 +48,18 @@ faccessat (int fd __attribute__ ((unused)), } #endif +#ifndef HAVE_FALLOCATE +int +fallocate (int fd __attribute__ ((unused)), + int mode __attribute__ ((unused)), + off_t offset __attribute__ ((unused)), + off_t len __attribute__ ((unused))) +{ + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_FCHMODAT int fchmodat (int dirfd __attribute__ ((unused)), @@ -104,6 +116,15 @@ inotify_init (void) } #endif +#ifndef HAVE_INOTIFY_INIT1 +int +inotify_init1 (int flags __attribute__ ((unused))) +{ + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_INOTIFY_RM_WATCH int inotify_rm_watch (int fd __attribute__ ((unused)), @@ -175,6 +196,18 @@ splice (int fd __attribute__ ((unused)), } #endif +#ifndef HAVE_SYNC_FILE_RANGE +int +sync_file_range (int fd __attribute__ ((unused)), + off64_t offset __attribute__ ((unused)), + off64_t nbytes __attribute__ ((unused)), + unsigned int flags __attribute__ ((unused))) +{ + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_TEE int tee (int fd_in __attribute__ ((unused)), diff --git a/libgo/runtime/go-panic.c b/libgo/runtime/go-panic.c index 24dc74bd285..7ba426f5148 100644 --- a/libgo/runtime/go-panic.c +++ b/libgo/runtime/go-panic.c @@ -27,7 +27,7 @@ __printpanics (struct __go_panic_stack *p) fprintf (stderr, "\t"); } fprintf (stderr, "panic: "); - printany (p->__arg); + runtime_printany (p->__arg); if (p->__was_recovered) fprintf (stderr, " [recovered]"); fputc ('\n', stderr); diff --git a/libgo/runtime/go-panic.h b/libgo/runtime/go-panic.h index 41996e43b5f..76411498759 100644 --- a/libgo/runtime/go-panic.h +++ b/libgo/runtime/go-panic.h @@ -40,23 +40,4 @@ extern struct __go_empty_interface __go_recover (void); extern void __go_unwind_stack (void); -/* Functions defined in libgo/go/runtime/error.go. */ - -extern void newTypeAssertionError(const struct __go_type_descriptor *pt1, - const struct __go_type_descriptor *pt2, - const struct __go_type_descriptor *pt3, - const struct __go_string *ps1, - const struct __go_string *ps2, - const struct __go_string *ps3, - const struct __go_string *pmeth, - struct __go_empty_interface *ret) - __asm__ ("libgo_runtime.runtime.NewTypeAssertionError"); - -extern void runtime_newErrorString(struct __go_string, - struct __go_empty_interface *) - __asm__ ("libgo_runtime.runtime.NewErrorString"); - -extern void printany(struct __go_empty_interface) - __asm__ ("libgo_runtime.runtime.Printany"); - #endif /* !defined(LIBGO_GO_PANIC_H) */ diff --git a/libgo/runtime/go-reflect.c b/libgo/runtime/go-reflect.c deleted file mode 100644 index d14a5805549..00000000000 --- a/libgo/runtime/go-reflect.c +++ /dev/null @@ -1,192 +0,0 @@ -/* go-reflect.c -- implement unsafe.Reflect and unsafe.Typeof for Go. - - Copyright 2009 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include <stdlib.h> -#include <stdint.h> - -#include "runtime.h" -#include "interface.h" -#include "go-alloc.h" -#include "go-string.h" -#include "go-type.h" - -/* For field alignment. */ - -struct field_align -{ - char c; - struct __go_type_descriptor *p; -}; - -/* The type descriptors in the runtime package. */ - -extern const struct __go_type_descriptor ptr_bool_descriptor - asm ("__go_td_pN30_libgo_runtime.runtime.BoolType"); -extern const struct __go_type_descriptor ptr_float_descriptor - asm ("__go_td_pN31_libgo_runtime.runtime.FloatType"); -extern const struct __go_type_descriptor ptr_complex_descriptor - asm ("__go_td_pN33_libgo_runtime.runtime.ComplexType"); -extern const struct __go_type_descriptor ptr_int_descriptor - asm ("__go_td_pN29_libgo_runtime.runtime.IntType"); -extern const struct __go_type_descriptor ptr_uint_descriptor - asm ("__go_td_pN30_libgo_runtime.runtime.UintType"); -extern const struct __go_type_descriptor ptr_string_descriptor - asm ("__go_td_pN32_libgo_runtime.runtime.StringType"); -extern const struct __go_type_descriptor ptr_unsafe_pointer_decriptor - asm ("__go_td_pN39_libgo_runtime.runtime.UnsafePointerType"); -extern const struct __go_type_descriptor ptr_array_descriptor - asm ("__go_td_pN31_libgo_runtime.runtime.ArrayType"); -extern const struct __go_type_descriptor ptr_slice_descriptor - asm ("__go_td_pN31_libgo_runtime.runtime.SliceType"); -extern const struct __go_type_descriptor ptr_chan_descriptor - asm ("__go_td_pN30_libgo_runtime.runtime.ChanType"); -extern const struct __go_type_descriptor ptr_func_descriptor - asm ("__go_td_pN30_libgo_runtime.runtime.FuncType"); -extern const struct __go_type_descriptor ptr_interface_descriptor - asm ("__go_td_pN35_libgo_runtime.runtime.InterfaceType"); -extern const struct __go_type_descriptor ptr_map_descriptor - asm ("__go_td_pN29_libgo_runtime.runtime.MapType"); -extern const struct __go_type_descriptor ptr_ptr_descriptor - asm ("__go_td_pN29_libgo_runtime.runtime.PtrType"); -extern const struct __go_type_descriptor ptr_struct_descriptor - asm ("__go_td_pN32_libgo_runtime.runtime.StructType"); - -const struct __go_type_descriptor * -get_descriptor (int code) -{ - switch (code & GO_CODE_MASK) - { - case GO_BOOL: - return &ptr_bool_descriptor; - case GO_FLOAT32: - case GO_FLOAT64: - return &ptr_float_descriptor; - case GO_COMPLEX64: - case GO_COMPLEX128: - return &ptr_complex_descriptor; - case GO_INT16: - case GO_INT32: - case GO_INT64: - case GO_INT8: - case GO_INT: - return &ptr_int_descriptor; - case GO_UINT16: - case GO_UINT32: - case GO_UINT64: - case GO_UINT8: - case GO_UINTPTR: - case GO_UINT: - return &ptr_uint_descriptor; - case GO_STRING: - return &ptr_string_descriptor; - case GO_UNSAFE_POINTER: - return &ptr_unsafe_pointer_decriptor; - case GO_ARRAY: - return &ptr_array_descriptor; - case GO_SLICE: - return &ptr_slice_descriptor; - case GO_CHAN: - return &ptr_chan_descriptor; - case GO_FUNC: - return &ptr_func_descriptor; - case GO_INTERFACE: - return &ptr_interface_descriptor; - case GO_MAP: - return &ptr_map_descriptor; - case GO_PTR: - return &ptr_ptr_descriptor; - case GO_STRUCT: - return &ptr_struct_descriptor; - default: - abort (); - } -} - -/* Implement unsafe.Reflect. */ - -struct reflect_ret -{ - struct __go_empty_interface rettype; - void *addr; -}; - -struct reflect_ret Reflect (struct __go_empty_interface) - asm ("libgo_unsafe.unsafe.Reflect"); - -struct reflect_ret -Reflect (struct __go_empty_interface e) -{ - struct reflect_ret ret; - - if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0) - runtime_panicstring ("invalid interface value"); - - if (e.__type_descriptor == NULL) - { - ret.rettype.__type_descriptor = NULL; - ret.rettype.__object = NULL; - ret.addr = NULL; - } - else - { - size_t size; - - ret.rettype.__type_descriptor = - get_descriptor (e.__type_descriptor->__code); - - /* This memcpy is really just an assignment of a const pointer - to a non-const pointer. FIXME: We should canonicalize this - pointer, so that for a given type we always return the same - pointer. */ - __builtin_memcpy (&ret.rettype.__object, &e.__type_descriptor, - sizeof (void *)); - - /* Make a copy of the value. */ - size = e.__type_descriptor->__size; - if (size <= sizeof (uint64_t)) - ret.addr = __go_alloc (sizeof (uint64_t)); - else - ret.addr = __go_alloc (size); - if (__go_is_pointer_type (e.__type_descriptor)) - *(void **) ret.addr = e.__object; - else - __builtin_memcpy (ret.addr, e.__object, size); - } - - return ret; -} - -/* Implement unsafe.Typeof. */ - -struct __go_empty_interface Typeof (struct __go_empty_interface) - asm ("libgo_unsafe.unsafe.Typeof"); - -struct __go_empty_interface -Typeof (const struct __go_empty_interface e) -{ - struct __go_empty_interface ret; - - if (((uintptr_t) e.__type_descriptor & reflectFlags) != 0) - runtime_panicstring ("invalid interface value"); - - if (e.__type_descriptor == NULL) - { - ret.__type_descriptor = NULL; - ret.__object = NULL; - } - else - { - ret.__type_descriptor = get_descriptor (e.__type_descriptor->__code); - - /* This memcpy is really just an assignment of a const pointer - to a non-const pointer. FIXME: We should canonicalize this - pointer, so that for a given type we always return the same - pointer. */ - __builtin_memcpy (&ret.__object, &e.__type_descriptor, sizeof (void *)); - } - - return ret; -} diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c index fd48f4ba659..b698ae2b897 100644 --- a/libgo/runtime/go-signal.c +++ b/libgo/runtime/go-signal.c @@ -25,11 +25,11 @@ extern void __splitstack_setcontext(void *context[10]); #endif -#define C SigCatch -#define I SigIgnore -#define R SigRestart -#define Q SigQueue +#define N SigNotify +#define K SigKill +#define T SigThrow #define P SigPanic +#define D SigDefault /* Signal actions. This collects the sigtab tables for several different targets from the master library. SIGKILL, SIGCONT, and @@ -38,105 +38,105 @@ extern void __splitstack_setcontext(void *context[10]); SigTab runtime_sigtab[] = { #ifdef SIGHUP - { SIGHUP, Q + R }, + { SIGHUP, N + K }, #endif #ifdef SIGINT - { SIGINT, Q + R }, + { SIGINT, N + K }, #endif #ifdef SIGQUIT - { SIGQUIT, C }, + { SIGQUIT, N + T }, #endif #ifdef SIGILL - { SIGILL, C }, + { SIGILL, T }, #endif #ifdef SIGTRAP - { SIGTRAP, C }, + { SIGTRAP, T }, #endif #ifdef SIGABRT - { SIGABRT, C }, + { SIGABRT, N + T }, #endif #ifdef SIGBUS - { SIGBUS, C + P }, + { SIGBUS, P }, #endif #ifdef SIGFPE - { SIGFPE, C + P }, + { SIGFPE, P }, #endif #ifdef SIGUSR1 - { SIGUSR1, Q + I + R }, + { SIGUSR1, N }, #endif #ifdef SIGSEGV - { SIGSEGV, C + P }, + { SIGSEGV, P }, #endif #ifdef SIGUSR2 - { SIGUSR2, Q + I + R }, + { SIGUSR2, N }, #endif #ifdef SIGPIPE - { SIGPIPE, I }, + { SIGPIPE, N }, #endif #ifdef SIGALRM - { SIGALRM, Q + I + R }, + { SIGALRM, N }, #endif #ifdef SIGTERM - { SIGTERM, Q + R }, + { SIGTERM, N + K }, #endif #ifdef SIGSTKFLT - { SIGSTKFLT, C }, + { SIGSTKFLT, T }, #endif #ifdef SIGCHLD - { SIGCHLD, Q + I + R }, + { SIGCHLD, N }, #endif #ifdef SIGTSTP - { SIGTSTP, Q + I + R }, + { SIGTSTP, N + D }, #endif #ifdef SIGTTIN - { SIGTTIN, Q + I + R }, + { SIGTTIN, N + D }, #endif #ifdef SIGTTOU - { SIGTTOU, Q + I + R }, + { SIGTTOU, N + D }, #endif #ifdef SIGURG - { SIGURG, Q + I + R }, + { SIGURG, N }, #endif #ifdef SIGXCPU - { SIGXCPU, Q + I + R }, + { SIGXCPU, N }, #endif #ifdef SIGXFSZ - { SIGXFSZ, Q + I + R }, + { SIGXFSZ, N }, #endif #ifdef SIGVTALRM - { SIGVTALRM, Q + I + R }, + { SIGVTALRM, N }, #endif #ifdef SIGPROF - { SIGPROF, Q + I + R }, + { SIGPROF, N }, #endif #ifdef SIGWINCH - { SIGWINCH, Q + I + R }, + { SIGWINCH, N }, #endif #ifdef SIGIO - { SIGIO, Q + I + R }, + { SIGIO, N }, #endif #ifdef SIGPWR - { SIGPWR, Q + I + R }, + { SIGPWR, N }, #endif #ifdef SIGSYS - { SIGSYS, C }, + { SIGSYS, N }, #endif #ifdef SIGEMT - { SIGEMT, C }, + { SIGEMT, T }, #endif #ifdef SIGINFO - { SIGINFO, Q + I + R }, + { SIGINFO, N }, #endif #ifdef SIGTHR - { SIGTHR, Q + I + R }, + { SIGTHR, N }, #endif { -1, 0 } }; -#undef C -#undef I -#undef R -#undef Q +#undef N +#undef K +#undef T #undef P +#undef D /* Handle a signal, for cases where we don't panic. We can split the stack here. */ @@ -158,21 +158,24 @@ sig_handler (int sig) for (i = 0; runtime_sigtab[i].sig != -1; ++i) { struct sigaction sa; + SigTab *t; - if (runtime_sigtab[i].sig != sig) + t = &runtime_sigtab[i]; + + if (t->sig != sig) continue; - if ((runtime_sigtab[i].flags & SigQueue) != 0) + if ((t->flags & SigNotify) != 0) { - if (__go_sigsend (sig) - || (runtime_sigtab[sig].flags & SigIgnore) != 0) + if (__go_sigsend (sig)) return; - runtime_exit (2); // SIGINT, SIGTERM, etc } - - if (runtime_panicking) + if ((t->flags & SigKill) != 0) runtime_exit (2); - runtime_panicking = 1; + if ((t->flags & SigThrow) == 0) + return; + + runtime_startpanic (); /* We should do a stack backtrace here. Until we can do that, we reraise the signal in order to get a slightly better @@ -227,7 +230,7 @@ static void sig_panic_info_handler (int sig, siginfo_t *info, void *context __attribute__ ((unused))) { - if (runtime_g () == NULL) + if (runtime_g () == NULL || info->si_code == SI_USER) { sig_handler (sig); return; @@ -316,16 +319,6 @@ sig_panic_handler (int sig) #endif /* !defined (SA_SIGINFO) */ -/* Ignore a signal. This is called on the alternate signal stack so - it may not split the stack. */ - -static void sig_ignore (int) __attribute__ ((no_split_stack)); - -static void -sig_ignore (int sig __attribute__ ((unused))) -{ -} - /* A signal handler used for signals which are not going to panic. This is called on the alternate signal stack so it may not split the stack. */ @@ -376,100 +369,41 @@ sig_tramp (int sig) } } -/* Initialize signal handling for Go. This is called when the program - starts. */ - void -runtime_initsig (int32 queue) +runtime_setsig (int32 i, bool def __attribute__ ((unused)), bool restart) { struct sigaction sa; - int i; - - siginit (); + int r; + SigTab *t; memset (&sa, 0, sizeof sa); - i = sigfillset (&sa.sa_mask); - __go_assert (i == 0); - - for (i = 0; runtime_sigtab[i].sig != -1; ++i) - { - if (runtime_sigtab[i].flags == 0) - continue; - if ((runtime_sigtab[i].flags & SigQueue) != queue) - continue; - - if ((runtime_sigtab[i].flags & (SigCatch | SigQueue)) != 0) - { - if ((runtime_sigtab[i].flags & SigPanic) == 0) - { - sa.sa_flags = SA_ONSTACK; - sa.sa_handler = sig_tramp; - } - else - { -#ifdef SA_SIGINFO - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = sig_panic_info_handler; -#else - sa.sa_flags = 0; - sa.sa_handler = sig_panic_handler; -#endif - } - } - else - { - sa.sa_flags = SA_ONSTACK; - sa.sa_handler = sig_ignore; - } + r = sigfillset (&sa.sa_mask); + __go_assert (r == 0); - if ((runtime_sigtab[i].flags & SigRestart) != 0) - sa.sa_flags |= SA_RESTART; + t = &runtime_sigtab[i]; - if (sigaction (runtime_sigtab[i].sig, &sa, NULL) != 0) - __go_assert (0); - } -} - -void -runtime_resetcpuprofiler(int32 hz) -{ -#ifdef SIGPROF - struct itimerval it; - struct sigaction sa; - int i; - - memset (&it, 0, sizeof it); - - memset (&sa, 0, sizeof sa); - i = sigfillset (&sa.sa_mask); - __go_assert (i == 0); - - if (hz == 0) + if ((t->flags & SigPanic) == 0) { - i = setitimer (ITIMER_PROF, &it, NULL); - __go_assert (i == 0); - - sa.sa_handler = SIG_IGN; - i = sigaction (SIGPROF, &sa, NULL); - __go_assert (i == 0); + sa.sa_flags = SA_ONSTACK; + sa.sa_handler = sig_tramp; } else { - sa.sa_handler = sig_handler; - sa.sa_flags = SA_RESTART; - i = sigaction (SIGPROF, &sa, NULL); - __go_assert (i == 0); - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 1000000 / hz; - it.it_value = it.it_interval; - i = setitimer (ITIMER_PROF, &it, NULL); - __go_assert (i == 0); - } +#ifdef SA_SIGINFO + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sig_panic_info_handler; +#else + sa.sa_flags = 0; + sa.sa_handler = sig_panic_handler; #endif + } + + if (restart) + sa.sa_flags |= SA_RESTART; - runtime_m()->profilehz = hz; + if (sigaction (t->sig, &sa, NULL) != 0) + __go_assert (0); } /* Used by the os package to raise SIGPIPE. */ @@ -494,3 +428,9 @@ os_sigpipe (void) raise (SIGPIPE); } + +void +runtime_setprof(bool on) +{ + USED(on); +} diff --git a/libgo/runtime/go-type-identity.c b/libgo/runtime/go-type-identity.c index 142edf42464..a50a8a131a1 100644 --- a/libgo/runtime/go-type-identity.c +++ b/libgo/runtime/go-type-identity.c @@ -6,6 +6,7 @@ #include <stddef.h> +#include "config.h" #include "go-type.h" /* The 64-bit type. */ @@ -31,7 +32,11 @@ __go_type_hash_identity (const void *key, uintptr_t key_size) unsigned char a[8]; } u; u.v = 0; - __builtin_memcpy (&u.a, key, key_size); +#ifdef WORDS_BIGENDIAN + __builtin_memcpy (&u.a[8 - key_size], key, key_size); +#else + __builtin_memcpy (&u.a[0], key, key_size); +#endif if (sizeof (uintptr_t) >= 8) return (uintptr_t) u.v; else diff --git a/libgo/runtime/go-unreflect.c b/libgo/runtime/go-unreflect.c deleted file mode 100644 index 6f1ea732fa3..00000000000 --- a/libgo/runtime/go-unreflect.c +++ /dev/null @@ -1,34 +0,0 @@ -/* go-unreflect.c -- implement unsafe.Unreflect for Go. - - Copyright 2009 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include "runtime.h" -#include "go-alloc.h" -#include "go-type.h" -#include "interface.h" - -/* Implement unsafe.Unreflect. */ - -struct __go_empty_interface Unreflect (struct __go_empty_interface type, - void *object) - asm ("libgo_unsafe.unsafe.Unreflect"); - -struct __go_empty_interface -Unreflect (struct __go_empty_interface type, void *object) -{ - struct __go_empty_interface ret; - - if (((uintptr_t) type.__type_descriptor & reflectFlags) != 0) - runtime_panicstring ("invalid interface value"); - - /* FIXME: We should check __type_descriptor to verify that this is - really a type descriptor. */ - ret.__type_descriptor = type.__object; - if (__go_is_pointer_type (ret.__type_descriptor)) - ret.__object = *(void **) object; - else - ret.__object = object; - return ret; -} diff --git a/libgo/runtime/go-unsafe-new.c b/libgo/runtime/go-unsafe-new.c index c60e05b3bda..2b9e044dc33 100644 --- a/libgo/runtime/go-unsafe-new.c +++ b/libgo/runtime/go-unsafe-new.c @@ -9,15 +9,16 @@ #include "go-type.h" #include "interface.h" -/* Implement unsafe.New. */ +/* Implement unsafe_New, called from the reflect package. */ -void *New (struct __go_empty_interface type) asm ("libgo_unsafe.unsafe.New"); +void *unsafe_New (struct __go_empty_interface type) + asm ("libgo_reflect.reflect.unsafe_New"); /* The dynamic type of the argument will be a pointer to a type descriptor. */ void * -New (struct __go_empty_interface type) +unsafe_New (struct __go_empty_interface type) { const struct __go_type_descriptor *descriptor; diff --git a/libgo/runtime/go-unsafe-newarray.c b/libgo/runtime/go-unsafe-newarray.c index 470ed2d0c72..f4c5595d463 100644 --- a/libgo/runtime/go-unsafe-newarray.c +++ b/libgo/runtime/go-unsafe-newarray.c @@ -9,16 +9,16 @@ #include "go-type.h" #include "interface.h" -/* Implement unsafe.NewArray. */ +/* Implement unsafe_NewArray, called from the reflect package. */ -void *NewArray (struct __go_empty_interface type, int n) - asm ("libgo_unsafe.unsafe.NewArray"); +void *unsafe_NewArray (struct __go_empty_interface type, int n) + asm ("libgo_reflect.reflect.unsafe_NewArray"); /* The dynamic type of the argument will be a pointer to a type descriptor. */ void * -NewArray (struct __go_empty_interface type, int n) +unsafe_NewArray (struct __go_empty_interface type, int n) { const struct __go_type_descriptor *descriptor; diff --git a/libgo/runtime/lock_futex.c b/libgo/runtime/lock_futex.c index cdc12d7c75c..9a533a577a4 100644 --- a/libgo/runtime/lock_futex.c +++ b/libgo/runtime/lock_futex.c @@ -118,8 +118,12 @@ runtime_notewakeup(Note *n) void runtime_notesleep(Note *n) { + if(runtime_m()->profilehz > 0) + runtime_setprof(false); while(runtime_atomicload(&n->key) == 0) runtime_futexsleep(&n->key, 0, -1); + if(runtime_m()->profilehz > 0) + runtime_setprof(true); } void @@ -135,14 +139,18 @@ runtime_notetsleep(Note *n, int64 ns) if(runtime_atomicload(&n->key) != 0) return; + if(runtime_m()->profilehz > 0) + runtime_setprof(false); deadline = runtime_nanotime() + ns; for(;;) { runtime_futexsleep(&n->key, 0, ns); if(runtime_atomicload(&n->key) != 0) - return; + break; now = runtime_nanotime(); if(now >= deadline) - return; + break; ns = deadline - now; } + if(runtime_m()->profilehz > 0) + runtime_setprof(true); } diff --git a/libgo/runtime/lock_sema.c b/libgo/runtime/lock_sema.c index b2a8f53be41..8c4b3973bdc 100644 --- a/libgo/runtime/lock_sema.c +++ b/libgo/runtime/lock_sema.c @@ -159,7 +159,11 @@ runtime_notesleep(Note *n) return; } // Queued. Sleep. + if(m->profilehz > 0) + runtime_setprof(false); runtime_semasleep(-1); + if(m->profilehz > 0) + runtime_setprof(true); } void @@ -185,12 +189,16 @@ runtime_notetsleep(Note *n, int64 ns) return; } + if(m->profilehz > 0) + runtime_setprof(false); deadline = runtime_nanotime() + ns; for(;;) { // Registered. Sleep. if(runtime_semasleep(ns) >= 0) { // Acquired semaphore, semawakeup unregistered us. // Done. + if(m->profilehz > 0) + runtime_setprof(true); return; } @@ -203,6 +211,9 @@ runtime_notetsleep(Note *n, int64 ns) ns = deadline - now; } + if(m->profilehz > 0) + runtime_setprof(true); + // Deadline arrived. Still registered. Semaphore not acquired. // Want to give up and return, but have to unregister first, // so that any notewakeup racing with the return does not diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index 9ad9eda8350..3fde250af3b 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -19,6 +19,7 @@ package runtime #include "go-type.h" MHeap runtime_mheap; + extern MStats mstats; // defined in extern.go extern volatile int32 runtime_MemProfileRate @@ -276,15 +277,27 @@ runtime_mallocinit(void) uintptr arena_size, bitmap_size; extern byte end[]; byte *want; + uintptr limit; runtime_sizeof_C_MStats = sizeof(MStats); + p = nil; + arena_size = 0; + bitmap_size = 0; + + // for 64-bit build + USED(p); + USED(arena_size); + USED(bitmap_size); + runtime_InitSizes(); + limit = runtime_memlimit(); + // Set up the allocation arena, a contiguous area of memory where // allocated data will be found. The arena begins with a bitmap large // enough to hold 4 bits per allocated word. - if(sizeof(void*) == 8) { + if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) { // On a 64-bit machine, allocate from a single contiguous reservation. // 16 GB should be big enough for now. // @@ -307,12 +320,13 @@ runtime_mallocinit(void) // Actually we reserve 17 GB (because the bitmap ends up being 1 GB) // but it hardly matters: fc is not valid UTF-8 either, and we have to // allocate 15 GB before we get that far. + // + // If this fails we fall back to the 32 bit memory mechanism arena_size = (uintptr)(16LL<<30); bitmap_size = arena_size / (sizeof(void*)*8/4); p = runtime_SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size); - if(p == nil) - runtime_throw("runtime: cannot reserve arena virtual address space"); - } else { + } + if (p == nil) { // On a 32-bit machine, we can't typically get away // with a giant virtual address space reservation. // Instead we map the memory information bitmap @@ -332,6 +346,10 @@ runtime_mallocinit(void) // of address space, which is probably too much in a 32-bit world. bitmap_size = MaxArena32 / (sizeof(void*)*8/4); arena_size = 512<<20; + if(limit > 0 && arena_size+bitmap_size > limit) { + bitmap_size = (limit / 9) & ~((1<<PageShift) - 1); + arena_size = bitmap_size * 8; + } // SysReserve treats the address we ask for, end, as a hint, // not as an absolute requirement. If we ask for the end @@ -348,6 +366,8 @@ runtime_mallocinit(void) p = runtime_SysReserve(want, bitmap_size + arena_size); if(p == nil) runtime_throw("runtime: cannot reserve arena virtual address space"); + if((uintptr)p & (((uintptr)1<<PageShift)-1)) + runtime_printf("runtime: SysReserve returned unaligned address %p; asked for %p", p, (void*)(bitmap_size+arena_size)); } if((uintptr)p & (((uintptr)1<<PageShift)-1)) runtime_throw("runtime: SysReserve returned unaligned address"); @@ -379,8 +399,8 @@ runtime_MHeap_SysAlloc(MHeap *h, uintptr n) return p; } - // On 64-bit, our reservation is all we have. - if(sizeof(void*) == 8) + // If using 64-bit, our reservation is all we have. + if(sizeof(void*) == 8 && (uintptr)h->bitmap >= 0xffffffffU) return nil; // On 32-bit, once the reservation is gone we can @@ -419,18 +439,6 @@ func new(typ *Type) (ret *uint8) { ret = runtime_mallocgc(typ->__size, flag, 1, 1); } -func Alloc(n uintptr) (p *byte) { - p = runtime_malloc(n); -} - -func Free(p *byte) { - runtime_free(p); -} - -func Lookup(p *byte) (base *byte, size uintptr) { - runtime_mlookup(p, &base, &size, nil); -} - func GC() { runtime_gc(1); } diff --git a/libgo/runtime/malloc.h b/libgo/runtime/malloc.h index c1cf02c6deb..4cb07477f15 100644 --- a/libgo/runtime/malloc.h +++ b/libgo/runtime/malloc.h @@ -205,6 +205,7 @@ struct MStats uint64 heap_sys; // bytes obtained from system uint64 heap_idle; // bytes in idle spans uint64 heap_inuse; // bytes in non-idle spans + uint64 heap_released; // bytes released to the OS uint64 heap_objects; // total number of allocated objects // Statistics about allocation of low-level fixed-size structures. @@ -220,6 +221,7 @@ struct MStats // Statistics about garbage collector. // Protected by stopping the world during GC. uint64 next_gc; // next GC (in heap_alloc time) + uint64 last_gc; // last GC (in absolute time) uint64 pause_total_ns; uint64 pause_ns[256]; uint32 numgc; @@ -304,14 +306,16 @@ struct MSpan { MSpan *next; // in a span linked list MSpan *prev; // in a span linked list - MSpan *allnext; // in the list of all spans + MSpan *allnext; // in the list of all spans PageID start; // starting page number uintptr npages; // number of pages in span MLink *freelist; // list of free objects uint32 ref; // number of allocated objects in this span uint32 sizeclass; // size class uint32 state; // MSpanInUse etc - byte *limit; // end of data in span + int64 unusedsince; // First time spotted by GC in MSpanFree state + uintptr npreleased; // number of pages released to the OS + byte *limit; // end of data in span }; void runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages); @@ -381,6 +385,7 @@ MSpan* runtime_MHeap_LookupMaybe(MHeap *h, void *v); void runtime_MGetSizeClassInfo(int32 sizeclass, uintptr *size, int32 *npages, int32 *nobj); void* runtime_MHeap_SysAlloc(MHeap *h, uintptr n); void runtime_MHeap_MapBits(MHeap *h); +void runtime_MHeap_Scavenger(void*); void* runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed); int32 runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **s); @@ -406,19 +411,11 @@ enum void runtime_MProf_Malloc(void*, uintptr); void runtime_MProf_Free(void*, uintptr); +void runtime_MProf_GC(void); void runtime_MProf_Mark(void (*scan)(byte *, int64)); int32 runtime_helpgc(bool*); void runtime_gchelper(void); -// Malloc profiling settings. -// Must match definition in extern.go. -enum { - MProf_None = 0, - MProf_Sample = 1, - MProf_All = 2, -}; -extern int32 runtime_malloc_profile; - struct __go_func_type; bool runtime_getfinalizer(void *p, bool del, void (**fn)(void*), const struct __go_func_type **ft); void runtime_walkfintab(void (*fn)(void*), void (*scan)(byte *, int64)); diff --git a/libgo/runtime/mem.c b/libgo/runtime/mem.c index a1c5eaa36d7..9df4c870dcf 100644 --- a/libgo/runtime/mem.c +++ b/libgo/runtime/mem.c @@ -39,6 +39,22 @@ addrspace_free(void *v __attribute__ ((unused)), uintptr n __attribute__ ((unuse return 1; } +static void * +mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset) +{ + void *p; + + p = runtime_mmap((void *)v, n, prot, flags, fd, offset); + if(p != v && addrspace_free(v, n)) { + // On some systems, mmap ignores v without + // MAP_FIXED, so retry if the address space is free. + if(p != MAP_FAILED) + runtime_munmap(p, n); + p = runtime_mmap((void *)v, n, prot, flags|MAP_FIXED, fd, offset); + } + return p; +} + void* runtime_SysAlloc(uintptr n) { @@ -91,12 +107,6 @@ runtime_SysReserve(void *v, uintptr n) int fd = -1; void *p; - // On 64-bit, people with ulimit -v set complain if we reserve too - // much address space. Instead, assume that the reservation is okay - // and check the assumption in SysMap. - if(sizeof(void*) == 8) - return v; - #ifdef USE_DEV_ZERO if (dev_zero == -1) { dev_zero = open("/dev/zero", O_RDONLY); @@ -108,10 +118,21 @@ runtime_SysReserve(void *v, uintptr n) fd = dev_zero; #endif + // On 64-bit, people with ulimit -v set complain if we reserve too + // much address space. Instead, assume that the reservation is okay + // if we can reserve at least 64K and check the assumption in SysMap. + // Only user-mode Linux (UML) rejects these requests. + if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) { + p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, fd, 0); + if (p != v) + return nil; + runtime_munmap(p, 64<<10); + return v; + } + p = runtime_mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, fd, 0); - if((uintptr)p < 4096 || -(uintptr)p < 4096) { + if(p == MAP_FAILED) return nil; - } return p; } @@ -135,13 +156,10 @@ runtime_SysMap(void *v, uintptr n) #endif // On 64-bit, we don't actually have v reserved, so tread carefully. - if(sizeof(void*) == 8) { - p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0); - if(p != v && addrspace_free(v, n)) { - // On some systems, mmap ignores v without - // MAP_FIXED, so retry if the address space is free. - p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0); - } + if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) { + p = mmap_fixed(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0); + if(p == MAP_FAILED && errno == ENOMEM) + runtime_throw("runtime: out of memory"); if(p != v) { runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p); runtime_throw("runtime: address space conflict"); diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index 73c399df239..4aa7c45dcb3 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -61,6 +61,21 @@ enum { #define bitMask (bitBlockBoundary | bitAllocated | bitMarked | bitSpecial) +// Holding worldsema grants an M the right to try to stop the world. +// The procedure is: +// +// runtime_semacquire(&runtime_worldsema); +// m->gcing = 1; +// runtime_stoptheworld(); +// +// ... do stuff ... +// +// m->gcing = 0; +// runtime_semrelease(&runtime_worldsema); +// runtime_starttheworld(); +// +uint32 runtime_worldsema = 1; + // TODO: Make these per-M. static uint64 nhandoff; @@ -92,7 +107,6 @@ struct FinBlock Finalizer fin[1]; }; - static G *fing; static FinBlock *finq; // list of finalizers that are to be executed static FinBlock *finc; // cache of free blocks @@ -640,14 +654,6 @@ markfin(void *v) scanblock(v, size); } -struct root_list { - struct root_list *next; - struct root { - void *decl; - size_t size; - } roots[]; -}; - static struct root_list* roots; void @@ -778,9 +784,11 @@ sweep(void) byte *p; MCache *c; byte *arena_start; + int64 now; m = runtime_m(); arena_start = runtime_mheap.arena_start; + now = runtime_nanotime(); for(;;) { s = work.spans; @@ -789,6 +797,11 @@ sweep(void) if(!runtime_casp(&work.spans, s, s->allnext)) continue; + // Stamp newly unused spans. The scavenger will use that + // info to potentially give back some pages to the OS. + if(s->state == MSpanFree && s->unusedsince == 0) + s->unusedsince = now; + if(s->state != MSpanInUse) continue; @@ -875,11 +888,6 @@ runtime_gchelper(void) runtime_notewakeup(&work.alldone); } -// Semaphore, not Lock, so that the goroutine -// reschedules when there is contention rather -// than spinning. -static uint32 gcsema = 1; - // Initialized from $GOGC. GOGC=off means no gc. // // Next gc is after we've allocated an extra amount of @@ -968,9 +976,9 @@ runtime_gc(int32 force) if(gcpercent < 0) return; - runtime_semacquire(&gcsema); + runtime_semacquire(&runtime_worldsema); if(!force && mstats.heap_alloc < mstats.next_gc) { - runtime_semrelease(&gcsema); + runtime_semrelease(&runtime_worldsema); return; } @@ -1032,6 +1040,7 @@ runtime_gc(int32 force) obj1 = mstats.nmalloc - mstats.nfree; t3 = runtime_nanotime(); + mstats.last_gc = t3; mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t3 - t0; mstats.pause_total_ns += t3 - t0; mstats.numgc++; @@ -1045,8 +1054,9 @@ runtime_gc(int32 force) (unsigned long long) mstats.nmalloc, (unsigned long long)mstats.nfree, (unsigned long long) nhandoff); } - - runtime_semrelease(&gcsema); + + runtime_MProf_GC(); + runtime_semrelease(&runtime_worldsema); // If we could have used another helper proc, start one now, // in the hope that it will be available next time. @@ -1073,18 +1083,18 @@ runtime_ReadMemStats(MStats *stats) { M *m; - // Have to acquire gcsema to stop the world, + // Have to acquire worldsema to stop the world, // because stoptheworld can only be used by // one goroutine at a time, and there might be // a pending garbage collection already calling it. - runtime_semacquire(&gcsema); + runtime_semacquire(&runtime_worldsema); m = runtime_m(); m->gcing = 1; runtime_stoptheworld(); cachestats(); *stats = mstats; m->gcing = 0; - runtime_semrelease(&gcsema); + runtime_semrelease(&runtime_worldsema); runtime_starttheworld(false); } diff --git a/libgo/runtime/mheap.c b/libgo/runtime/mheap.c index 5a5a1e71a12..6bf38aa9934 100644 --- a/libgo/runtime/mheap.c +++ b/libgo/runtime/mheap.c @@ -103,6 +103,8 @@ HaveSpan: runtime_MSpanList_Remove(s); s->state = MSpanInUse; mstats.heap_idle -= s->npages<<PageShift; + mstats.heap_released -= s->npreleased<<PageShift; + s->npreleased = 0; if(s->npages > npage) { // Trim extra and put it back in the heap. @@ -280,6 +282,8 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) } mstats.heap_idle += s->npages<<PageShift; s->state = MSpanFree; + s->unusedsince = 0; + s->npreleased = 0; runtime_MSpanList_Remove(s); sp = (uintptr*)(s->start<<PageShift); @@ -292,6 +296,7 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) *tp |= *sp; // propagate "needs zeroing" mark s->start = t->start; s->npages += t->npages; + s->npreleased = t->npreleased; // absorb released pages p -= t->npages; h->map[p] = s; runtime_MSpanList_Remove(t); @@ -304,6 +309,7 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) tp = (uintptr*)(t->start<<PageShift); *sp |= *tp; // propagate "needs zeroing" mark s->npages += t->npages; + s->npreleased += t->npreleased; h->map[p + s->npages - 1] = s; runtime_MSpanList_Remove(t); t->state = MSpanDead; @@ -317,8 +323,86 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) runtime_MSpanList_Insert(&h->free[s->npages], s); else runtime_MSpanList_Insert(&h->large, s); +} - // TODO(rsc): IncrementalScavenge() to return memory to OS. +// Release (part of) unused memory to OS. +// Goroutine created at startup. +// Loop forever. +void +runtime_MHeap_Scavenger(void* dummy) +{ + MHeap *h; + MSpan *s, *list; + uint64 tick, now, forcegc, limit; + uint32 k, i; + uintptr released, sumreleased; + const byte *env; + bool trace; + Note note; + + USED(dummy); + + // If we go two minutes without a garbage collection, force one to run. + forcegc = 2*60*1e9; + // If a span goes unused for 5 minutes after a garbage collection, + // we hand it back to the operating system. + limit = 5*60*1e9; + // Make wake-up period small enough for the sampling to be correct. + if(forcegc < limit) + tick = forcegc/2; + else + tick = limit/2; + + trace = false; + env = runtime_getenv("GOGCTRACE"); + if(env != nil) + trace = runtime_atoi(env) > 0; + + h = &runtime_mheap; + for(k=0;; k++) { + runtime_noteclear(¬e); + runtime_entersyscall(); + runtime_notetsleep(¬e, tick); + runtime_exitsyscall(); + + runtime_lock(h); + now = runtime_nanotime(); + if(now - mstats.last_gc > forcegc) { + runtime_unlock(h); + runtime_gc(1); + runtime_lock(h); + now = runtime_nanotime(); + if (trace) + runtime_printf("scvg%d: GC forced\n", k); + } + sumreleased = 0; + for(i=0; i < nelem(h->free)+1; i++) { + if(i < nelem(h->free)) + list = &h->free[i]; + else + list = &h->large; + if(runtime_MSpanList_IsEmpty(list)) + continue; + for(s=list->next; s != list; s=s->next) { + if(s->unusedsince != 0 && (now - s->unusedsince) > limit) { + released = (s->npages - s->npreleased) << PageShift; + mstats.heap_released += released; + sumreleased += released; + s->npreleased = s->npages; + runtime_SysUnused((void*)(s->start << PageShift), s->npages << PageShift); + } + } + } + runtime_unlock(h); + + if(trace) { + if(sumreleased > 0) + runtime_printf("scvg%d: %p MB released\n", k, (void*)(sumreleased>>20)); + runtime_printf("scvg%d: inuse: %lld, idle: %lld, sys: %lld, released: %lld, consumed: %lld (MB)\n", + k, (long long)(mstats.heap_inuse>>20), (long long)(mstats.heap_idle>>20), (long long)(mstats.heap_sys>>20), + (long long)(mstats.heap_released>>20), (long long)((mstats.heap_sys - mstats.heap_released)>>20)); + } + } } // Initialize a new span with the given start and npages. @@ -333,6 +417,8 @@ runtime_MSpan_Init(MSpan *span, PageID start, uintptr npages) span->ref = 0; span->sizeclass = 0; span->state = 0; + span->unusedsince = 0; + span->npreleased = 0; } // Initialize an empty doubly-linked list. diff --git a/libgo/runtime/mprof.goc b/libgo/runtime/mprof.goc index d143d19e5ba..c61c65ccee3 100644 --- a/libgo/runtime/mprof.goc +++ b/libgo/runtime/mprof.goc @@ -26,6 +26,10 @@ struct Bucket uintptr frees; uintptr alloc_bytes; uintptr free_bytes; + uintptr recent_allocs; // since last gc + uintptr recent_frees; + uintptr recent_alloc_bytes; + uintptr recent_free_bytes; uintptr hash; uintptr nstk; uintptr stk[1]; @@ -39,7 +43,7 @@ static uintptr bucketmem; // Return the bucket for stk[0:nstk], allocating new bucket if needed. static Bucket* -stkbucket(uintptr *stk, int32 nstk) +stkbucket(uintptr *stk, int32 nstk, bool alloc) { int32 i; uintptr h; @@ -66,6 +70,9 @@ stkbucket(uintptr *stk, int32 nstk) runtime_mcmp((byte*)b->stk, (byte*)stk, nstk*sizeof stk[0]) == 0) return b; + if(!alloc) + return nil; + b = runtime_mallocgc(sizeof *b + nstk*sizeof stk[0], FlagNoProfiling, 0, 1); bucketmem += sizeof *b + nstk*sizeof stk[0]; runtime_memmove(b->stk, stk, nstk*sizeof stk[0]); @@ -78,6 +85,26 @@ stkbucket(uintptr *stk, int32 nstk) return b; } +// Record that a gc just happened: all the 'recent' statistics are now real. +void +runtime_MProf_GC(void) +{ + Bucket *b; + + runtime_lock(&proflock); + for(b=buckets; b; b=b->allnext) { + b->allocs += b->recent_allocs; + b->frees += b->recent_frees; + b->alloc_bytes += b->recent_alloc_bytes; + b->free_bytes += b->recent_free_bytes; + b->recent_allocs = 0; + b->recent_frees = 0; + b->recent_alloc_bytes = 0; + b->recent_free_bytes = 0; + } + runtime_unlock(&proflock); +} + // Map from pointer to Bucket* that allocated it. // Three levels: // Linked-list hash table for top N-20 bits. @@ -198,15 +225,11 @@ runtime_MProf_Malloc(void *p, uintptr size) return; m->nomemprof++; -#if 0 nstk = runtime_callers(1, stk, 32); -#else - nstk = 0; -#endif runtime_lock(&proflock); - b = stkbucket(stk, nstk); - b->allocs++; - b->alloc_bytes += size; + b = stkbucket(stk, nstk, true); + b->recent_allocs++; + b->recent_alloc_bytes += size; setaddrbucket((uintptr)p, b); runtime_unlock(&proflock); m = runtime_m(); @@ -228,8 +251,8 @@ runtime_MProf_Free(void *p, uintptr size) runtime_lock(&proflock); b = getaddrbucket((uintptr)p); if(b != nil) { - b->frees++; - b->free_bytes += size; + b->recent_frees++; + b->recent_free_bytes += size; } runtime_unlock(&proflock); m = runtime_m(); @@ -240,7 +263,7 @@ runtime_MProf_Free(void *p, uintptr size) // Go interface to profile data. (Declared in extern.go) // Assumes Go sizeof(int) == sizeof(int32) -// Must match MemProfileRecord in extern.go. +// Must match MemProfileRecord in debug.go. typedef struct Record Record; struct Record { int64 alloc_bytes, free_bytes; @@ -292,3 +315,114 @@ runtime_MProf_Mark(void (*scan)(byte *, int64)) scan((byte*)&addrhash, sizeof addrhash); scan((byte*)&addrfree, sizeof addrfree); } + +// Must match StackRecord in debug.go. +typedef struct TRecord TRecord; +struct TRecord { + uintptr stk[32]; +}; + +func ThreadCreateProfile(p Slice) (n int32, ok bool) { + TRecord *r; + M *first, *m; + + first = runtime_atomicloadp(&runtime_allm); + n = 0; + for(m=first; m; m=m->alllink) + n++; + ok = false; + if(n <= p.__count) { + ok = true; + r = (TRecord*)p.__values; + for(m=first; m; m=m->alllink) { + runtime_memmove(r->stk, m->createstack, sizeof r->stk); + r++; + } + } +} + +func Stack(b Slice, all bool) (n int32) { + byte *pc, *sp; + + sp = runtime_getcallersp(&b); + pc = runtime_getcallerpc(&b); + + if(all) { + runtime_semacquire(&runtime_worldsema); + runtime_m()->gcing = 1; + runtime_stoptheworld(); + } + + if(b.__count == 0) + n = 0; + else{ + G* g = runtime_g(); + g->writebuf = (byte*)b.__values; + g->writenbuf = b.__count; + USED(pc); + USED(sp); + // runtime_goroutineheader(g); + // runtime_traceback(pc, sp, 0, g); + // if(all) + // runtime_tracebackothers(g); + n = b.__count - g->writenbuf; + g->writebuf = nil; + g->writenbuf = 0; + } + + if(all) { + runtime_m()->gcing = 0; + runtime_semrelease(&runtime_worldsema); + runtime_starttheworld(false); + } +} + +static void +saveg(byte *pc, byte *sp, G *g, TRecord *r) +{ + int32 n; + + USED(pc); + USED(sp); + USED(g); + // n = runtime_gentraceback(pc, sp, 0, g, 0, r->stk, nelem(r->stk)); + n = 0; + if((size_t)n < nelem(r->stk)) + r->stk[n] = 0; +} + +func GoroutineProfile(b Slice) (n int32, ok bool) { + byte *pc, *sp; + TRecord *r; + G *gp; + + sp = runtime_getcallersp(&b); + pc = runtime_getcallerpc(&b); + + ok = false; + n = runtime_gcount(); + if(n <= b.__count) { + runtime_semacquire(&runtime_worldsema); + runtime_m()->gcing = 1; + runtime_stoptheworld(); + + n = runtime_gcount(); + if(n <= b.__count) { + G* g = runtime_g(); + ok = true; + r = (TRecord*)b.__values; + saveg(pc, sp, g, r++); + for(gp = runtime_allg; gp != nil; gp = gp->alllink) { + if(gp == g || gp->status == Gdead) + continue; + //saveg(gp->sched.pc, gp->sched.sp, gp, r++); + r++; + } + } + + runtime_m()->gcing = 0; + runtime_semrelease(&runtime_worldsema); + runtime_starttheworld(false); + } +} + diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index d7e1e5ff405..31e8287e704 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -362,6 +362,9 @@ runtime_mcall(void (*pfn)(G*)) } } +// Keep trace of scavenger's goroutine for deadlock detection. +static G *scvg; + // The bootstrap sequence is: // // call osinit @@ -430,6 +433,7 @@ runtime_main(void) // to preserve the lock. runtime_LockOSThread(); runtime_sched.init = true; + scvg = __go_go(runtime_MHeap_Scavenger, nil); main_init(); runtime_sched.init = false; if(!runtime_sched.lockmain) @@ -536,18 +540,20 @@ runtime_idlegoroutine(void) static void mcommoninit(M *m) { - // Add to runtime_allm so garbage collector doesn't free m - // when it is just in a register or thread-local storage. - m->alllink = runtime_allm; - // runtime_Cgocalls() iterates over allm w/o schedlock, - // so we need to publish it safely. - runtime_atomicstorep((void**)&runtime_allm, m); - m->id = runtime_sched.mcount++; m->fastrand = 0x49f6428aUL + m->id + runtime_cputicks(); if(m->mcache == nil) m->mcache = runtime_allocmcache(); + + runtime_callers(1, m->createstack, nelem(m->createstack)); + + // Add to runtime_allm so garbage collector doesn't free m + // when it is just in a register or thread-local storage. + m->alllink = runtime_allm; + // runtime_NumCgoCall() iterates over allm w/o schedlock, + // so we need to publish it safely. + runtime_atomicstorep(&runtime_allm, m); } // Try to increment mcpu. Report whether succeeded. @@ -784,9 +790,13 @@ top: mput(m); } - v = runtime_atomicload(&runtime_sched.atomic); - if(runtime_sched.grunning == 0) + // Look for deadlock situation. + if((scvg == nil && runtime_sched.grunning == 0) || + (scvg != nil && runtime_sched.grunning == 1 && runtime_sched.gwait == 0 && + (scvg->status == Grunning || scvg->status == Gsyscall))) { runtime_throw("all goroutines are asleep - deadlock!"); + } + m->nextg = nil; m->waitnextg = 1; runtime_noteclear(&m->havenextg); @@ -795,6 +805,7 @@ top: // Entersyscall might have decremented mcpu too, but if so // it will see the waitstop and take the slow path. // Exitsyscall never increments mcpu beyond mcpumax. + v = runtime_atomicload(&runtime_sched.atomic); if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) { // set waitstop = 0 (known to be 1) runtime_xadd(&runtime_sched.atomic, -1<<waitstopShift); @@ -1124,6 +1135,9 @@ runtime_entersyscall(void) { uint32 v; + if(m->profilehz > 0) + runtime_setprof(false); + // Leave SP around for gc and traceback. #ifdef USING_SPLIT_STACK g->gcstack = __splitstack_find(NULL, NULL, &g->gcstack_size, @@ -1194,6 +1208,9 @@ runtime_exitsyscall(void) #endif gp->gcnext_sp = nil; runtime_memclr(gp->gcregs, sizeof gp->gcregs); + + if(m->profilehz > 0) + runtime_setprof(true); return; } @@ -1470,11 +1487,17 @@ runtime_mid() return m->id; } -int32 runtime_Goroutines (void) - __asm__ ("libgo_runtime.runtime.Goroutines"); +int32 runtime_NumGoroutine (void) + __asm__ ("libgo_runtime.runtime.NumGoroutine"); + +int32 +runtime_NumGoroutine() +{ + return runtime_sched.gcount; +} int32 -runtime_Goroutines() +runtime_gcount(void) { return runtime_sched.gcount; } diff --git a/libgo/runtime/reflect.goc b/libgo/runtime/reflect.goc index d3cde7c0e5b..447b786a8d8 100644 --- a/libgo/runtime/reflect.goc +++ b/libgo/runtime/reflect.goc @@ -17,10 +17,10 @@ func ifaceE2I(inter *Type, e Eface, ret *Iface) { t = e.__type_descriptor; if(t == nil) { // explicit conversions require non-nil interface value. - newTypeAssertionError(nil, nil, inter, + runtime_newTypeAssertionError( nil, nil, inter->__reflection, nil, &err); - __go_panic(err); + runtime_panic(err); } ret->__object = e.__object; ret->__methods = __go_convert_interface(inter, t); diff --git a/libgo/runtime/runtime.c b/libgo/runtime/runtime.c index 7c8c436deeb..d1ce26db499 100644 --- a/libgo/runtime/runtime.c +++ b/libgo/runtime/runtime.c @@ -184,6 +184,21 @@ runtime_fastrand1(void) return x; } +static struct root_list runtime_roots = +{ NULL, + { { &syscall_Envs, sizeof syscall_Envs }, + { &os_Args, sizeof os_Args }, + { NULL, 0 } }, +}; + +void +runtime_check(void) +{ + __go_register_gc_roots(&runtime_roots); + + runtime_initsig (); +} + int64 runtime_cputicks(void) { @@ -196,22 +211,3 @@ runtime_cputicks(void) return 0; #endif } - -struct funcline_go_return -{ - String retfile; - int32 retline; -}; - -struct funcline_go_return -runtime_funcline_go(void *f, uintptr targetpc) - __asm__("libgo_runtime.runtime.funcline_go"); - -struct funcline_go_return -runtime_funcline_go(void *f __attribute__((unused)), - uintptr targetpc __attribute__((unused))) -{ - struct funcline_go_return ret; - runtime_memclr(&ret, sizeof ret); - return ret; -} diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 41b0ef5f007..e012e1833bb 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -48,6 +48,7 @@ typedef unsigned int uintptr __attribute__ ((mode (pointer))); typedef uint8 bool; typedef uint8 byte; +typedef struct Func Func; typedef struct G G; typedef union Lock Lock; typedef struct M M; @@ -143,6 +144,8 @@ struct G M* lockedm; M* idlem; // int32 sig; + int32 writenbuf; + byte* writebuf; // uintptr sigcode0; // uintptr sigcode1; // uintptr sigpc; @@ -174,6 +177,7 @@ struct M MCache *mcache; G* lockedg; G* idleg; + uintptr createstack[32]; // Stack that created this thread. M* nextwaitm; // next M waiting for lock uintptr waitsema; // semaphore for parking on locks uint32 waitsemacount; @@ -187,11 +191,23 @@ struct SigTab }; enum { - SigCatch = 1<<0, - SigIgnore = 1<<1, - SigRestart = 1<<2, - SigQueue = 1<<3, - SigPanic = 1<<4, + SigNotify = 1<<0, // let signal.Notify have signal, even if from kernel + SigKill = 1<<1, // if signal.Notify doesn't take it, exit quietly + SigThrow = 1<<2, // if signal.Notify doesn't take it, exit loudly + SigPanic = 1<<3, // if the signal is from the kernel, panic + SigDefault = 1<<4, // if the signal isn't explicitly requested, don't monitor it +}; + +#ifndef NSIG +#define NSIG 32 +#endif + +// NOTE(rsc): keep in sync with extern.go:/type.Func. +// Eventually, the loaded symbol table should be closer to this form. +struct Func +{ + String name; + uintptr entry; // entry pc }; /* Macros. */ @@ -271,7 +287,8 @@ void runtime_throw(const char*) __attribute__ ((noreturn)); void runtime_panicstring(const char*) __attribute__ ((noreturn)); void* runtime_mal(uintptr); void runtime_schedinit(void); -void runtime_initsig(int32); +void runtime_initsig(void); +void runtime_sigenable(uint32 sig); String runtime_gostringnocopy(const byte*); void* runtime_mstart(void*); G* runtime_malg(int32, byte**, size_t*); @@ -285,11 +302,13 @@ void runtime_entersyscall(void) __asm__("libgo_syscall.syscall.entersyscall"); void runtime_exitsyscall(void) __asm__("libgo_syscall.syscall.exitsyscall"); void siginit(void); bool __go_sigsend(int32 sig); +int32 runtime_callers(int32, uintptr*, int32); int64 runtime_nanotime(void); int64 runtime_cputicks(void); void runtime_stoptheworld(void); void runtime_starttheworld(bool); +extern uint32 runtime_worldsema; G* __go_go(void (*pfn)(void*), void*); /* @@ -336,9 +355,26 @@ void runtime_futexsleep(uint32*, uint32, int64); void runtime_futexwakeup(uint32*, uint32); /* + * low level C-called + */ +#define runtime_mmap mmap +#define runtime_munmap munmap +#define runtime_madvise madvise +#define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size)) +#define runtime_getcallerpc(p) __builtin_return_address(0) + +#ifdef __rtems__ +void __wrap_rtems_task_variable_add(void **); +#endif + +/* * runtime go-called */ void runtime_panic(Eface); +struct __go_func_type; +void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool, + void **, void **) + asm ("libgo_reflect.reflect.call"); /* Functions. */ #define runtime_panic __go_panic @@ -348,11 +384,9 @@ void runtime_panic(Eface); #define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2)) #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s)) #define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s)) -#define runtime_exit(s) _exit(s) +#define runtime_exit(s) exit(s) MCache* runtime_allocmcache(void); void free(void *v); -struct __go_func_type; -bool runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type *); #define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) #define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) #define runtime_xadd(p, v) __sync_add_and_fetch (p, v) @@ -362,6 +396,11 @@ bool runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type * #define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) #define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) +struct __go_func_type; +bool runtime_addfinalizer(void*, void(*fn)(void*), const struct __go_func_type *); +#define runtime_getcallersp(p) __builtin_frame_address(1) +int32 runtime_mcount(void); +int32 runtime_gcount(void); void runtime_dopanic(int32) __attribute__ ((noreturn)); void runtime_startpanic(void); void runtime_ready(G*); @@ -374,29 +413,55 @@ void runtime_resetcpuprofiler(int32); void runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32); void runtime_usleep(uint32); +/* + * runtime c-called (but written in Go) + */ +void runtime_newError(String, Eface*); +void runtime_printany(Eface) + __asm__("libgo_runtime.runtime.Printany"); +void runtime_newTypeAssertionError(const String*, const String*, const String*, const String*, Eface*) + __asm__("libgo_runtime.runtime.NewTypeAssertionError"); +void runtime_newErrorString(String, Eface*) + __asm__("libgo_runtime.runtime.NewErrorString"); + +/* + * wrapped for go users + */ void runtime_semacquire(uint32 volatile *); void runtime_semrelease(uint32 volatile *); +String runtime_signame(int32 sig); int32 runtime_gomaxprocsfunc(int32 n); void runtime_procyield(uint32); void runtime_osyield(void); void runtime_LockOSThread(void) __asm__("libgo_runtime.runtime.LockOSThread"); void runtime_UnlockOSThread(void) __asm__("libgo_runtime.runtime.UnlockOSThread"); -/* - * low level C-called - */ -#define runtime_mmap mmap -#define runtime_munmap munmap -#define runtime_madvise madvise -#define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size)) +uintptr runtime_memlimit(void); -struct __go_func_type; -void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool, - void **, void **) - asm ("libgo_reflect.reflect.call"); - -#ifdef __rtems__ -void __wrap_rtems_task_variable_add(void **); -#endif +// If appropriate, ask the operating system to control whether this +// thread should receive profiling signals. This is only necessary on OS X. +// An operating system should not deliver a profiling signal to a +// thread that is not actually executing (what good is that?), but that's +// what OS X prefers to do. When profiling is turned on, we mask +// away the profiling signal when threads go to sleep, so that OS X +// is forced to deliver the signal to a thread that's actually running. +// This is a no-op on other systems. +void runtime_setprof(bool); void runtime_time_scan(void (*)(byte*, int64)); + +void runtime_setsig(int32, bool, bool); +#define runtime_setitimer setitimer + +void runtime_check(void); + +// A list of global variables that the garbage collector must scan. +struct root_list { + struct root_list *next; + struct root { + void *decl; + size_t size; + } roots[]; +}; + +void __go_register_gc_roots(struct root_list*); diff --git a/libgo/runtime/sema.goc b/libgo/runtime/sema.goc index dd58cf38fb8..ff9c4f2e19e 100644 --- a/libgo/runtime/sema.goc +++ b/libgo/runtime/sema.goc @@ -17,7 +17,7 @@ // See Mullender and Cox, ``Semaphores in Plan 9,'' // http://swtch.com/semaphore.pdf -package runtime +package sync #include "runtime.h" #include "arch.h" @@ -172,10 +172,10 @@ runtime_semrelease(uint32 volatile *addr) runtime_ready(s->g); } -func Semacquire(addr *uint32) { +func runtime_Semacquire(addr *uint32) { runtime_semacquire(addr); } -func Semrelease(addr *uint32) { +func runtime_Semrelease(addr *uint32) { runtime_semrelease(addr); } diff --git a/libgo/runtime/signal_unix.c b/libgo/runtime/signal_unix.c new file mode 100644 index 00000000000..3b8f4393708 --- /dev/null +++ b/libgo/runtime/signal_unix.c @@ -0,0 +1,64 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd linux openbsd netbsd + +#include <sys/time.h> + +#include "runtime.h" +#include "defs.h" + +extern SigTab runtime_sigtab[]; + +void +runtime_initsig(void) +{ + int32 i; + SigTab *t; + + // First call: basic setup. + for(i = 0; runtime_sigtab[i].sig != -1; i++) { + t = &runtime_sigtab[i]; + if((t->flags == 0) || (t->flags & SigDefault)) + continue; + runtime_setsig(i, false, true); + } +} + +void +runtime_sigenable(uint32 sig) +{ + int32 i; + SigTab *t; + + for(i = 0; runtime_sigtab[i].sig != -1; i++) { + // ~0 means all signals. + if(~sig == 0 || runtime_sigtab[i].sig == (int32)sig) { + t = &runtime_sigtab[i]; + if(t->flags & SigDefault) { + runtime_setsig(i, false, true); + t->flags &= ~SigDefault; // make this idempotent + } + } + } +} + +void +runtime_resetcpuprofiler(int32 hz) +{ + struct itimerval it; + + runtime_memclr((byte*)&it, sizeof it); + if(hz == 0) { + runtime_setitimer(ITIMER_PROF, &it, nil); + runtime_setprof(false); + } else { + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 1000000 / hz; + it.it_value = it.it_interval; + runtime_setitimer(ITIMER_PROF, &it, nil); + runtime_setprof(true); + } + runtime_m()->profilehz = hz; +} diff --git a/libgo/runtime/sigqueue.goc b/libgo/runtime/sigqueue.goc index e91571902c0..be7c5920cbc 100644 --- a/libgo/runtime/sigqueue.goc +++ b/libgo/runtime/sigqueue.goc @@ -11,7 +11,7 @@ // // Ownership for sig.Note passes back and forth between // the signal handler and the signal goroutine in rounds. -// The initial state is that sig.note is cleared (setup by siginit). +// The initial state is that sig.note is cleared (setup by signal_enable). // At the beginning of each round, mask == 0. // The round goes through three stages: // @@ -36,7 +36,7 @@ // ownership by returning from notesleep (caused by the notewakeup) // and gives up ownership by clearing mask. -package runtime +package signal #include "config.h" #include "runtime.h" #include "arch.h" @@ -45,33 +45,29 @@ package runtime static struct { Note; - uint32 mask; + uint32 mask[(NSIG+31)/32]; + uint32 wanted[(NSIG+31)/32]; + uint32 kick; bool inuse; } sig; -void -siginit(void) -{ - runtime_noteclear(&sig); -} - // Called from sighandler to send a signal back out of the signal handling thread. bool __go_sigsend(int32 s) { uint32 bit, mask; - if(!sig.inuse) + if(!sig.inuse || s < 0 || (size_t)s >= 32*nelem(sig.wanted) || !(sig.wanted[s/32]&(1U<<(s&31)))) return false; - bit = 1 << s; + bit = 1 << (s&31); for(;;) { - mask = sig.mask; + mask = sig.mask[s/32]; if(mask & bit) break; // signal already in queue - if(runtime_cas(&sig.mask, mask, mask|bit)) { + if(runtime_cas(&sig.mask[s/32], mask, mask|bit)) { // Added to queue. - // Only send a wakeup for the first signal in each round. - if(mask == 0) + // Only send a wakeup if the receiver needs a kick. + if(runtime_cas(&sig.kick, 1, 0)) runtime_notewakeup(&sig); break; } @@ -79,37 +75,79 @@ __go_sigsend(int32 s) return true; } -// Called to receive a bitmask of queued signals. -func Sigrecv() (m uint32) { - runtime_entersyscall(); - runtime_notesleep(&sig); - runtime_exitsyscall(); - runtime_noteclear(&sig); +// Called to receive the next queued signal. +// Must only be called from a single goroutine at a time. +func signal_recv() (m uint32) { + static uint32 recv[nelem(sig.mask)]; + int32 i, more; + for(;;) { - m = sig.mask; - if(runtime_cas(&sig.mask, m, 0)) - break; + // Serve from local copy if there are bits left. + for(i=0; i<NSIG; i++) { + if(recv[i/32]&(1U<<(i&31))) { + recv[i/32] ^= 1U<<(i&31); + m = i; + goto done; + } + } + + // Get a new local copy. + // Ask for a kick if more signals come in + // during or after our check (before the sleep). + if(sig.kick == 0) { + runtime_noteclear(&sig); + runtime_cas(&sig.kick, 0, 1); + } + + more = 0; + for(i=0; (size_t)i<nelem(sig.mask); i++) { + for(;;) { + m = sig.mask[i]; + if(runtime_cas(&sig.mask[i], m, 0)) + break; + } + recv[i] = m; + if(m != 0) + more = 1; + } + if(more) + continue; + + // Sleep waiting for more. + runtime_entersyscall(); + runtime_notesleep(&sig); + runtime_exitsyscall(); } + +done:; + // goc requires that we fall off the end of functions + // that return values instead of using our own return + // statements. } -func Signame(sig int32) (name String) { - const char* s = NULL; - char buf[100]; -#if defined(HAVE_STRSIGNAL) - s = strsignal(sig); -#endif - if (s == NULL) { - snprintf(buf, sizeof buf, "signal %d", sig); - s = buf; +// Must only be called from a single goroutine at a time. +func signal_enable(s uint32) { + int32 i; + + if(!sig.inuse) { + // The first call to signal_enable is for us + // to use for initialization. It does not pass + // signal information in m. + sig.inuse = true; // enable reception of signals; cannot disable + runtime_noteclear(&sig); + return; + } + + if(~s == 0) { + // Special case: want everything. + for(i=0; (size_t)i<nelem(sig.wanted); i++) + sig.wanted[i] = ~(uint32)0; + runtime_sigenable(s); + return; } - int32 len = __builtin_strlen(s); - unsigned char *data = runtime_mallocgc(len, FlagNoPointers, 0, 0); - __builtin_memcpy(data, s, len); - name.__data = data; - name.__length = len; -} -func Siginit() { - runtime_initsig(SigQueue); - sig.inuse = true; // enable reception of signals; cannot disable + if(s >= nelem(sig.wanted)*32) + return; + sig.wanted[s/32] |= 1U<<(s&31); + runtime_sigenable(s); } diff --git a/libgo/runtime/thread-linux.c b/libgo/runtime/thread-linux.c index 8dd5fc4b481..6a69fb429a4 100644 --- a/libgo/runtime/thread-linux.c +++ b/libgo/runtime/thread-linux.c @@ -3,6 +3,16 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "defs.h" + +// Linux futex. +// +// futexsleep(uint32 *addr, uint32 val) +// futexwakeup(uint32 *addr) +// +// Futexsleep atomically checks if *addr == val and if so, sleeps on addr. +// Futexwakeup wakes up threads sleeping on addr. +// Futexsleep is allowed to wake up spuriously. #include <errno.h> #include <string.h> diff --git a/libgo/runtime/thread.c b/libgo/runtime/thread.c index 748a62d59f5..12d009926e3 100644 --- a/libgo/runtime/thread.c +++ b/libgo/runtime/thread.c @@ -4,6 +4,8 @@ #include <errno.h> #include <signal.h> +#include <sys/time.h> +#include <sys/resource.h> #include "runtime.h" #include "go-assert.h" @@ -138,6 +140,7 @@ runtime_minit(void) byte* stack; size_t stacksize; stack_t ss; + sigset_t sigs; // Initialize signal handling. runtime_m()->gsignal = runtime_malg(32*1024, &stack, &stacksize); // OS X wants >=8K, Linux >=2K @@ -146,4 +149,34 @@ runtime_minit(void) ss.ss_size = stacksize; if(sigaltstack(&ss, nil) < 0) *(int *)0xf1 = 0xf1; + if (sigemptyset(&sigs) != 0) + runtime_throw("sigemptyset"); + sigprocmask(SIG_SETMASK, &sigs, nil); +} + +uintptr +runtime_memlimit(void) +{ + struct rlimit rl; + uintptr used; + + if(getrlimit(RLIMIT_AS, &rl) != 0) + return 0; + if(rl.rlim_cur >= 0x7fffffff) + return 0; + + // Estimate our VM footprint excluding the heap. + // Not an exact science: use size of binary plus + // some room for thread stacks. + used = (64<<20); + if(used >= rl.rlim_cur) + return 0; + + // If there's not at least 16 MB left, we're probably + // not going to be able to do much. Treat as no limit. + rl.rlim_cur -= used; + if(rl.rlim_cur < (16<<20)) + return 0; + + return rl.rlim_cur - used; } |