From 2042488d202f85ffd6b2c6c9a9bbe84e6099c85e Mon Sep 17 00:00:00 2001 From: Kevin Schoon Date: Tue, 30 Jan 2018 21:23:53 -0500 Subject: [PATCH] fix out of date dependencies --- Gopkg.lock | 32 +- Gopkg.toml | 4 - vendor/github.com/gizak/termui/.gitignore | 26 + vendor/github.com/gizak/termui/.travis.yml | 6 + vendor/github.com/gizak/termui/LICENSE | 22 + vendor/github.com/gizak/termui/README.md | 151 + vendor/github.com/gizak/termui/barchart.go | 149 + vendor/github.com/gizak/termui/block.go | 240 ++ .../github.com/gizak/termui/block_common.go | 20 + vendor/github.com/gizak/termui/block_test.go | 72 + .../github.com/gizak/termui/block_windows.go | 14 + vendor/github.com/gizak/termui/buffer.go | 106 + vendor/github.com/gizak/termui/buffer_test.go | 23 + vendor/github.com/gizak/termui/canvas.go | 72 + vendor/github.com/gizak/termui/canvas_test.go | 57 + vendor/github.com/gizak/termui/config.py | 54 + vendor/github.com/gizak/termui/doc.go | 29 + vendor/github.com/gizak/termui/events.go | 323 ++ vendor/github.com/gizak/termui/events_test.go | 37 + vendor/github.com/gizak/termui/gauge.go | 109 + vendor/github.com/gizak/termui/glide.lock | 30 + vendor/github.com/gizak/termui/glide.yaml | 9 + vendor/github.com/gizak/termui/grid.go | 279 ++ vendor/github.com/gizak/termui/grid_test.go | 80 + vendor/github.com/gizak/termui/helper.go | 222 ++ vendor/github.com/gizak/termui/helper_test.go | 70 + vendor/github.com/gizak/termui/linechart.go | 331 ++ .../gizak/termui/linechart_others.go | 11 + .../gizak/termui/linechart_windows.go | 11 + vendor/github.com/gizak/termui/list.go | 89 + vendor/github.com/gizak/termui/mbarchart.go | 242 ++ vendor/github.com/gizak/termui/mkdocs.yml | 28 + vendor/github.com/gizak/termui/par.go | 73 + vendor/github.com/gizak/termui/par_test.go | 24 + vendor/github.com/gizak/termui/pos.go | 78 + vendor/github.com/gizak/termui/pos_test.go | 38 + vendor/github.com/gizak/termui/render.go | 164 + vendor/github.com/gizak/termui/sparkline.go | 167 + vendor/github.com/gizak/termui/table.go | 185 ++ vendor/github.com/gizak/termui/textbuilder.go | 278 ++ .../gizak/termui/textbuilder_test.go | 70 + vendor/github.com/gizak/termui/theme.go | 140 + vendor/github.com/gizak/termui/theme_test.go | 35 + vendor/github.com/gizak/termui/widget.go | 94 + vendor/github.com/gosuri/uilive/.travis.yml | 7 - vendor/github.com/gosuri/uilive/LICENSE | 10 - vendor/github.com/gosuri/uilive/README.md | 31 - vendor/github.com/gosuri/uilive/doc.go | 2 - .../github.com/gosuri/uilive/doc/example.gif | Bin 159491 -> 0 bytes .../github.com/gosuri/uilive/example/main.go | 26 - .../github.com/gosuri/uilive/example_test.go | 23 - vendor/github.com/gosuri/uilive/writer.go | 138 - .../github.com/gosuri/uilive/writer_posix.go | 14 - .../github.com/gosuri/uilive/writer_test.go | 24 - .../gosuri/uilive/writer_windows.go | 74 - .../jawher/mow.cli/testdata/help-output.txt | 45 - .../mow.cli/testdata/long-help-output.txt | 10 - .../github.com/maruel/panicparse/.travis.yml | 16 + .../github.com/maruel/panicparse/Gopkg.lock | 57 + .../github.com/maruel/panicparse/Gopkg.toml | 38 + vendor/github.com/maruel/panicparse/LICENSE | 201 ++ vendor/github.com/maruel/panicparse/README.md | 139 + vendor/github.com/maruel/panicparse/main.go | 31 + .../maruel/panicparse/stack/source.go | 302 ++ .../maruel/panicparse/stack/source_test.go | 563 ++++ .../maruel/panicparse/stack/stack.go | 832 +++++ .../maruel/panicparse/stack/stack_test.go | 1018 +++++++ .../github.com/maruel/panicparse/stack/ui.go | 139 + .../maruel/panicparse/stack/ui_test.go | 149 + .../go-colorable/_example/escape-seq/main.go | 16 - .../go-colorable/_example/logrus/main.go | 16 - .../mattn/go-colorable/_example/title/main.go | 14 - .../github.com/mattn/go-runewidth/.travis.yml | 8 + vendor/github.com/mattn/go-runewidth/LICENSE | 21 + .../github.com/mattn/go-runewidth/README.mkd | 27 + .../mattn/go-runewidth/runewidth.go | 1223 ++++++++ .../mattn/go-runewidth/runewidth_js.go | 8 + .../mattn/go-runewidth/runewidth_posix.go | 77 + .../mattn/go-runewidth/runewidth_test.go | 275 ++ .../mattn/go-runewidth/runewidth_windows.go | 25 + .../go-sqlite3/_example/custom_func/main.go | 133 - .../mattn/go-sqlite3/_example/hook/hook.go | 78 - .../mattn/go-sqlite3/_example/limit/limit.go | 113 - .../go-sqlite3/_example/mod_regexp/Makefile | 22 - .../_example/mod_regexp/extension.go | 43 - .../_example/mod_regexp/sqlite3_mod_regexp.c | 31 - .../go-sqlite3/_example/mod_vtable/Makefile | 24 - .../_example/mod_vtable/extension.go | 37 - .../go-sqlite3/_example/mod_vtable/picojson.h | 1040 ------- .../_example/mod_vtable/sqlite3_mod_vtable.cc | 238 -- .../go-sqlite3/_example/simple/simple.go | 106 - .../mattn/go-sqlite3/_example/trace/main.go | 264 -- .../mattn/go-sqlite3/_example/vtable/main.go | 38 - .../go-sqlite3/_example/vtable/vtable.go | 111 - .../mattn/go-sqlite3/tool/upgrade.go | 111 - .../mitchellh/go-wordwrap/LICENSE.md | 21 + .../mitchellh/go-wordwrap/README.md | 39 + .../mitchellh/go-wordwrap/wordwrap.go | 73 + .../mitchellh/go-wordwrap/wordwrap_test.go | 85 + vendor/github.com/nsf/termbox-go/AUTHORS | 4 + vendor/github.com/nsf/termbox-go/LICENSE | 19 + vendor/github.com/nsf/termbox-go/README.md | 39 + vendor/github.com/nsf/termbox-go/api.go | 489 +++ .../github.com/nsf/termbox-go/api_common.go | 187 ++ .../github.com/nsf/termbox-go/api_windows.go | 239 ++ .../nsf/termbox-go/collect_terminfo.py | 110 + vendor/github.com/nsf/termbox-go/escwait.go | 11 + .../nsf/termbox-go/escwait_darwin.go | 9 + vendor/github.com/nsf/termbox-go/syscalls.go | 39 + .../nsf/termbox-go/syscalls_darwin.go | 41 + .../nsf/termbox-go/syscalls_darwin_amd64.go | 40 + .../nsf/termbox-go/syscalls_dragonfly.go | 39 + .../nsf/termbox-go/syscalls_freebsd.go | 39 + .../nsf/termbox-go/syscalls_linux.go | 33 + .../nsf/termbox-go/syscalls_netbsd.go | 39 + .../nsf/termbox-go/syscalls_openbsd.go | 39 + .../nsf/termbox-go/syscalls_windows.go | 61 + vendor/github.com/nsf/termbox-go/termbox.go | 529 ++++ .../nsf/termbox-go/termbox_common.go | 59 + .../nsf/termbox-go/termbox_windows.go | 889 ++++++ vendor/github.com/nsf/termbox-go/terminfo.go | 221 ++ .../nsf/termbox-go/terminfo_builtin.go | 64 + vendor/golang.org/x/sys/plan9/asm.s | 8 - vendor/golang.org/x/sys/plan9/asm_plan9_386.s | 30 - .../golang.org/x/sys/plan9/asm_plan9_amd64.s | 30 - vendor/golang.org/x/sys/plan9/const_plan9.go | 70 - vendor/golang.org/x/sys/plan9/dir_plan9.go | 212 -- vendor/golang.org/x/sys/plan9/env_plan9.go | 31 - vendor/golang.org/x/sys/plan9/errors_plan9.go | 50 - vendor/golang.org/x/sys/plan9/mkall.sh | 138 - vendor/golang.org/x/sys/plan9/mkerrors.sh | 246 -- vendor/golang.org/x/sys/plan9/mksyscall.pl | 319 -- .../golang.org/x/sys/plan9/mksysnum_plan9.sh | 23 - .../golang.org/x/sys/plan9/pwd_go15_plan9.go | 21 - vendor/golang.org/x/sys/plan9/pwd_plan9.go | 23 - vendor/golang.org/x/sys/plan9/race.go | 30 - vendor/golang.org/x/sys/plan9/race0.go | 25 - vendor/golang.org/x/sys/plan9/str.go | 22 - vendor/golang.org/x/sys/plan9/syscall.go | 74 - .../golang.org/x/sys/plan9/syscall_plan9.go | 349 --- vendor/golang.org/x/sys/plan9/syscall_test.go | 33 - .../x/sys/plan9/zsyscall_plan9_386.go | 292 -- .../x/sys/plan9/zsyscall_plan9_amd64.go | 292 -- .../golang.org/x/sys/plan9/zsysnum_plan9.go | 49 - vendor/golang.org/x/sys/unix/linux/Dockerfile | 51 - vendor/golang.org/x/sys/unix/linux/mkall.go | 482 --- .../golang.org/x/sys/unix/linux/mksysnum.pl | 85 - vendor/golang.org/x/sys/unix/linux/types.go | 645 ---- .../x/sys/windows/asm_windows_386.s | 13 - .../x/sys/windows/asm_windows_amd64.s | 13 - .../golang.org/x/sys/windows/dll_windows.go | 378 --- .../golang.org/x/sys/windows/env_windows.go | 29 - vendor/golang.org/x/sys/windows/eventlog.go | 20 - .../golang.org/x/sys/windows/exec_windows.go | 97 - .../x/sys/windows/memory_windows.go | 26 - vendor/golang.org/x/sys/windows/mksyscall.go | 7 - vendor/golang.org/x/sys/windows/race.go | 30 - vendor/golang.org/x/sys/windows/race0.go | 25 - .../x/sys/windows/registry/export_test.go | 11 - .../golang.org/x/sys/windows/registry/key.go | 200 -- .../x/sys/windows/registry/mksyscall.go | 7 - .../x/sys/windows/registry/registry_test.go | 756 ----- .../x/sys/windows/registry/syscall.go | 32 - .../x/sys/windows/registry/value.go | 384 --- .../sys/windows/registry/zsyscall_windows.go | 120 - .../x/sys/windows/security_windows.go | 476 --- vendor/golang.org/x/sys/windows/service.go | 164 - vendor/golang.org/x/sys/windows/str.go | 22 - .../golang.org/x/sys/windows/svc/debug/log.go | 56 - .../x/sys/windows/svc/debug/service.go | 45 - vendor/golang.org/x/sys/windows/svc/event.go | 48 - .../x/sys/windows/svc/eventlog/install.go | 80 - .../x/sys/windows/svc/eventlog/log.go | 70 - .../x/sys/windows/svc/eventlog/log_test.go | 51 - .../x/sys/windows/svc/example/beep.go | 22 - .../x/sys/windows/svc/example/install.go | 92 - .../x/sys/windows/svc/example/main.go | 76 - .../x/sys/windows/svc/example/manage.go | 62 - .../x/sys/windows/svc/example/service.go | 82 - vendor/golang.org/x/sys/windows/svc/go12.c | 24 - vendor/golang.org/x/sys/windows/svc/go12.go | 11 - vendor/golang.org/x/sys/windows/svc/go13.go | 31 - .../x/sys/windows/svc/mgr/config.go | 139 - .../golang.org/x/sys/windows/svc/mgr/mgr.go | 162 - .../x/sys/windows/svc/mgr/mgr_test.go | 169 -- .../x/sys/windows/svc/mgr/service.go | 72 - .../golang.org/x/sys/windows/svc/security.go | 62 - .../golang.org/x/sys/windows/svc/service.go | 363 --- .../golang.org/x/sys/windows/svc/svc_test.go | 118 - vendor/golang.org/x/sys/windows/svc/sys_386.s | 68 - .../golang.org/x/sys/windows/svc/sys_amd64.s | 42 - vendor/golang.org/x/sys/windows/syscall.go | 71 - .../golang.org/x/sys/windows/syscall_test.go | 53 - .../x/sys/windows/syscall_windows.go | 1153 ------- .../x/sys/windows/syscall_windows_test.go | 107 - .../golang.org/x/sys/windows/types_windows.go | 1333 -------- .../x/sys/windows/types_windows_386.go | 22 - .../x/sys/windows/types_windows_amd64.go | 22 - .../x/sys/windows/zsyscall_windows.go | 2687 ----------------- 199 files changed, 12892 insertions(+), 16680 deletions(-) create mode 100644 vendor/github.com/gizak/termui/.gitignore create mode 100644 vendor/github.com/gizak/termui/.travis.yml create mode 100644 vendor/github.com/gizak/termui/LICENSE create mode 100644 vendor/github.com/gizak/termui/README.md create mode 100644 vendor/github.com/gizak/termui/barchart.go create mode 100644 vendor/github.com/gizak/termui/block.go create mode 100644 vendor/github.com/gizak/termui/block_common.go create mode 100644 vendor/github.com/gizak/termui/block_test.go create mode 100644 vendor/github.com/gizak/termui/block_windows.go create mode 100644 vendor/github.com/gizak/termui/buffer.go create mode 100644 vendor/github.com/gizak/termui/buffer_test.go create mode 100644 vendor/github.com/gizak/termui/canvas.go create mode 100644 vendor/github.com/gizak/termui/canvas_test.go create mode 100644 vendor/github.com/gizak/termui/config.py create mode 100644 vendor/github.com/gizak/termui/doc.go create mode 100644 vendor/github.com/gizak/termui/events.go create mode 100644 vendor/github.com/gizak/termui/events_test.go create mode 100644 vendor/github.com/gizak/termui/gauge.go create mode 100644 vendor/github.com/gizak/termui/glide.lock create mode 100644 vendor/github.com/gizak/termui/glide.yaml create mode 100644 vendor/github.com/gizak/termui/grid.go create mode 100644 vendor/github.com/gizak/termui/grid_test.go create mode 100644 vendor/github.com/gizak/termui/helper.go create mode 100644 vendor/github.com/gizak/termui/helper_test.go create mode 100644 vendor/github.com/gizak/termui/linechart.go create mode 100644 vendor/github.com/gizak/termui/linechart_others.go create mode 100644 vendor/github.com/gizak/termui/linechart_windows.go create mode 100644 vendor/github.com/gizak/termui/list.go create mode 100644 vendor/github.com/gizak/termui/mbarchart.go create mode 100644 vendor/github.com/gizak/termui/mkdocs.yml create mode 100644 vendor/github.com/gizak/termui/par.go create mode 100644 vendor/github.com/gizak/termui/par_test.go create mode 100644 vendor/github.com/gizak/termui/pos.go create mode 100644 vendor/github.com/gizak/termui/pos_test.go create mode 100644 vendor/github.com/gizak/termui/render.go create mode 100644 vendor/github.com/gizak/termui/sparkline.go create mode 100644 vendor/github.com/gizak/termui/table.go create mode 100644 vendor/github.com/gizak/termui/textbuilder.go create mode 100644 vendor/github.com/gizak/termui/textbuilder_test.go create mode 100644 vendor/github.com/gizak/termui/theme.go create mode 100644 vendor/github.com/gizak/termui/theme_test.go create mode 100644 vendor/github.com/gizak/termui/widget.go delete mode 100644 vendor/github.com/gosuri/uilive/.travis.yml delete mode 100644 vendor/github.com/gosuri/uilive/LICENSE delete mode 100644 vendor/github.com/gosuri/uilive/README.md delete mode 100644 vendor/github.com/gosuri/uilive/doc.go delete mode 100644 vendor/github.com/gosuri/uilive/doc/example.gif delete mode 100644 vendor/github.com/gosuri/uilive/example/main.go delete mode 100644 vendor/github.com/gosuri/uilive/example_test.go delete mode 100644 vendor/github.com/gosuri/uilive/writer.go delete mode 100644 vendor/github.com/gosuri/uilive/writer_posix.go delete mode 100644 vendor/github.com/gosuri/uilive/writer_test.go delete mode 100644 vendor/github.com/gosuri/uilive/writer_windows.go delete mode 100644 vendor/github.com/jawher/mow.cli/testdata/help-output.txt delete mode 100644 vendor/github.com/jawher/mow.cli/testdata/long-help-output.txt create mode 100644 vendor/github.com/maruel/panicparse/.travis.yml create mode 100644 vendor/github.com/maruel/panicparse/Gopkg.lock create mode 100644 vendor/github.com/maruel/panicparse/Gopkg.toml create mode 100644 vendor/github.com/maruel/panicparse/LICENSE create mode 100644 vendor/github.com/maruel/panicparse/README.md create mode 100644 vendor/github.com/maruel/panicparse/main.go create mode 100644 vendor/github.com/maruel/panicparse/stack/source.go create mode 100644 vendor/github.com/maruel/panicparse/stack/source_test.go create mode 100644 vendor/github.com/maruel/panicparse/stack/stack.go create mode 100644 vendor/github.com/maruel/panicparse/stack/stack_test.go create mode 100644 vendor/github.com/maruel/panicparse/stack/ui.go create mode 100644 vendor/github.com/maruel/panicparse/stack/ui_test.go delete mode 100644 vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go delete mode 100644 vendor/github.com/mattn/go-colorable/_example/logrus/main.go delete mode 100644 vendor/github.com/mattn/go-colorable/_example/title/main.go create mode 100644 vendor/github.com/mattn/go-runewidth/.travis.yml create mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE create mode 100644 vendor/github.com/mattn/go-runewidth/README.mkd create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_test.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/limit/limit.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/trace/main.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go delete mode 100644 vendor/github.com/mattn/go-sqlite3/tool/upgrade.go create mode 100644 vendor/github.com/mitchellh/go-wordwrap/LICENSE.md create mode 100644 vendor/github.com/mitchellh/go-wordwrap/README.md create mode 100644 vendor/github.com/mitchellh/go-wordwrap/wordwrap.go create mode 100644 vendor/github.com/mitchellh/go-wordwrap/wordwrap_test.go create mode 100644 vendor/github.com/nsf/termbox-go/AUTHORS create mode 100644 vendor/github.com/nsf/termbox-go/LICENSE create mode 100644 vendor/github.com/nsf/termbox-go/README.md create mode 100644 vendor/github.com/nsf/termbox-go/api.go create mode 100644 vendor/github.com/nsf/termbox-go/api_common.go create mode 100644 vendor/github.com/nsf/termbox-go/api_windows.go create mode 100755 vendor/github.com/nsf/termbox-go/collect_terminfo.py create mode 100644 vendor/github.com/nsf/termbox-go/escwait.go create mode 100644 vendor/github.com/nsf/termbox-go/escwait_darwin.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_darwin.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_freebsd.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_linux.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_netbsd.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_openbsd.go create mode 100644 vendor/github.com/nsf/termbox-go/syscalls_windows.go create mode 100644 vendor/github.com/nsf/termbox-go/termbox.go create mode 100644 vendor/github.com/nsf/termbox-go/termbox_common.go create mode 100644 vendor/github.com/nsf/termbox-go/termbox_windows.go create mode 100644 vendor/github.com/nsf/termbox-go/terminfo.go create mode 100644 vendor/github.com/nsf/termbox-go/terminfo_builtin.go delete mode 100644 vendor/golang.org/x/sys/plan9/asm.s delete mode 100644 vendor/golang.org/x/sys/plan9/asm_plan9_386.s delete mode 100644 vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s delete mode 100644 vendor/golang.org/x/sys/plan9/const_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/dir_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/env_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/errors_plan9.go delete mode 100755 vendor/golang.org/x/sys/plan9/mkall.sh delete mode 100755 vendor/golang.org/x/sys/plan9/mkerrors.sh delete mode 100755 vendor/golang.org/x/sys/plan9/mksyscall.pl delete mode 100755 vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh delete mode 100644 vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/pwd_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/race.go delete mode 100644 vendor/golang.org/x/sys/plan9/race0.go delete mode 100644 vendor/golang.org/x/sys/plan9/str.go delete mode 100644 vendor/golang.org/x/sys/plan9/syscall.go delete mode 100644 vendor/golang.org/x/sys/plan9/syscall_plan9.go delete mode 100644 vendor/golang.org/x/sys/plan9/syscall_test.go delete mode 100644 vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go delete mode 100644 vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go delete mode 100644 vendor/golang.org/x/sys/plan9/zsysnum_plan9.go delete mode 100644 vendor/golang.org/x/sys/unix/linux/Dockerfile delete mode 100644 vendor/golang.org/x/sys/unix/linux/mkall.go delete mode 100755 vendor/golang.org/x/sys/unix/linux/mksysnum.pl delete mode 100644 vendor/golang.org/x/sys/unix/linux/types.go delete mode 100644 vendor/golang.org/x/sys/windows/asm_windows_386.s delete mode 100644 vendor/golang.org/x/sys/windows/asm_windows_amd64.s delete mode 100644 vendor/golang.org/x/sys/windows/dll_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/env_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/eventlog.go delete mode 100644 vendor/golang.org/x/sys/windows/exec_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/memory_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/mksyscall.go delete mode 100644 vendor/golang.org/x/sys/windows/race.go delete mode 100644 vendor/golang.org/x/sys/windows/race0.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/export_test.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/key.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/mksyscall.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/registry_test.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/syscall.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/value.go delete mode 100644 vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/security_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/service.go delete mode 100644 vendor/golang.org/x/sys/windows/str.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/debug/log.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/debug/service.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/event.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/eventlog/install.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/eventlog/log.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/example/beep.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/example/install.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/example/main.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/example/manage.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/example/service.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/go12.c delete mode 100644 vendor/golang.org/x/sys/windows/svc/go12.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/go13.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/config.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/mgr.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/service.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/security.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/service.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/svc_test.go delete mode 100644 vendor/golang.org/x/sys/windows/svc/sys_386.s delete mode 100644 vendor/golang.org/x/sys/windows/svc/sys_amd64.s delete mode 100644 vendor/golang.org/x/sys/windows/syscall.go delete mode 100644 vendor/golang.org/x/sys/windows/syscall_test.go delete mode 100644 vendor/golang.org/x/sys/windows/syscall_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/syscall_windows_test.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_386.go delete mode 100644 vendor/golang.org/x/sys/windows/types_windows_amd64.go delete mode 100644 vendor/golang.org/x/sys/windows/zsyscall_windows.go diff --git a/Gopkg.lock b/Gopkg.lock index 54d0aa0..66b3b15 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -8,10 +8,10 @@ version = "v1.5.0" [[projects]] - branch = "master" - name = "github.com/gosuri/uilive" + name = "github.com/gizak/termui" packages = ["."] - revision = "ac356e6e42cd31fcef8e6aec13ae9ed6fe87713e" + revision = "24acd523c756fd9728824cdfac66aad9d8982fb7" + version = "v2.2.0" [[projects]] name = "github.com/jawher/mow.cli" @@ -19,6 +19,12 @@ revision = "0e80ee9f63156ea1954dc2375c33a1c7e752c25c" version = "v1.0.3" +[[projects]] + name = "github.com/maruel/panicparse" + packages = ["stack"] + revision = "766956aceb8ff49664065ae50bef0ae8a0a83ec4" + version = "v1.0.2" + [[projects]] name = "github.com/mattn/go-colorable" packages = ["."] @@ -31,12 +37,30 @@ revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" version = "v0.0.3" +[[projects]] + name = "github.com/mattn/go-runewidth" + packages = ["."] + revision = "9e777a8366cce605130a531d2cd6363d07ad7317" + version = "v0.0.2" + [[projects]] name = "github.com/mattn/go-sqlite3" packages = ["."] revision = "6c771bb9887719704b210e87e934f08be014bdb1" version = "v1.6.0" +[[projects]] + branch = "master" + name = "github.com/mitchellh/go-wordwrap" + packages = ["."] + revision = "ad45545899c7b13c020ea92b2072220eefad42b8" + +[[projects]] + branch = "master" + name = "github.com/nsf/termbox-go" + packages = ["."] + revision = "88b7b944be8bc8d8ec6195fca97c5869ba20f99d" + [[projects]] branch = "master" name = "golang.org/x/sys" @@ -46,6 +70,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "1a1f721ab61fd1976d54ba03bad816beaefd926604a77b24c318305d4082f779" + inputs-digest = "59a956a9d4768c1668abfcf5af67434d0f8251797d381c64b9dcf013a3dfcb34" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index e70ac58..329330b 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -24,10 +24,6 @@ name = "github.com/fatih/color" version = "1.5.0" -[[constraint]] - branch = "master" - name = "github.com/gosuri/uilive" - [[constraint]] name = "github.com/jawher/mow.cli" version = "1.0.3" diff --git a/vendor/github.com/gizak/termui/.gitignore b/vendor/github.com/gizak/termui/.gitignore new file mode 100644 index 0000000..8b156b0 --- /dev/null +++ b/vendor/github.com/gizak/termui/.gitignore @@ -0,0 +1,26 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +.DS_Store +/vendor diff --git a/vendor/github.com/gizak/termui/.travis.yml b/vendor/github.com/gizak/termui/.travis.yml new file mode 100644 index 0000000..206e887 --- /dev/null +++ b/vendor/github.com/gizak/termui/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - tip + +script: go test -v ./ \ No newline at end of file diff --git a/vendor/github.com/gizak/termui/LICENSE b/vendor/github.com/gizak/termui/LICENSE new file mode 100644 index 0000000..311ccc7 --- /dev/null +++ b/vendor/github.com/gizak/termui/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Zack Guo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/gizak/termui/README.md b/vendor/github.com/gizak/termui/README.md new file mode 100644 index 0000000..d5f3d9a --- /dev/null +++ b/vendor/github.com/gizak/termui/README.md @@ -0,0 +1,151 @@ +# termui [![Build Status](https://travis-ci.org/gizak/termui.svg?branch=master)](https://travis-ci.org/gizak/termui) [![Doc Status](https://godoc.org/github.com/gizak/termui?status.png)](https://godoc.org/github.com/gizak/termui) + +demo cast under osx 10.10; Terminal.app; Menlo Regular 12pt.) + +`termui` is a cross-platform, easy-to-compile, and fully-customizable terminal dashboard. It is inspired by [blessed-contrib](https://github.com/yaronn/blessed-contrib), but purely in Go. + +Now version v2 has arrived! It brings new event system, new theme system, new `Buffer` interface and specific colour text rendering. (some docs are missing, but it will be completed soon!) + +## Installation + +`master` mirrors v2 branch, to install: + + go get -u github.com/gizak/termui + +It is recommanded to use locked deps by using [glide](https://glide.sh): move to `termui` src directory then run `glide up`. + +For the compatible reason, you can choose to install the legacy version of `termui`: + + go get gopkg.in/gizak/termui.v1 + +## Usage + +### Layout + +To use `termui`, the very first thing you may want to know is how to manage layout. `termui` offers two ways of doing this, known as absolute layout and grid layout. + +__Absolute layout__ + +Each widget has an underlying block structure which basically is a box model. It has border, label and padding properties. A border of a widget can be chosen to hide or display (with its border label), you can pick a different front/back colour for the border as well. To display such a widget at a specific location in terminal window, you need to assign `.X`, `.Y`, `.Height`, `.Width` values for each widget before sending it to `.Render`. Let's demonstrate these by a code snippet: + +`````go + import ui "github.com/gizak/termui" // <- ui shortcut, optional + + func main() { + err := ui.Init() + if err != nil { + panic(err) + } + defer ui.Close() + + p := ui.NewPar(":PRESS q TO QUIT DEMO") + p.Height = 3 + p.Width = 50 + p.TextFgColor = ui.ColorWhite + p.BorderLabel = "Text Box" + p.BorderFg = ui.ColorCyan + + g := ui.NewGauge() + g.Percent = 50 + g.Width = 50 + g.Height = 3 + g.Y = 11 + g.BorderLabel = "Gauge" + g.BarColor = ui.ColorRed + g.BorderFg = ui.ColorWhite + g.BorderLabelFg = ui.ColorCyan + + ui.Render(p, g) // feel free to call Render, it's async and non-block + + // event handler... + } +````` + +Note that components can be overlapped (I'd rather call this a feature...), `Render(rs ...Renderer)` renders its args from left to right (i.e. each component's weight is arising from left to right). + +__Grid layout:__ + +grid + +Grid layout uses [12 columns grid system](http://www.w3schools.com/bootstrap/bootstrap_grid_system.asp) with expressive syntax. To use `Grid`, all we need to do is build a widget tree consisting of `Row`s and `Col`s (Actually a `Col` is also a `Row` but with a widget endpoint attached). + +```go + import ui "github.com/gizak/termui" + // init and create widgets... + + // build + ui.Body.AddRows( + ui.NewRow( + ui.NewCol(6, 0, widget0), + ui.NewCol(6, 0, widget1)), + ui.NewRow( + ui.NewCol(3, 0, widget2), + ui.NewCol(3, 0, widget30, widget31, widget32), + ui.NewCol(6, 0, widget4))) + + // calculate layout + ui.Body.Align() + + ui.Render(ui.Body) +``` + +### Events + +`termui` ships with a http-like event mux handling system. All events are channeled up from different sources (typing, click, windows resize, custom event) and then encoded as universal `Event` object. `Event.Path` indicates the event type and `Event.Data` stores the event data struct. Add a handler to a certain event is easy as below: + +```go + // handle key q pressing + ui.Handle("/sys/kbd/q", func(ui.Event) { + // press q to quit + ui.StopLoop() + }) + + ui.Handle("/sys/kbd/C-x", func(ui.Event) { + // handle Ctrl + x combination + }) + + ui.Handle("/sys/kbd", func(ui.Event) { + // handle all other key pressing + }) + + // handle a 1s timer + ui.Handle("/timer/1s", func(e ui.Event) { + t := e.Data.(ui.EvtTimer) + // t is a EvtTimer + if t.Count%2 ==0 { + // do something + } + }) + + ui.Loop() // block until StopLoop is called +``` + +### Widgets + +Click image to see the corresponding demo codes. + +[par](https://github.com/gizak/termui/blob/master/_example/par.go) +[list](https://github.com/gizak/termui/blob/master/_example/list.go) +[gauge](https://github.com/gizak/termui/blob/master/_example/gauge.go) +[linechart](https://github.com/gizak/termui/blob/master/_example/linechart.go) +[barchart](https://github.com/gizak/termui/blob/master/_example/barchart.go) +[barchart](https://github.com/gizak/termui/blob/master/_example/mbarchart.go) +[sparklines](https://github.com/gizak/termui/blob/master/_example/sparklines.go) +[table](https://github.com/gizak/termui/blob/master/_example/table.go) + +## GoDoc + +[godoc](https://godoc.org/github.com/gizak/termui) + +## TODO + +- [x] Grid layout +- [x] Event system +- [x] Canvas widget +- [x] Refine APIs +- [ ] Focusable widgets + +## Changelog + +## License +This library is under the [MIT License](http://opensource.org/licenses/MIT) diff --git a/vendor/github.com/gizak/termui/barchart.go b/vendor/github.com/gizak/termui/barchart.go new file mode 100644 index 0000000..6560c8b --- /dev/null +++ b/vendor/github.com/gizak/termui/barchart.go @@ -0,0 +1,149 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "fmt" + +// BarChart creates multiple bars in a widget: +/* + bc := termui.NewBarChart() + data := []int{3, 2, 5, 3, 9, 5} + bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} + bc.BorderLabel = "Bar Chart" + bc.Data = data + bc.Width = 26 + bc.Height = 10 + bc.DataLabels = bclabels + bc.TextColor = termui.ColorGreen + bc.BarColor = termui.ColorRed + bc.NumColor = termui.ColorYellow +*/ +type BarChart struct { + Block + BarColor Attribute + TextColor Attribute + NumColor Attribute + Data []int + DataLabels []string + BarWidth int + BarGap int + CellChar rune + labels [][]rune + dataNum [][]rune + numBar int + scale float64 + max int +} + +// NewBarChart returns a new *BarChart with current theme. +func NewBarChart() *BarChart { + bc := &BarChart{Block: *NewBlock()} + bc.BarColor = ThemeAttr("barchart.bar.bg") + bc.NumColor = ThemeAttr("barchart.num.fg") + bc.TextColor = ThemeAttr("barchart.text.fg") + bc.BarGap = 1 + bc.BarWidth = 3 + bc.CellChar = ' ' + return bc +} + +func (bc *BarChart) layout() { + bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth) + bc.labels = make([][]rune, bc.numBar) + bc.dataNum = make([][]rune, len(bc.Data)) + + for i := 0; i < bc.numBar && i < len(bc.DataLabels) && i < len(bc.Data); i++ { + bc.labels[i] = trimStr2Runes(bc.DataLabels[i], bc.BarWidth) + n := bc.Data[i] + s := fmt.Sprint(n) + bc.dataNum[i] = trimStr2Runes(s, bc.BarWidth) + } + + //bc.max = bc.Data[0] // what if Data is nil? Sometimes when bar graph is nill it produces panic with panic: runtime error: index out of range + // Asign a negative value to get maxvalue auto-populates + if bc.max == 0 { + bc.max = -1 + } + for i := 0; i < len(bc.Data); i++ { + if bc.max < bc.Data[i] { + bc.max = bc.Data[i] + } + } + bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1) +} + +func (bc *BarChart) SetMax(max int) { + + if max > 0 { + bc.max = max + } +} + +// Buffer implements Bufferer interface. +func (bc *BarChart) Buffer() Buffer { + buf := bc.Block.Buffer() + bc.layout() + + for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ { + h := int(float64(bc.Data[i]) / bc.scale) + oftX := i * (bc.BarWidth + bc.BarGap) + + barBg := bc.Bg + barFg := bc.BarColor + + if bc.CellChar == ' ' { + barBg = bc.BarColor + barFg = ColorDefault + if bc.BarColor == ColorDefault { // the same as above + barBg |= AttrReverse + } + } + + // plot bar + for j := 0; j < bc.BarWidth; j++ { + for k := 0; k < h; k++ { + c := Cell{ + Ch: bc.CellChar, + Bg: barBg, + Fg: barFg, + } + + x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k + buf.Set(x, y, c) + } + } + // plot text + for j, k := 0, 0; j < len(bc.labels[i]); j++ { + w := charWidth(bc.labels[i][j]) + c := Cell{ + Ch: bc.labels[i][j], + Bg: bc.Bg, + Fg: bc.TextColor, + } + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1 + x := bc.innerArea.Min.X + oftX + k + buf.Set(x, y, c) + k += w + } + // plot num + for j := 0; j < len(bc.dataNum[i]); j++ { + c := Cell{ + Ch: bc.dataNum[i][j], + Fg: bc.NumColor, + Bg: barBg, + } + + if h == 0 { + c.Bg = bc.Bg + } + x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 + buf.Set(x, y, c) + } + } + + return buf +} diff --git a/vendor/github.com/gizak/termui/block.go b/vendor/github.com/gizak/termui/block.go new file mode 100644 index 0000000..3e8571b --- /dev/null +++ b/vendor/github.com/gizak/termui/block.go @@ -0,0 +1,240 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "image" + +// Hline is a horizontal line. +type Hline struct { + X int + Y int + Len int + Fg Attribute + Bg Attribute +} + +// Vline is a vertical line. +type Vline struct { + X int + Y int + Len int + Fg Attribute + Bg Attribute +} + +// Buffer draws a horizontal line. +func (l Hline) Buffer() Buffer { + if l.Len <= 0 { + return NewBuffer() + } + return NewFilledBuffer(l.X, l.Y, l.X+l.Len, l.Y+1, HORIZONTAL_LINE, l.Fg, l.Bg) +} + +// Buffer draws a vertical line. +func (l Vline) Buffer() Buffer { + if l.Len <= 0 { + return NewBuffer() + } + return NewFilledBuffer(l.X, l.Y, l.X+1, l.Y+l.Len, VERTICAL_LINE, l.Fg, l.Bg) +} + +// Buffer draws a box border. +func (b Block) drawBorder(buf Buffer) { + if !b.Border { + return + } + + min := b.area.Min + max := b.area.Max + + x0 := min.X + y0 := min.Y + x1 := max.X - 1 + y1 := max.Y - 1 + + // draw lines + if b.BorderTop { + buf.Merge(Hline{x0, y0, x1 - x0, b.BorderFg, b.BorderBg}.Buffer()) + } + if b.BorderBottom { + buf.Merge(Hline{x0, y1, x1 - x0, b.BorderFg, b.BorderBg}.Buffer()) + } + if b.BorderLeft { + buf.Merge(Vline{x0, y0, y1 - y0, b.BorderFg, b.BorderBg}.Buffer()) + } + if b.BorderRight { + buf.Merge(Vline{x1, y0, y1 - y0, b.BorderFg, b.BorderBg}.Buffer()) + } + + // draw corners + if b.BorderTop && b.BorderLeft && b.area.Dx() > 0 && b.area.Dy() > 0 { + buf.Set(x0, y0, Cell{TOP_LEFT, b.BorderFg, b.BorderBg}) + } + if b.BorderTop && b.BorderRight && b.area.Dx() > 1 && b.area.Dy() > 0 { + buf.Set(x1, y0, Cell{TOP_RIGHT, b.BorderFg, b.BorderBg}) + } + if b.BorderBottom && b.BorderLeft && b.area.Dx() > 0 && b.area.Dy() > 1 { + buf.Set(x0, y1, Cell{BOTTOM_LEFT, b.BorderFg, b.BorderBg}) + } + if b.BorderBottom && b.BorderRight && b.area.Dx() > 1 && b.area.Dy() > 1 { + buf.Set(x1, y1, Cell{BOTTOM_RIGHT, b.BorderFg, b.BorderBg}) + } +} + +func (b Block) drawBorderLabel(buf Buffer) { + maxTxtW := b.area.Dx() - 2 + tx := DTrimTxCls(DefaultTxBuilder.Build(b.BorderLabel, b.BorderLabelFg, b.BorderLabelBg), maxTxtW) + + for i, w := 0, 0; i < len(tx); i++ { + buf.Set(b.area.Min.X+1+w, b.area.Min.Y, tx[i]) + w += tx[i].Width() + } +} + +// Block is a base struct for all other upper level widgets, +// consider it as css: display:block. +// Normally you do not need to create it manually. +type Block struct { + area image.Rectangle + innerArea image.Rectangle + X int + Y int + Border bool + BorderFg Attribute + BorderBg Attribute + BorderLeft bool + BorderRight bool + BorderTop bool + BorderBottom bool + BorderLabel string + BorderLabelFg Attribute + BorderLabelBg Attribute + Display bool + Bg Attribute + Width int + Height int + PaddingTop int + PaddingBottom int + PaddingLeft int + PaddingRight int + id string + Float Align +} + +// NewBlock returns a *Block which inherits styles from current theme. +func NewBlock() *Block { + b := Block{} + b.Display = true + b.Border = true + b.BorderLeft = true + b.BorderRight = true + b.BorderTop = true + b.BorderBottom = true + b.BorderBg = ThemeAttr("border.bg") + b.BorderFg = ThemeAttr("border.fg") + b.BorderLabelBg = ThemeAttr("label.bg") + b.BorderLabelFg = ThemeAttr("label.fg") + b.Bg = ThemeAttr("block.bg") + b.Width = 2 + b.Height = 2 + b.id = GenId() + b.Float = AlignNone + return &b +} + +func (b Block) Id() string { + return b.id +} + +// Align computes box model +func (b *Block) Align() { + // outer + b.area.Min.X = 0 + b.area.Min.Y = 0 + b.area.Max.X = b.Width + b.area.Max.Y = b.Height + + // float + b.area = AlignArea(TermRect(), b.area, b.Float) + b.area = MoveArea(b.area, b.X, b.Y) + + // inner + b.innerArea.Min.X = b.area.Min.X + b.PaddingLeft + b.innerArea.Min.Y = b.area.Min.Y + b.PaddingTop + b.innerArea.Max.X = b.area.Max.X - b.PaddingRight + b.innerArea.Max.Y = b.area.Max.Y - b.PaddingBottom + + if b.Border { + if b.BorderLeft { + b.innerArea.Min.X++ + } + if b.BorderRight { + b.innerArea.Max.X-- + } + if b.BorderTop { + b.innerArea.Min.Y++ + } + if b.BorderBottom { + b.innerArea.Max.Y-- + } + } +} + +// InnerBounds returns the internal bounds of the block after aligning and +// calculating the padding and border, if any. +func (b *Block) InnerBounds() image.Rectangle { + b.Align() + return b.innerArea +} + +// Buffer implements Bufferer interface. +// Draw background and border (if any). +func (b *Block) Buffer() Buffer { + b.Align() + + buf := NewBuffer() + buf.SetArea(b.area) + buf.Fill(' ', ColorDefault, b.Bg) + + b.drawBorder(buf) + b.drawBorderLabel(buf) + + return buf +} + +// GetHeight implements GridBufferer. +// It returns current height of the block. +func (b Block) GetHeight() int { + return b.Height +} + +// SetX implements GridBufferer interface, which sets block's x position. +func (b *Block) SetX(x int) { + b.X = x +} + +// SetY implements GridBufferer interface, it sets y position for block. +func (b *Block) SetY(y int) { + b.Y = y +} + +// SetWidth implements GridBuffer interface, it sets block's width. +func (b *Block) SetWidth(w int) { + b.Width = w +} + +func (b Block) InnerWidth() int { + return b.innerArea.Dx() +} + +func (b Block) InnerHeight() int { + return b.innerArea.Dy() +} + +func (b Block) InnerX() int { + return b.innerArea.Min.X +} + +func (b Block) InnerY() int { return b.innerArea.Min.Y } diff --git a/vendor/github.com/gizak/termui/block_common.go b/vendor/github.com/gizak/termui/block_common.go new file mode 100644 index 0000000..6438bf2 --- /dev/null +++ b/vendor/github.com/gizak/termui/block_common.go @@ -0,0 +1,20 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +// +build !windows + +package termui + +const TOP_RIGHT = '┐' +const VERTICAL_LINE = '│' +const HORIZONTAL_LINE = '─' +const TOP_LEFT = '┌' +const BOTTOM_RIGHT = '┘' +const BOTTOM_LEFT = '└' +const VERTICAL_LEFT = '┤' +const VERTICAL_RIGHT = '├' +const HORIZONTAL_DOWN = '┬' +const HORIZONTAL_UP = '┴' +const QUOTA_LEFT = '«' +const QUOTA_RIGHT = '»' diff --git a/vendor/github.com/gizak/termui/block_test.go b/vendor/github.com/gizak/termui/block_test.go new file mode 100644 index 0000000..8194179 --- /dev/null +++ b/vendor/github.com/gizak/termui/block_test.go @@ -0,0 +1,72 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "testing" +) + +func TestBlockFloat(t *testing.T) { + Init() + defer Close() + + b := NewBlock() + b.X = 10 + b.Y = 20 + + b.Float = AlignCenter + b.Align() +} + +func TestBlockInnerBounds(t *testing.T) { + Init() + defer Close() + + b := NewBlock() + b.X = 10 + b.Y = 11 + b.Width = 12 + b.Height = 13 + + assert := func(name string, x, y, w, h int) { + t.Log(name) + area := b.InnerBounds() + cx := area.Min.X + cy := area.Min.Y + cw := area.Dx() + ch := area.Dy() + + if cx != x { + t.Errorf("expected x to be %d but got %d", x, cx) + } + if cy != y { + t.Errorf("expected y to be %d but got %d\n%+v", y, cy, area) + } + if cw != w { + t.Errorf("expected width to be %d but got %d", w, cw) + } + if ch != h { + t.Errorf("expected height to be %d but got %d", h, ch) + } + } + + b.Border = false + assert("no border, no padding", 10, 11, 12, 13) + + b.Border = true + assert("border, no padding", 11, 12, 10, 11) + + b.PaddingBottom = 2 + assert("border, 2b padding", 11, 12, 10, 9) + + b.PaddingTop = 3 + assert("border, 2b 3t padding", 11, 15, 10, 6) + + b.PaddingLeft = 4 + assert("border, 2b 3t 4l padding", 15, 15, 6, 6) + + b.PaddingRight = 5 + assert("border, 2b 3t 4l 5r padding", 15, 15, 1, 6) +} diff --git a/vendor/github.com/gizak/termui/block_windows.go b/vendor/github.com/gizak/termui/block_windows.go new file mode 100644 index 0000000..a4fba77 --- /dev/null +++ b/vendor/github.com/gizak/termui/block_windows.go @@ -0,0 +1,14 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +// +build windows + +package termui + +const TOP_RIGHT = '+' +const VERTICAL_LINE = '|' +const HORIZONTAL_LINE = '-' +const TOP_LEFT = '+' +const BOTTOM_RIGHT = '+' +const BOTTOM_LEFT = '+' diff --git a/vendor/github.com/gizak/termui/buffer.go b/vendor/github.com/gizak/termui/buffer.go new file mode 100644 index 0000000..9e3a973 --- /dev/null +++ b/vendor/github.com/gizak/termui/buffer.go @@ -0,0 +1,106 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "image" + +// Cell is a rune with assigned Fg and Bg +type Cell struct { + Ch rune + Fg Attribute + Bg Attribute +} + +// Buffer is a renderable rectangle cell data container. +type Buffer struct { + Area image.Rectangle // selected drawing area + CellMap map[image.Point]Cell +} + +// At returns the cell at (x,y). +func (b Buffer) At(x, y int) Cell { + return b.CellMap[image.Pt(x, y)] +} + +// Set assigns a char to (x,y) +func (b Buffer) Set(x, y int, c Cell) { + b.CellMap[image.Pt(x, y)] = c +} + +// Bounds returns the domain for which At can return non-zero color. +func (b Buffer) Bounds() image.Rectangle { + x0, y0, x1, y1 := 0, 0, 0, 0 + for p := range b.CellMap { + if p.X > x1 { + x1 = p.X + } + if p.X < x0 { + x0 = p.X + } + if p.Y > y1 { + y1 = p.Y + } + if p.Y < y0 { + y0 = p.Y + } + } + return image.Rect(x0, y0, x1+1, y1+1) +} + +// SetArea assigns a new rect area to Buffer b. +func (b *Buffer) SetArea(r image.Rectangle) { + b.Area.Max = r.Max + b.Area.Min = r.Min +} + +// Sync sets drawing area to the buffer's bound +func (b *Buffer) Sync() { + b.SetArea(b.Bounds()) +} + +// NewCell returns a new cell +func NewCell(ch rune, fg, bg Attribute) Cell { + return Cell{ch, fg, bg} +} + +// Merge merges bs Buffers onto b +func (b *Buffer) Merge(bs ...Buffer) { + for _, buf := range bs { + for p, v := range buf.CellMap { + b.Set(p.X, p.Y, v) + } + b.SetArea(b.Area.Union(buf.Area)) + } +} + +// NewBuffer returns a new Buffer +func NewBuffer() Buffer { + return Buffer{ + CellMap: make(map[image.Point]Cell), + Area: image.Rectangle{}} +} + +// Fill fills the Buffer b with ch,fg and bg. +func (b Buffer) Fill(ch rune, fg, bg Attribute) { + for x := b.Area.Min.X; x < b.Area.Max.X; x++ { + for y := b.Area.Min.Y; y < b.Area.Max.Y; y++ { + b.Set(x, y, Cell{ch, fg, bg}) + } + } +} + +// NewFilledBuffer returns a new Buffer filled with ch, fb and bg. +func NewFilledBuffer(x0, y0, x1, y1 int, ch rune, fg, bg Attribute) Buffer { + buf := NewBuffer() + buf.Area.Min = image.Pt(x0, y0) + buf.Area.Max = image.Pt(x1, y1) + + for x := buf.Area.Min.X; x < buf.Area.Max.X; x++ { + for y := buf.Area.Min.Y; y < buf.Area.Max.Y; y++ { + buf.Set(x, y, Cell{ch, fg, bg}) + } + } + return buf +} diff --git a/vendor/github.com/gizak/termui/buffer_test.go b/vendor/github.com/gizak/termui/buffer_test.go new file mode 100644 index 0000000..aae9d08 --- /dev/null +++ b/vendor/github.com/gizak/termui/buffer_test.go @@ -0,0 +1,23 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "image" + "testing" +) + +func TestBufferUnion(t *testing.T) { + b0 := NewBuffer() + b1 := NewBuffer() + + b1.Area.Max.X = 100 + b1.Area.Max.Y = 100 + b0.Area.Max.X = 50 + b0.Merge(b1) + if b0.Area.Max.X != 100 { + t.Errorf("Buffer.Merge unions Area failed: should:%v, actual %v,%v", image.Rect(0, 0, 50, 0).Union(image.Rect(0, 0, 100, 100)), b1.Area, b0.Area) + } +} diff --git a/vendor/github.com/gizak/termui/canvas.go b/vendor/github.com/gizak/termui/canvas.go new file mode 100644 index 0000000..6d2513e --- /dev/null +++ b/vendor/github.com/gizak/termui/canvas.go @@ -0,0 +1,72 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +/* +dots: + ,___, + |1 4| + |2 5| + |3 6| + |7 8| + ````` +*/ + +var brailleBase = '\u2800' + +var brailleOftMap = [4][2]rune{ + {'\u0001', '\u0008'}, + {'\u0002', '\u0010'}, + {'\u0004', '\u0020'}, + {'\u0040', '\u0080'}} + +// Canvas contains drawing map: i,j -> rune +type Canvas map[[2]int]rune + +// NewCanvas returns an empty Canvas +func NewCanvas() Canvas { + return make(map[[2]int]rune) +} + +func chOft(x, y int) rune { + return brailleOftMap[y%4][x%2] +} + +func (c Canvas) rawCh(x, y int) rune { + if ch, ok := c[[2]int{x, y}]; ok { + return ch + } + return '\u0000' //brailleOffset +} + +// return coordinate in terminal +func chPos(x, y int) (int, int) { + return y / 4, x / 2 +} + +// Set sets a point (x,y) in the virtual coordinate +func (c Canvas) Set(x, y int) { + i, j := chPos(x, y) + ch := c.rawCh(i, j) + ch |= chOft(x, y) + c[[2]int{i, j}] = ch +} + +// Unset removes point (x,y) +func (c Canvas) Unset(x, y int) { + i, j := chPos(x, y) + ch := c.rawCh(i, j) + ch &= ^chOft(x, y) + c[[2]int{i, j}] = ch +} + +// Buffer returns un-styled points +func (c Canvas) Buffer() Buffer { + buf := NewBuffer() + for k, v := range c { + buf.Set(k[0], k[1], Cell{Ch: v + brailleBase}) + } + return buf +} diff --git a/vendor/github.com/gizak/termui/canvas_test.go b/vendor/github.com/gizak/termui/canvas_test.go new file mode 100644 index 0000000..f73ce48 --- /dev/null +++ b/vendor/github.com/gizak/termui/canvas_test.go @@ -0,0 +1,57 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +// +build ignore + +package termui + +import ( + "testing" + + "github.com/davecgh/go-spew/spew" +) + +func TestCanvasSet(t *testing.T) { + c := NewCanvas() + c.Set(0, 0) + c.Set(0, 1) + c.Set(0, 2) + c.Set(0, 3) + c.Set(1, 3) + c.Set(2, 3) + c.Set(3, 3) + c.Set(4, 3) + c.Set(5, 3) + spew.Dump(c) +} + +func TestCanvasUnset(t *testing.T) { + c := NewCanvas() + c.Set(0, 0) + c.Set(0, 1) + c.Set(0, 2) + c.Unset(0, 2) + spew.Dump(c) + c.Unset(0, 3) + spew.Dump(c) +} + +func TestCanvasBuffer(t *testing.T) { + c := NewCanvas() + c.Set(0, 0) + c.Set(0, 1) + c.Set(0, 2) + c.Set(0, 3) + c.Set(1, 3) + c.Set(2, 3) + c.Set(3, 3) + c.Set(4, 3) + c.Set(5, 3) + c.Set(6, 3) + c.Set(7, 2) + c.Set(8, 1) + c.Set(9, 0) + bufs := c.Buffer() + spew.Dump(bufs) +} diff --git a/vendor/github.com/gizak/termui/config.py b/vendor/github.com/gizak/termui/config.py new file mode 100644 index 0000000..30fadcf --- /dev/null +++ b/vendor/github.com/gizak/termui/config.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +import re +import os +import io + +copyright = """// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +""" + +exclude_dirs = [".git", "_docs"] +exclude_files = [] +include_dirs = [".", "debug", "extra", "test", "_example"] + + +def is_target(fpath): + if os.path.splitext(fpath)[-1] == ".go": + return True + return False + + +def update_copyright(fpath): + print("processing " + fpath) + f = io.open(fpath, 'r', encoding='utf-8') + fstr = f.read() + f.close() + + # remove old + m = re.search('^// Copyright .+?\r?\n\r?\n', fstr, re.MULTILINE|re.DOTALL) + if m: + fstr = fstr[m.end():] + + # add new + fstr = copyright + fstr + f = io.open(fpath, 'w',encoding='utf-8') + f.write(fstr) + f.close() + + +def main(): + for d in include_dirs: + files = [ + os.path.join(d, f) for f in os.listdir(d) + if os.path.isfile(os.path.join(d, f)) + ] + for f in files: + if is_target(f): + update_copyright(f) + + +if __name__ == '__main__': + main() diff --git a/vendor/github.com/gizak/termui/doc.go b/vendor/github.com/gizak/termui/doc.go new file mode 100644 index 0000000..13924eb --- /dev/null +++ b/vendor/github.com/gizak/termui/doc.go @@ -0,0 +1,29 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +/* +Package termui is a library designed for creating command line UI. For more info, goto http://github.com/gizak/termui + +A simplest example: + package main + + import ui "github.com/gizak/termui" + + func main() { + if err:=ui.Init(); err != nil { + panic(err) + } + defer ui.Close() + + g := ui.NewGauge() + g.Percent = 50 + g.Width = 50 + g.BorderLabel = "Gauge" + + ui.Render(g) + + ui.Loop() + } +*/ +package termui diff --git a/vendor/github.com/gizak/termui/events.go b/vendor/github.com/gizak/termui/events.go new file mode 100644 index 0000000..eb7319b --- /dev/null +++ b/vendor/github.com/gizak/termui/events.go @@ -0,0 +1,323 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "path" + "strconv" + "sync" + "time" + + "github.com/nsf/termbox-go" +) + +type Event struct { + Type string + Path string + From string + To string + Data interface{} + Time int64 +} + +var sysEvtChs []chan Event + +type EvtKbd struct { + KeyStr string +} + +func evtKbd(e termbox.Event) EvtKbd { + ek := EvtKbd{} + + k := string(e.Ch) + pre := "" + mod := "" + + if e.Mod == termbox.ModAlt { + mod = "M-" + } + if e.Ch == 0 { + if e.Key > 0xFFFF-12 { + k = "" + } else if e.Key > 0xFFFF-25 { + ks := []string{"", "", "", "", "", "", "", "", "", ""} + k = ks[0xFFFF-int(e.Key)-12] + } + + if e.Key <= 0x7F { + pre = "C-" + k = string('a' - 1 + int(e.Key)) + kmap := map[termbox.Key][2]string{ + termbox.KeyCtrlSpace: {"C-", ""}, + termbox.KeyBackspace: {"", ""}, + termbox.KeyTab: {"", ""}, + termbox.KeyEnter: {"", ""}, + termbox.KeyEsc: {"", ""}, + termbox.KeyCtrlBackslash: {"C-", "\\"}, + termbox.KeyCtrlSlash: {"C-", "/"}, + termbox.KeySpace: {"", ""}, + termbox.KeyCtrl8: {"C-", "8"}, + } + if sk, ok := kmap[e.Key]; ok { + pre = sk[0] + k = sk[1] + } + } + } + + ek.KeyStr = pre + mod + k + return ek +} + +func crtTermboxEvt(e termbox.Event) Event { + systypemap := map[termbox.EventType]string{ + termbox.EventKey: "keyboard", + termbox.EventResize: "window", + termbox.EventMouse: "mouse", + termbox.EventError: "error", + termbox.EventInterrupt: "interrupt", + } + ne := Event{From: "/sys", Time: time.Now().Unix()} + typ := e.Type + ne.Type = systypemap[typ] + + switch typ { + case termbox.EventKey: + kbd := evtKbd(e) + ne.Path = "/sys/kbd/" + kbd.KeyStr + ne.Data = kbd + case termbox.EventResize: + wnd := EvtWnd{} + wnd.Width = e.Width + wnd.Height = e.Height + ne.Path = "/sys/wnd/resize" + ne.Data = wnd + case termbox.EventError: + err := EvtErr(e.Err) + ne.Path = "/sys/err" + ne.Data = err + case termbox.EventMouse: + m := EvtMouse{} + m.X = e.MouseX + m.Y = e.MouseY + ne.Path = "/sys/mouse" + ne.Data = m + } + return ne +} + +type EvtWnd struct { + Width int + Height int +} + +type EvtMouse struct { + X int + Y int + Press string +} + +type EvtErr error + +func hookTermboxEvt() { + for { + e := termbox.PollEvent() + + for _, c := range sysEvtChs { + go func(ch chan Event) { + ch <- crtTermboxEvt(e) + }(c) + } + } +} + +func NewSysEvtCh() chan Event { + ec := make(chan Event) + sysEvtChs = append(sysEvtChs, ec) + return ec +} + +var DefaultEvtStream = NewEvtStream() + +type EvtStream struct { + sync.RWMutex + srcMap map[string]chan Event + stream chan Event + wg sync.WaitGroup + sigStopLoop chan Event + Handlers map[string]func(Event) + hook func(Event) +} + +func NewEvtStream() *EvtStream { + return &EvtStream{ + srcMap: make(map[string]chan Event), + stream: make(chan Event), + Handlers: make(map[string]func(Event)), + sigStopLoop: make(chan Event), + } +} + +func (es *EvtStream) Init() { + es.Merge("internal", es.sigStopLoop) + go func() { + es.wg.Wait() + close(es.stream) + }() +} + +func cleanPath(p string) string { + if p == "" { + return "/" + } + if p[0] != '/' { + p = "/" + p + } + return path.Clean(p) +} + +func isPathMatch(pattern, path string) bool { + if len(pattern) == 0 { + return false + } + n := len(pattern) + return len(path) >= n && path[0:n] == pattern +} + +func (es *EvtStream) Merge(name string, ec chan Event) { + es.Lock() + defer es.Unlock() + + es.wg.Add(1) + es.srcMap[name] = ec + + go func(a chan Event) { + for n := range a { + n.From = name + es.stream <- n + } + es.wg.Done() + }(ec) +} + +func (es *EvtStream) Handle(path string, handler func(Event)) { + es.Handlers[cleanPath(path)] = handler +} + +func findMatch(mux map[string]func(Event), path string) string { + n := -1 + pattern := "" + for m := range mux { + if !isPathMatch(m, path) { + continue + } + if len(m) > n { + pattern = m + n = len(m) + } + } + return pattern + +} +// Remove all existing defined Handlers from the map +func (es *EvtStream) ResetHandlers() { + for Path, _ := range es.Handlers { + delete(es.Handlers, Path) + } + return +} + +func (es *EvtStream) match(path string) string { + return findMatch(es.Handlers, path) +} + +func (es *EvtStream) Hook(f func(Event)) { + es.hook = f +} + +func (es *EvtStream) Loop() { + for e := range es.stream { + switch e.Path { + case "/sig/stoploop": + return + } + go func(a Event) { + es.RLock() + defer es.RUnlock() + if pattern := es.match(a.Path); pattern != "" { + es.Handlers[pattern](a) + } + }(e) + if es.hook != nil { + es.hook(e) + } + } +} + +func (es *EvtStream) StopLoop() { + go func() { + e := Event{ + Path: "/sig/stoploop", + } + es.sigStopLoop <- e + }() +} + +func Merge(name string, ec chan Event) { + DefaultEvtStream.Merge(name, ec) +} + +func Handle(path string, handler func(Event)) { + DefaultEvtStream.Handle(path, handler) +} + +func Loop() { + DefaultEvtStream.Loop() +} + +func StopLoop() { + DefaultEvtStream.StopLoop() +} + +type EvtTimer struct { + Duration time.Duration + Count uint64 +} + +func NewTimerCh(du time.Duration) chan Event { + t := make(chan Event) + + go func(a chan Event) { + n := uint64(0) + for { + n++ + time.Sleep(du) + e := Event{} + e.Type = "timer" + e.Path = "/timer/" + du.String() + e.Time = time.Now().Unix() + e.Data = EvtTimer{ + Duration: du, + Count: n, + } + t <- e + + } + }(t) + return t +} + +var DefualtHandler = func(e Event) { +} + +var usrEvtCh = make(chan Event) + +func SendCustomEvt(path string, data interface{}) { + e := Event{} + e.Path = path + e.Data = data + e.Time = time.Now().Unix() + usrEvtCh <- e +} diff --git a/vendor/github.com/gizak/termui/events_test.go b/vendor/github.com/gizak/termui/events_test.go new file mode 100644 index 0000000..4e369e5 --- /dev/null +++ b/vendor/github.com/gizak/termui/events_test.go @@ -0,0 +1,37 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "testing" + +var ps = []string{ + "", + "/", + "/a", + "/b", + "/a/c", + "/a/b", + "/a/b/c", + "/a/b/c/d", + "/a/b/c/d/"} + +func TestMatchScore(t *testing.T) { + chk := func(a, b string, s bool) { + if c := isPathMatch(a, b); c != s { + t.Errorf("\na:%s\nb:%s\nshould:%t\nactual:%t", a, b, s, c) + } + } + + chk(ps[1], ps[1], true) + chk(ps[1], ps[2], true) + chk(ps[2], ps[1], false) + chk(ps[4], ps[1], false) + chk(ps[6], ps[2], false) + chk(ps[4], ps[5], false) +} + +func TestCrtEvt(t *testing.T) { + +} diff --git a/vendor/github.com/gizak/termui/gauge.go b/vendor/github.com/gizak/termui/gauge.go new file mode 100644 index 0000000..9f6ce3a --- /dev/null +++ b/vendor/github.com/gizak/termui/gauge.go @@ -0,0 +1,109 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "strconv" + "strings" +) + +// Gauge is a progress bar like widget. +// A simple example: +/* + g := termui.NewGauge() + g.Percent = 40 + g.Width = 50 + g.Height = 3 + g.BorderLabel = "Slim Gauge" + g.BarColor = termui.ColorRed + g.PercentColor = termui.ColorBlue +*/ + +const ColorUndef Attribute = Attribute(^uint16(0)) + +type Gauge struct { + Block + Percent int + BarColor Attribute + PercentColor Attribute + PercentColorHighlighted Attribute + Label string + LabelAlign Align +} + +// NewGauge return a new gauge with current theme. +func NewGauge() *Gauge { + g := &Gauge{ + Block: *NewBlock(), + PercentColor: ThemeAttr("gauge.percent.fg"), + BarColor: ThemeAttr("gauge.bar.bg"), + Label: "{{percent}}%", + LabelAlign: AlignCenter, + PercentColorHighlighted: ColorUndef, + } + + g.Width = 12 + g.Height = 5 + return g +} + +// Buffer implements Bufferer interface. +func (g *Gauge) Buffer() Buffer { + buf := g.Block.Buffer() + + // plot bar + w := g.Percent * g.innerArea.Dx() / 100 + for i := 0; i < g.innerArea.Dy(); i++ { + for j := 0; j < w; j++ { + c := Cell{} + c.Ch = ' ' + c.Bg = g.BarColor + if c.Bg == ColorDefault { + c.Bg |= AttrReverse + } + buf.Set(g.innerArea.Min.X+j, g.innerArea.Min.Y+i, c) + } + } + + // plot percentage + s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1) + pry := g.innerArea.Min.Y + g.innerArea.Dy()/2 + rs := str2runes(s) + var pos int + switch g.LabelAlign { + case AlignLeft: + pos = 0 + + case AlignCenter: + pos = (g.innerArea.Dx() - strWidth(s)) / 2 + + case AlignRight: + pos = g.innerArea.Dx() - strWidth(s) - 1 + } + pos += g.innerArea.Min.X + + for i, v := range rs { + c := Cell{ + Ch: v, + Fg: g.PercentColor, + } + + if w+g.innerArea.Min.X > pos+i { + c.Bg = g.BarColor + if c.Bg == ColorDefault { + c.Bg |= AttrReverse + } + + if g.PercentColorHighlighted != ColorUndef { + c.Fg = g.PercentColorHighlighted + } + } else { + c.Bg = g.Block.Bg + } + + buf.Set(1+pos+i, pry, c) + } + return buf +} diff --git a/vendor/github.com/gizak/termui/glide.lock b/vendor/github.com/gizak/termui/glide.lock new file mode 100644 index 0000000..be5952d --- /dev/null +++ b/vendor/github.com/gizak/termui/glide.lock @@ -0,0 +1,30 @@ +hash: 7a754ba100256404a978b2fc8738aee337beb822458e4b6060399fb89ebd215c +updated: 2016-11-03T17:39:24.323773674-04:00 +imports: +- name: github.com/maruel/panicparse + version: ad661195ed0e88491e0f14be6613304e3b1141d6 + subpackages: + - stack +- name: github.com/mattn/go-runewidth + version: 737072b4e32b7a5018b4a7125da8d12de90e8045 +- name: github.com/mitchellh/go-wordwrap + version: ad45545899c7b13c020ea92b2072220eefad42b8 +- name: github.com/nsf/termbox-go + version: b6acae516ace002cb8105a89024544a1480655a5 +- name: golang.org/x/net + version: 569280fa63be4e201b975e5411e30a92178f0118 + subpackages: + - websocket +testImports: +- name: github.com/davecgh/go-spew + version: 346938d642f2ec3594ed81d874461961cd0faa76 + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/testify + version: 976c720a22c8eb4eb6a0b4348ad85ad12491a506 + subpackages: + - assert diff --git a/vendor/github.com/gizak/termui/glide.yaml b/vendor/github.com/gizak/termui/glide.yaml new file mode 100644 index 0000000..a681231 --- /dev/null +++ b/vendor/github.com/gizak/termui/glide.yaml @@ -0,0 +1,9 @@ +package: github.com/gizak/termui +import: +- package: github.com/mattn/go-runewidth +- package: github.com/mitchellh/go-wordwrap +- package: github.com/nsf/termbox-go +- package: golang.org/x/net + subpackages: + - websocket +- package: github.com/maruel/panicparse diff --git a/vendor/github.com/gizak/termui/grid.go b/vendor/github.com/gizak/termui/grid.go new file mode 100644 index 0000000..a950232 --- /dev/null +++ b/vendor/github.com/gizak/termui/grid.go @@ -0,0 +1,279 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +// GridBufferer introduces a Bufferer that can be manipulated by Grid. +type GridBufferer interface { + Bufferer + GetHeight() int + SetWidth(int) + SetX(int) + SetY(int) +} + +// Row builds a layout tree +type Row struct { + Cols []*Row //children + Widget GridBufferer // root + X int + Y int + Width int + Height int + Span int + Offset int +} + +// calculate and set the underlying layout tree's x, y, height and width. +func (r *Row) calcLayout() { + r.assignWidth(r.Width) + r.Height = r.solveHeight() + r.assignX(r.X) + r.assignY(r.Y) +} + +// tell if the node is leaf in the tree. +func (r *Row) isLeaf() bool { + return r.Cols == nil || len(r.Cols) == 0 +} + +func (r *Row) isRenderableLeaf() bool { + return r.isLeaf() && r.Widget != nil +} + +// assign widgets' (and their parent rows') width recursively. +func (r *Row) assignWidth(w int) { + r.SetWidth(w) + + accW := 0 // acc span and offset + calcW := make([]int, len(r.Cols)) // calculated width + calcOftX := make([]int, len(r.Cols)) // computated start position of x + + for i, c := range r.Cols { + accW += c.Span + c.Offset + cw := int(float64(c.Span*r.Width) / 12.0) + + if i >= 1 { + calcOftX[i] = calcOftX[i-1] + + calcW[i-1] + + int(float64(r.Cols[i-1].Offset*r.Width)/12.0) + } + + // use up the space if it is the last col + if i == len(r.Cols)-1 && accW == 12 { + cw = r.Width - calcOftX[i] + } + calcW[i] = cw + r.Cols[i].assignWidth(cw) + } +} + +// bottom up calc and set rows' (and their widgets') height, +// return r's total height. +func (r *Row) solveHeight() int { + if r.isRenderableLeaf() { + r.Height = r.Widget.GetHeight() + return r.Widget.GetHeight() + } + + maxh := 0 + if !r.isLeaf() { + for _, c := range r.Cols { + nh := c.solveHeight() + // when embed rows in Cols, row widgets stack up + if r.Widget != nil { + nh += r.Widget.GetHeight() + } + if nh > maxh { + maxh = nh + } + } + } + + r.Height = maxh + return maxh +} + +// recursively assign x position for r tree. +func (r *Row) assignX(x int) { + r.SetX(x) + + if !r.isLeaf() { + acc := 0 + for i, c := range r.Cols { + if c.Offset != 0 { + acc += int(float64(c.Offset*r.Width) / 12.0) + } + r.Cols[i].assignX(x + acc) + acc += c.Width + } + } +} + +// recursively assign y position to r. +func (r *Row) assignY(y int) { + r.SetY(y) + + if r.isLeaf() { + return + } + + for i := range r.Cols { + acc := 0 + if r.Widget != nil { + acc = r.Widget.GetHeight() + } + r.Cols[i].assignY(y + acc) + } + +} + +// GetHeight implements GridBufferer interface. +func (r Row) GetHeight() int { + return r.Height +} + +// SetX implements GridBufferer interface. +func (r *Row) SetX(x int) { + r.X = x + if r.Widget != nil { + r.Widget.SetX(x) + } +} + +// SetY implements GridBufferer interface. +func (r *Row) SetY(y int) { + r.Y = y + if r.Widget != nil { + r.Widget.SetY(y) + } +} + +// SetWidth implements GridBufferer interface. +func (r *Row) SetWidth(w int) { + r.Width = w + if r.Widget != nil { + r.Widget.SetWidth(w) + } +} + +// Buffer implements Bufferer interface, +// recursively merge all widgets buffer +func (r *Row) Buffer() Buffer { + merged := NewBuffer() + + if r.isRenderableLeaf() { + return r.Widget.Buffer() + } + + // for those are not leaves but have a renderable widget + if r.Widget != nil { + merged.Merge(r.Widget.Buffer()) + } + + // collect buffer from children + if !r.isLeaf() { + for _, c := range r.Cols { + merged.Merge(c.Buffer()) + } + } + + return merged +} + +// Grid implements 12 columns system. +// A simple example: +/* + import ui "github.com/gizak/termui" + // init and create widgets... + + // build + ui.Body.AddRows( + ui.NewRow( + ui.NewCol(6, 0, widget0), + ui.NewCol(6, 0, widget1)), + ui.NewRow( + ui.NewCol(3, 0, widget2), + ui.NewCol(3, 0, widget30, widget31, widget32), + ui.NewCol(6, 0, widget4))) + + // calculate layout + ui.Body.Align() + + ui.Render(ui.Body) +*/ +type Grid struct { + Rows []*Row + Width int + X int + Y int + BgColor Attribute +} + +// NewGrid returns *Grid with given rows. +func NewGrid(rows ...*Row) *Grid { + return &Grid{Rows: rows} +} + +// AddRows appends given rows to Grid. +func (g *Grid) AddRows(rs ...*Row) { + g.Rows = append(g.Rows, rs...) +} + +// NewRow creates a new row out of given columns. +func NewRow(cols ...*Row) *Row { + rs := &Row{Span: 12, Cols: cols} + return rs +} + +// NewCol accepts: widgets are LayoutBufferer or widgets is A NewRow. +// Note that if multiple widgets are provided, they will stack up in the col. +func NewCol(span, offset int, widgets ...GridBufferer) *Row { + r := &Row{Span: span, Offset: offset} + + if widgets != nil && len(widgets) == 1 { + wgt := widgets[0] + nw, isRow := wgt.(*Row) + if isRow { + r.Cols = nw.Cols + } else { + r.Widget = wgt + } + return r + } + + r.Cols = []*Row{} + ir := r + for _, w := range widgets { + nr := &Row{Span: 12, Widget: w} + ir.Cols = []*Row{nr} + ir = nr + } + + return r +} + +// Align calculate each rows' layout. +func (g *Grid) Align() { + h := 0 + for _, r := range g.Rows { + r.SetWidth(g.Width) + r.SetX(g.X) + r.SetY(g.Y + h) + r.calcLayout() + h += r.GetHeight() + } +} + +// Buffer implments Bufferer interface. +func (g Grid) Buffer() Buffer { + buf := NewBuffer() + + for _, r := range g.Rows { + buf.Merge(r.Buffer()) + } + return buf +} + +var Body *Grid diff --git a/vendor/github.com/gizak/termui/grid_test.go b/vendor/github.com/gizak/termui/grid_test.go new file mode 100644 index 0000000..7b7b0b7 --- /dev/null +++ b/vendor/github.com/gizak/termui/grid_test.go @@ -0,0 +1,80 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "testing" + + "github.com/davecgh/go-spew/spew" +) + +var r *Row + +func TestRowWidth(t *testing.T) { + p0 := NewBlock() + p0.Height = 1 + p1 := NewBlock() + p1.Height = 1 + p2 := NewBlock() + p2.Height = 1 + p3 := NewBlock() + p3.Height = 1 + + /* test against tree: + + r + / \ + 0:w 1 + / \ + 10:w 11 + / + 110:w + / + 1100:w + */ + + r = NewRow( + NewCol(6, 0, p0), + NewCol(6, 0, + NewRow( + NewCol(6, 0, p1), + NewCol(6, 0, p2, p3)))) + + r.assignWidth(100) + if r.Width != 100 || + (r.Cols[0].Width) != 50 || + (r.Cols[1].Width) != 50 || + (r.Cols[1].Cols[0].Width) != 25 || + (r.Cols[1].Cols[1].Width) != 25 || + (r.Cols[1].Cols[1].Cols[0].Width) != 25 || + (r.Cols[1].Cols[1].Cols[0].Cols[0].Width) != 25 { + t.Error("assignWidth fails") + } +} + +func TestRowHeight(t *testing.T) { + spew.Dump() + + if (r.solveHeight()) != 2 || + (r.Cols[1].Cols[1].Height) != 2 || + (r.Cols[1].Cols[1].Cols[0].Height) != 2 || + (r.Cols[1].Cols[0].Height) != 1 { + t.Error("solveHeight fails") + } +} + +func TestAssignXY(t *testing.T) { + r.assignX(0) + r.assignY(0) + if (r.Cols[0].X) != 0 || + (r.Cols[1].Cols[0].X) != 50 || + (r.Cols[1].Cols[1].X) != 75 || + (r.Cols[1].Cols[1].Cols[0].X) != 75 || + (r.Cols[1].Cols[0].Y) != 0 || + (r.Cols[1].Cols[1].Cols[0].Y) != 0 || + (r.Cols[1].Cols[1].Cols[0].Cols[0].Y) != 1 { + t.Error("assignXY fails") + } +} diff --git a/vendor/github.com/gizak/termui/helper.go b/vendor/github.com/gizak/termui/helper.go new file mode 100644 index 0000000..18a6770 --- /dev/null +++ b/vendor/github.com/gizak/termui/helper.go @@ -0,0 +1,222 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "regexp" + "strings" + + tm "github.com/nsf/termbox-go" +) +import rw "github.com/mattn/go-runewidth" + +/* ---------------Port from termbox-go --------------------- */ + +// Attribute is printable cell's color and style. +type Attribute uint16 + +// 8 basic clolrs +const ( + ColorDefault Attribute = iota + ColorBlack + ColorRed + ColorGreen + ColorYellow + ColorBlue + ColorMagenta + ColorCyan + ColorWhite +) + +//Have a constant that defines number of colors +const NumberofColors = 8 + +// Text style +const ( + AttrBold Attribute = 1 << (iota + 9) + AttrUnderline + AttrReverse +) + +var ( + dot = "…" + dotw = rw.StringWidth(dot) +) + +/* ----------------------- End ----------------------------- */ + +func toTmAttr(x Attribute) tm.Attribute { + return tm.Attribute(x) +} + +func str2runes(s string) []rune { + return []rune(s) +} + +// Here for backwards-compatibility. +func trimStr2Runes(s string, w int) []rune { + return TrimStr2Runes(s, w) +} + +// TrimStr2Runes trims string to w[-1 rune], appends …, and returns the runes +// of that string if string is grather then n. If string is small then w, +// return the runes. +func TrimStr2Runes(s string, w int) []rune { + if w <= 0 { + return []rune{} + } + + sw := rw.StringWidth(s) + if sw > w { + return []rune(rw.Truncate(s, w, dot)) + } + return str2runes(s) +} + +// TrimStrIfAppropriate trim string to "s[:-1] + …" +// if string > width otherwise return string +func TrimStrIfAppropriate(s string, w int) string { + if w <= 0 { + return "" + } + + sw := rw.StringWidth(s) + if sw > w { + return rw.Truncate(s, w, dot) + } + + return s +} + +func strWidth(s string) int { + return rw.StringWidth(s) +} + +func charWidth(ch rune) int { + return rw.RuneWidth(ch) +} + +var whiteSpaceRegex = regexp.MustCompile(`\s`) + +// StringToAttribute converts text to a termui attribute. You may specifiy more +// then one attribute like that: "BLACK, BOLD, ...". All whitespaces +// are ignored. +func StringToAttribute(text string) Attribute { + text = whiteSpaceRegex.ReplaceAllString(strings.ToLower(text), "") + attributes := strings.Split(text, ",") + result := Attribute(0) + + for _, theAttribute := range attributes { + var match Attribute + switch theAttribute { + case "reset", "default": + match = ColorDefault + + case "black": + match = ColorBlack + + case "red": + match = ColorRed + + case "green": + match = ColorGreen + + case "yellow": + match = ColorYellow + + case "blue": + match = ColorBlue + + case "magenta": + match = ColorMagenta + + case "cyan": + match = ColorCyan + + case "white": + match = ColorWhite + + case "bold": + match = AttrBold + + case "underline": + match = AttrUnderline + + case "reverse": + match = AttrReverse + } + + result |= match + } + + return result +} + +// TextCells returns a coloured text cells []Cell +func TextCells(s string, fg, bg Attribute) []Cell { + cs := make([]Cell, 0, len(s)) + + // sequence := MarkdownTextRendererFactory{}.TextRenderer(s).Render(fg, bg) + // runes := []rune(sequence.NormalizedText) + runes := str2runes(s) + + for n := range runes { + // point, _ := sequence.PointAt(n, 0, 0) + // cs = append(cs, Cell{point.Ch, point.Fg, point.Bg}) + cs = append(cs, Cell{runes[n], fg, bg}) + } + return cs +} + +// Width returns the actual screen space the cell takes (usually 1 or 2). +func (c Cell) Width() int { + return charWidth(c.Ch) +} + +// Copy return a copy of c +func (c Cell) Copy() Cell { + return c +} + +// TrimTxCells trims the overflowed text cells sequence. +func TrimTxCells(cs []Cell, w int) []Cell { + if len(cs) <= w { + return cs + } + return cs[:w] +} + +// DTrimTxCls trims the overflowed text cells sequence and append dots at the end. +func DTrimTxCls(cs []Cell, w int) []Cell { + l := len(cs) + if l <= 0 { + return []Cell{} + } + + rt := make([]Cell, 0, w) + csw := 0 + for i := 0; i < l && csw <= w; i++ { + c := cs[i] + cw := c.Width() + + if cw+csw < w { + rt = append(rt, c) + csw += cw + } else { + rt = append(rt, Cell{'…', c.Fg, c.Bg}) + break + } + } + + return rt +} + +func CellsToStr(cs []Cell) string { + str := "" + for _, c := range cs { + str += string(c.Ch) + } + return str +} diff --git a/vendor/github.com/gizak/termui/helper_test.go b/vendor/github.com/gizak/termui/helper_test.go new file mode 100644 index 0000000..0b4b13e --- /dev/null +++ b/vendor/github.com/gizak/termui/helper_test.go @@ -0,0 +1,70 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStr2Rune(t *testing.T) { + s := "你好,世界." + rs := str2runes(s) + if len(rs) != 6 { + t.Error(t) + } +} + +func TestWidth(t *testing.T) { + s0 := "つのだ☆HIRO" + s1 := "11111111111" + // above not align for setting East Asian Ambiguous to wide!! + + if strWidth(s0) != strWidth(s1) { + t.Error("str len failed") + } + + len1 := []rune{'a', '2', '&', '「', 'オ', '。'} //will false: 'ᆵ', 'ᄚ', 'ᄒ' + for _, v := range len1 { + if charWidth(v) != 1 { + t.Error("len1 failed") + } + } + + len2 := []rune{'漢', '字', '한', '자', '你', '好', 'だ', '。', '%', 's', 'E', 'ョ', '、', 'ヲ'} + for _, v := range len2 { + if charWidth(v) != 2 { + t.Error("len2 failed") + } + } +} + +func TestTrim(t *testing.T) { + s := "つのだ☆HIRO" + if string(trimStr2Runes(s, 10)) != "つのだ☆HI"+dot { + t.Error("trim failed") + } + if string(trimStr2Runes(s, 11)) != "つのだ☆HIRO" { + t.Error("avoid tail trim failed") + } + if string(trimStr2Runes(s, 15)) != "つのだ☆HIRO" { + t.Error("avoid trim failed") + } +} + +func TestTrimStrIfAppropriate_NoTrim(t *testing.T) { + assert.Equal(t, "hello", TrimStrIfAppropriate("hello", 5)) +} + +func TestTrimStrIfAppropriate(t *testing.T) { + assert.Equal(t, "hel…", TrimStrIfAppropriate("hello", 4)) + assert.Equal(t, "h…", TrimStrIfAppropriate("hello", 2)) +} + +func TestStringToAttribute(t *testing.T) { + assert.Equal(t, ColorRed, StringToAttribute("ReD")) + assert.Equal(t, ColorRed|AttrBold, StringToAttribute("RED, bold")) +} diff --git a/vendor/github.com/gizak/termui/linechart.go b/vendor/github.com/gizak/termui/linechart.go new file mode 100644 index 0000000..f7eea28 --- /dev/null +++ b/vendor/github.com/gizak/termui/linechart.go @@ -0,0 +1,331 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "fmt" + "math" +) + +// only 16 possible combinations, why bother +var braillePatterns = map[[2]int]rune{ + [2]int{0, 0}: '⣀', + [2]int{0, 1}: '⡠', + [2]int{0, 2}: '⡐', + [2]int{0, 3}: '⡈', + + [2]int{1, 0}: '⢄', + [2]int{1, 1}: '⠤', + [2]int{1, 2}: '⠔', + [2]int{1, 3}: '⠌', + + [2]int{2, 0}: '⢂', + [2]int{2, 1}: '⠢', + [2]int{2, 2}: '⠒', + [2]int{2, 3}: '⠊', + + [2]int{3, 0}: '⢁', + [2]int{3, 1}: '⠡', + [2]int{3, 2}: '⠑', + [2]int{3, 3}: '⠉', +} + +var lSingleBraille = [4]rune{'\u2840', '⠄', '⠂', '⠁'} +var rSingleBraille = [4]rune{'\u2880', '⠠', '⠐', '⠈'} + +// LineChart has two modes: braille(default) and dot. Using braille gives 2x capicity as dot mode, +// because one braille char can represent two data points. +/* + lc := termui.NewLineChart() + lc.BorderLabel = "braille-mode Line Chart" + lc.Data = [1.2, 1.3, 1.5, 1.7, 1.5, 1.6, 1.8, 2.0] + lc.Width = 50 + lc.Height = 12 + lc.AxesColor = termui.ColorWhite + lc.LineColor = termui.ColorGreen | termui.AttrBold + // termui.Render(lc)... +*/ +type LineChart struct { + Block + Data []float64 + DataLabels []string // if unset, the data indices will be used + Mode string // braille | dot + DotStyle rune + LineColor Attribute + scale float64 // data span per cell on y-axis + AxesColor Attribute + drawingX int + drawingY int + axisYHeight int + axisXWidth int + axisYLabelGap int + axisXLabelGap int + topValue float64 + bottomValue float64 + labelX [][]rune + labelY [][]rune + labelYSpace int + maxY float64 + minY float64 + autoLabels bool +} + +// NewLineChart returns a new LineChart with current theme. +func NewLineChart() *LineChart { + lc := &LineChart{Block: *NewBlock()} + lc.AxesColor = ThemeAttr("linechart.axes.fg") + lc.LineColor = ThemeAttr("linechart.line.fg") + lc.Mode = "braille" + lc.DotStyle = '•' + lc.axisXLabelGap = 2 + lc.axisYLabelGap = 1 + lc.bottomValue = math.Inf(1) + lc.topValue = math.Inf(-1) + return lc +} + +// one cell contains two data points +// so the capicity is 2x as dot-mode +func (lc *LineChart) renderBraille() Buffer { + buf := NewBuffer() + + // return: b -> which cell should the point be in + // m -> in the cell, divided into 4 equal height levels, which subcell? + getPos := func(d float64) (b, m int) { + cnt4 := int((d-lc.bottomValue)/(lc.scale/4) + 0.5) + b = cnt4 / 4 + m = cnt4 % 4 + return + } + // plot points + for i := 0; 2*i+1 < len(lc.Data) && i < lc.axisXWidth; i++ { + b0, m0 := getPos(lc.Data[2*i]) + b1, m1 := getPos(lc.Data[2*i+1]) + + if b0 == b1 { + c := Cell{ + Ch: braillePatterns[[2]int{m0, m1}], + Bg: lc.Bg, + Fg: lc.LineColor, + } + y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0 + x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i + buf.Set(x, y, c) + } else { + c0 := Cell{Ch: lSingleBraille[m0], + Fg: lc.LineColor, + Bg: lc.Bg} + x0 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i + y0 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0 + buf.Set(x0, y0, c0) + + c1 := Cell{Ch: rSingleBraille[m1], + Fg: lc.LineColor, + Bg: lc.Bg} + x1 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i + y1 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b1 + buf.Set(x1, y1, c1) + } + + } + return buf +} + +func (lc *LineChart) renderDot() Buffer { + buf := NewBuffer() + for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ { + c := Cell{ + Ch: lc.DotStyle, + Fg: lc.LineColor, + Bg: lc.Bg, + } + x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i + y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5) + buf.Set(x, y, c) + } + + return buf +} + +func (lc *LineChart) calcLabelX() { + lc.labelX = [][]rune{} + + for i, l := 0, 0; i < len(lc.DataLabels) && l < lc.axisXWidth; i++ { + if lc.Mode == "dot" { + if l >= len(lc.DataLabels) { + break + } + + s := str2runes(lc.DataLabels[l]) + w := strWidth(lc.DataLabels[l]) + if l+w <= lc.axisXWidth { + lc.labelX = append(lc.labelX, s) + } + l += w + lc.axisXLabelGap + } else { // braille + if 2*l >= len(lc.DataLabels) { + break + } + + s := str2runes(lc.DataLabels[2*l]) + w := strWidth(lc.DataLabels[2*l]) + if l+w <= lc.axisXWidth { + lc.labelX = append(lc.labelX, s) + } + l += w + lc.axisXLabelGap + + } + } +} + +func shortenFloatVal(x float64) string { + s := fmt.Sprintf("%.2f", x) + if len(s)-3 > 3 { + s = fmt.Sprintf("%.2e", x) + } + + if x < 0 { + s = fmt.Sprintf("%.2f", x) + } + return s +} + +func (lc *LineChart) calcLabelY() { + span := lc.topValue - lc.bottomValue + lc.scale = span / float64(lc.axisYHeight) + + n := (1 + lc.axisYHeight) / (lc.axisYLabelGap + 1) + lc.labelY = make([][]rune, n) + maxLen := 0 + for i := 0; i < n; i++ { + s := str2runes(shortenFloatVal(lc.bottomValue + float64(i)*span/float64(n))) + if len(s) > maxLen { + maxLen = len(s) + } + lc.labelY[i] = s + } + + lc.labelYSpace = maxLen +} + +func (lc *LineChart) calcLayout() { + // set datalabels if it is not provided + if (lc.DataLabels == nil || len(lc.DataLabels) == 0) || lc.autoLabels { + lc.autoLabels = true + lc.DataLabels = make([]string, len(lc.Data)) + for i := range lc.Data { + lc.DataLabels[i] = fmt.Sprint(i) + } + } + + // lazy increase, to avoid y shaking frequently + // update bound Y when drawing is gonna overflow + lc.minY = lc.Data[0] + lc.maxY = lc.Data[0] + + // valid visible range + vrange := lc.innerArea.Dx() + if lc.Mode == "braille" { + vrange = 2 * lc.innerArea.Dx() + } + if vrange > len(lc.Data) { + vrange = len(lc.Data) + } + + for _, v := range lc.Data[:vrange] { + if v > lc.maxY { + lc.maxY = v + } + if v < lc.minY { + lc.minY = v + } + } + + span := lc.maxY - lc.minY + + if lc.minY < lc.bottomValue { + lc.bottomValue = lc.minY - 0.2*span + } + + if lc.maxY > lc.topValue { + lc.topValue = lc.maxY + 0.2*span + } + + lc.axisYHeight = lc.innerArea.Dy() - 2 + lc.calcLabelY() + + lc.axisXWidth = lc.innerArea.Dx() - 1 - lc.labelYSpace + lc.calcLabelX() + + lc.drawingX = lc.innerArea.Min.X + 1 + lc.labelYSpace + lc.drawingY = lc.innerArea.Min.Y +} + +func (lc *LineChart) plotAxes() Buffer { + buf := NewBuffer() + + origY := lc.innerArea.Min.Y + lc.innerArea.Dy() - 2 + origX := lc.innerArea.Min.X + lc.labelYSpace + + buf.Set(origX, origY, Cell{Ch: ORIGIN, Fg: lc.AxesColor, Bg: lc.Bg}) + + for x := origX + 1; x < origX+lc.axisXWidth; x++ { + buf.Set(x, origY, Cell{Ch: HDASH, Fg: lc.AxesColor, Bg: lc.Bg}) + } + + for dy := 1; dy <= lc.axisYHeight; dy++ { + buf.Set(origX, origY-dy, Cell{Ch: VDASH, Fg: lc.AxesColor, Bg: lc.Bg}) + } + + // x label + oft := 0 + for _, rs := range lc.labelX { + if oft+len(rs) > lc.axisXWidth { + break + } + for j, r := range rs { + c := Cell{ + Ch: r, + Fg: lc.AxesColor, + Bg: lc.Bg, + } + x := origX + oft + j + y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 1 + buf.Set(x, y, c) + } + oft += len(rs) + lc.axisXLabelGap + } + + // y labels + for i, rs := range lc.labelY { + for j, r := range rs { + buf.Set( + lc.innerArea.Min.X+j, + origY-i*(lc.axisYLabelGap+1), + Cell{Ch: r, Fg: lc.AxesColor, Bg: lc.Bg}) + } + } + + return buf +} + +// Buffer implements Bufferer interface. +func (lc *LineChart) Buffer() Buffer { + buf := lc.Block.Buffer() + + if lc.Data == nil || len(lc.Data) == 0 { + return buf + } + lc.calcLayout() + buf.Merge(lc.plotAxes()) + + if lc.Mode == "dot" { + buf.Merge(lc.renderDot()) + } else { + buf.Merge(lc.renderBraille()) + } + + return buf +} diff --git a/vendor/github.com/gizak/termui/linechart_others.go b/vendor/github.com/gizak/termui/linechart_others.go new file mode 100644 index 0000000..14897ea --- /dev/null +++ b/vendor/github.com/gizak/termui/linechart_others.go @@ -0,0 +1,11 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +// +build !windows + +package termui + +const VDASH = '┊' +const HDASH = '┈' +const ORIGIN = '└' diff --git a/vendor/github.com/gizak/termui/linechart_windows.go b/vendor/github.com/gizak/termui/linechart_windows.go new file mode 100644 index 0000000..994d3e5 --- /dev/null +++ b/vendor/github.com/gizak/termui/linechart_windows.go @@ -0,0 +1,11 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +// +build windows + +package termui + +const VDASH = '|' +const HDASH = '-' +const ORIGIN = '+' diff --git a/vendor/github.com/gizak/termui/list.go b/vendor/github.com/gizak/termui/list.go new file mode 100644 index 0000000..ea6635e --- /dev/null +++ b/vendor/github.com/gizak/termui/list.go @@ -0,0 +1,89 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "strings" + +// List displays []string as its items, +// it has a Overflow option (default is "hidden"), when set to "hidden", +// the item exceeding List's width is truncated, but when set to "wrap", +// the overflowed text breaks into next line. +/* + strs := []string{ + "[0] github.com/gizak/termui", + "[1] editbox.go", + "[2] iterrupt.go", + "[3] keyboard.go", + "[4] output.go", + "[5] random_out.go", + "[6] dashboard.go", + "[7] nsf/termbox-go"} + + ls := termui.NewList() + ls.Items = strs + ls.ItemFgColor = termui.ColorYellow + ls.BorderLabel = "List" + ls.Height = 7 + ls.Width = 25 + ls.Y = 0 +*/ +type List struct { + Block + Items []string + Overflow string + ItemFgColor Attribute + ItemBgColor Attribute +} + +// NewList returns a new *List with current theme. +func NewList() *List { + l := &List{Block: *NewBlock()} + l.Overflow = "hidden" + l.ItemFgColor = ThemeAttr("list.item.fg") + l.ItemBgColor = ThemeAttr("list.item.bg") + return l +} + +// Buffer implements Bufferer interface. +func (l *List) Buffer() Buffer { + buf := l.Block.Buffer() + + switch l.Overflow { + case "wrap": + cs := DefaultTxBuilder.Build(strings.Join(l.Items, "\n"), l.ItemFgColor, l.ItemBgColor) + i, j, k := 0, 0, 0 + for i < l.innerArea.Dy() && k < len(cs) { + w := cs[k].Width() + if cs[k].Ch == '\n' || j+w > l.innerArea.Dx() { + i++ + j = 0 + if cs[k].Ch == '\n' { + k++ + } + continue + } + buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, cs[k]) + + k++ + j++ + } + + case "hidden": + trimItems := l.Items + if len(trimItems) > l.innerArea.Dy() { + trimItems = trimItems[:l.innerArea.Dy()] + } + for i, v := range trimItems { + cs := DTrimTxCls(DefaultTxBuilder.Build(v, l.ItemFgColor, l.ItemBgColor), l.innerArea.Dx()) + j := 0 + for _, vv := range cs { + w := vv.Width() + buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, vv) + j += w + } + } + } + return buf +} diff --git a/vendor/github.com/gizak/termui/mbarchart.go b/vendor/github.com/gizak/termui/mbarchart.go new file mode 100644 index 0000000..0f91e97 --- /dev/null +++ b/vendor/github.com/gizak/termui/mbarchart.go @@ -0,0 +1,242 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "fmt" +) + +// This is the implemetation of multi-colored or stacked bar graph. This is different from default barGraph which is implemented in bar.go +// Multi-Colored-BarChart creates multiple bars in a widget: +/* + bc := termui.NewMBarChart() + data := make([][]int, 2) + data[0] := []int{3, 2, 5, 7, 9, 4} + data[1] := []int{7, 8, 5, 3, 1, 6} + bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} + bc.BorderLabel = "Bar Chart" + bc.Data = data + bc.Width = 26 + bc.Height = 10 + bc.DataLabels = bclabels + bc.TextColor = termui.ColorGreen + bc.BarColor = termui.ColorRed + bc.NumColor = termui.ColorYellow +*/ +type MBarChart struct { + Block + BarColor [NumberofColors]Attribute + TextColor Attribute + NumColor [NumberofColors]Attribute + Data [NumberofColors][]int + DataLabels []string + BarWidth int + BarGap int + labels [][]rune + dataNum [NumberofColors][][]rune + numBar int + scale float64 + max int + minDataLen int + numStack int + ShowScale bool + maxScale []rune +} + +// NewBarChart returns a new *BarChart with current theme. +func NewMBarChart() *MBarChart { + bc := &MBarChart{Block: *NewBlock()} + bc.BarColor[0] = ThemeAttr("mbarchart.bar.bg") + bc.NumColor[0] = ThemeAttr("mbarchart.num.fg") + bc.TextColor = ThemeAttr("mbarchart.text.fg") + bc.BarGap = 1 + bc.BarWidth = 3 + return bc +} + +func (bc *MBarChart) layout() { + bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth) + bc.labels = make([][]rune, bc.numBar) + DataLen := 0 + LabelLen := len(bc.DataLabels) + bc.minDataLen = 9999 //Set this to some very hight value so that we find the minimum one We want to know which array among data[][] has got the least length + + // We need to know how many stack/data array data[0] , data[1] are there + for i := 0; i < len(bc.Data); i++ { + if bc.Data[i] == nil { + break + } + DataLen++ + } + bc.numStack = DataLen + + //We need to know what is the mimimum size of data array data[0] could have 10 elements data[1] could have only 5, so we plot only 5 bar graphs + + for i := 0; i < DataLen; i++ { + if bc.minDataLen > len(bc.Data[i]) { + bc.minDataLen = len(bc.Data[i]) + } + } + + if LabelLen > bc.minDataLen { + LabelLen = bc.minDataLen + } + + for i := 0; i < LabelLen && i < bc.numBar; i++ { + bc.labels[i] = trimStr2Runes(bc.DataLabels[i], bc.BarWidth) + } + + for i := 0; i < bc.numStack; i++ { + bc.dataNum[i] = make([][]rune, len(bc.Data[i])) + //For each stack of bar calcualte the rune + for j := 0; j < LabelLen && i < bc.numBar; j++ { + n := bc.Data[i][j] + s := fmt.Sprint(n) + bc.dataNum[i][j] = trimStr2Runes(s, bc.BarWidth) + } + //If color is not defined by default then populate a color that is different from the prevous bar + if bc.BarColor[i] == ColorDefault && bc.NumColor[i] == ColorDefault { + if i == 0 { + bc.BarColor[i] = ColorBlack + } else { + bc.BarColor[i] = bc.BarColor[i-1] + 1 + if bc.BarColor[i] > NumberofColors { + bc.BarColor[i] = ColorBlack + } + } + bc.NumColor[i] = (NumberofColors + 1) - bc.BarColor[i] //Make NumColor opposite of barColor for visibility + } + } + + //If Max value is not set then we have to populate, this time the max value will be max(sum(d1[0],d2[0],d3[0]) .... sum(d1[n], d2[n], d3[n])) + + if bc.max == 0 { + bc.max = -1 + } + for i := 0; i < bc.minDataLen && i < LabelLen; i++ { + var dsum int + for j := 0; j < bc.numStack; j++ { + dsum += bc.Data[j][i] + } + if dsum > bc.max { + bc.max = dsum + } + } + + //Finally Calculate max sale + if bc.ShowScale { + s := fmt.Sprintf("%d", bc.max) + bc.maxScale = trimStr2Runes(s, len(s)) + bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-2) + } else { + bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1) + } + +} + +func (bc *MBarChart) SetMax(max int) { + + if max > 0 { + bc.max = max + } +} + +// Buffer implements Bufferer interface. +func (bc *MBarChart) Buffer() Buffer { + buf := bc.Block.Buffer() + bc.layout() + var oftX int + + for i := 0; i < bc.numBar && i < bc.minDataLen && i < len(bc.DataLabels); i++ { + ph := 0 //Previous Height to stack up + oftX = i * (bc.BarWidth + bc.BarGap) + for i1 := 0; i1 < bc.numStack; i1++ { + h := int(float64(bc.Data[i1][i]) / bc.scale) + // plot bars + for j := 0; j < bc.BarWidth; j++ { + for k := 0; k < h; k++ { + c := Cell{ + Ch: ' ', + Bg: bc.BarColor[i1], + } + if bc.BarColor[i1] == ColorDefault { // when color is default, space char treated as transparent! + c.Bg |= AttrReverse + } + x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k - ph + buf.Set(x, y, c) + + } + } + ph += h + } + // plot text + for j, k := 0, 0; j < len(bc.labels[i]); j++ { + w := charWidth(bc.labels[i][j]) + c := Cell{ + Ch: bc.labels[i][j], + Bg: bc.Bg, + Fg: bc.TextColor, + } + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1 + x := bc.innerArea.Max.X + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k + buf.Set(x, y, c) + k += w + } + // plot num + ph = 0 //re-initialize previous height + for i1 := 0; i1 < bc.numStack; i1++ { + h := int(float64(bc.Data[i1][i]) / bc.scale) + for j := 0; j < len(bc.dataNum[i1][i]) && h > 0; j++ { + c := Cell{ + Ch: bc.dataNum[i1][i][j], + Fg: bc.NumColor[i1], + Bg: bc.BarColor[i1], + } + if bc.BarColor[i1] == ColorDefault { // the same as above + c.Bg |= AttrReverse + } + if h == 0 { + c.Bg = bc.Bg + } + x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i1][i]))/2 + j + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - ph + buf.Set(x, y, c) + } + ph += h + } + } + + if bc.ShowScale { + //Currently bar graph only supprts data range from 0 to MAX + //Plot 0 + c := Cell{ + Ch: '0', + Bg: bc.Bg, + Fg: bc.TextColor, + } + + y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 + x := bc.X + buf.Set(x, y, c) + + //Plot the maximum sacle value + for i := 0; i < len(bc.maxScale); i++ { + c := Cell{ + Ch: bc.maxScale[i], + Bg: bc.Bg, + Fg: bc.TextColor, + } + + y := bc.innerArea.Min.Y + x := bc.X + i + + buf.Set(x, y, c) + } + + } + + return buf +} diff --git a/vendor/github.com/gizak/termui/mkdocs.yml b/vendor/github.com/gizak/termui/mkdocs.yml new file mode 100644 index 0000000..2ab45f0 --- /dev/null +++ b/vendor/github.com/gizak/termui/mkdocs.yml @@ -0,0 +1,28 @@ +pages: +- Home: 'index.md' +- Quickstart: 'quickstart.md' +- Recipes: 'recipes.md' +- References: + - Layouts: 'layouts.md' + - Components: 'components.md' + - Events: 'events.md' + - Themes: 'themes.md' +- Versions: 'versions.md' +- About: 'about.md' + +site_name: termui +repo_url: https://github.com/gizak/termui/ +site_description: 'termui user guide' +site_author: gizak + +docs_dir: '_docs' + +theme: readthedocs + +markdown_extensions: + - smarty + - admonition + - toc + +extra: + version: 1.0 diff --git a/vendor/github.com/gizak/termui/par.go b/vendor/github.com/gizak/termui/par.go new file mode 100644 index 0000000..29b6d46 --- /dev/null +++ b/vendor/github.com/gizak/termui/par.go @@ -0,0 +1,73 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +// Par displays a paragraph. +/* + par := termui.NewPar("Simple Text") + par.Height = 3 + par.Width = 17 + par.BorderLabel = "Label" +*/ +type Par struct { + Block + Text string + TextFgColor Attribute + TextBgColor Attribute + WrapLength int // words wrap limit. Note it may not work properly with multi-width char +} + +// NewPar returns a new *Par with given text as its content. +func NewPar(s string) *Par { + return &Par{ + Block: *NewBlock(), + Text: s, + TextFgColor: ThemeAttr("par.text.fg"), + TextBgColor: ThemeAttr("par.text.bg"), + WrapLength: 0, + } +} + +// Buffer implements Bufferer interface. +func (p *Par) Buffer() Buffer { + buf := p.Block.Buffer() + + fg, bg := p.TextFgColor, p.TextBgColor + cs := DefaultTxBuilder.Build(p.Text, fg, bg) + + // wrap if WrapLength set + if p.WrapLength < 0 { + cs = wrapTx(cs, p.Width-2) + } else if p.WrapLength > 0 { + cs = wrapTx(cs, p.WrapLength) + } + + y, x, n := 0, 0, 0 + for y < p.innerArea.Dy() && n < len(cs) { + w := cs[n].Width() + if cs[n].Ch == '\n' || x+w > p.innerArea.Dx() { + y++ + x = 0 // set x = 0 + if cs[n].Ch == '\n' { + n++ + } + + if y >= p.innerArea.Dy() { + buf.Set(p.innerArea.Min.X+p.innerArea.Dx()-1, + p.innerArea.Min.Y+p.innerArea.Dy()-1, + Cell{Ch: '…', Fg: p.TextFgColor, Bg: p.TextBgColor}) + break + } + continue + } + + buf.Set(p.innerArea.Min.X+x, p.innerArea.Min.Y+y, cs[n]) + + n++ + x += w + } + + return buf +} diff --git a/vendor/github.com/gizak/termui/par_test.go b/vendor/github.com/gizak/termui/par_test.go new file mode 100644 index 0000000..4d28f4d --- /dev/null +++ b/vendor/github.com/gizak/termui/par_test.go @@ -0,0 +1,24 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "testing" + +func TestPar_NoBorderBackground(t *testing.T) { + par := NewPar("a") + par.Border = false + par.Bg = ColorBlue + par.TextBgColor = ColorBlue + par.Width = 2 + par.Height = 2 + + pts := par.Buffer() + for _, p := range pts.CellMap { + t.Log(p) + if p.Bg != par.Bg { + t.Errorf("expected color to be %v but got %v", par.Bg, p.Bg) + } + } +} diff --git a/vendor/github.com/gizak/termui/pos.go b/vendor/github.com/gizak/termui/pos.go new file mode 100644 index 0000000..c7d647f --- /dev/null +++ b/vendor/github.com/gizak/termui/pos.go @@ -0,0 +1,78 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "image" + +// Align is the position of the gauge's label. +type Align uint + +// All supported positions. +const ( + AlignNone Align = 0 + AlignLeft Align = 1 << iota + AlignRight + AlignBottom + AlignTop + AlignCenterVertical + AlignCenterHorizontal + AlignCenter = AlignCenterVertical | AlignCenterHorizontal +) + +func AlignArea(parent, child image.Rectangle, a Align) image.Rectangle { + w, h := child.Dx(), child.Dy() + + // parent center + pcx, pcy := parent.Min.X+parent.Dx()/2, parent.Min.Y+parent.Dy()/2 + // child center + ccx, ccy := child.Min.X+child.Dx()/2, child.Min.Y+child.Dy()/2 + + if a&AlignLeft == AlignLeft { + child.Min.X = parent.Min.X + child.Max.X = child.Min.X + w + } + + if a&AlignRight == AlignRight { + child.Max.X = parent.Max.X + child.Min.X = child.Max.X - w + } + + if a&AlignBottom == AlignBottom { + child.Max.Y = parent.Max.Y + child.Min.Y = child.Max.Y - h + } + + if a&AlignTop == AlignRight { + child.Min.Y = parent.Min.Y + child.Max.Y = child.Min.Y + h + } + + if a&AlignCenterHorizontal == AlignCenterHorizontal { + child.Min.X += pcx - ccx + child.Max.X = child.Min.X + w + } + + if a&AlignCenterVertical == AlignCenterVertical { + child.Min.Y += pcy - ccy + child.Max.Y = child.Min.Y + h + } + + return child +} + +func MoveArea(a image.Rectangle, dx, dy int) image.Rectangle { + a.Min.X += dx + a.Max.X += dx + a.Min.Y += dy + a.Max.Y += dy + return a +} + +var termWidth int +var termHeight int + +func TermRect() image.Rectangle { + return image.Rect(0, 0, termWidth, termHeight) +} diff --git a/vendor/github.com/gizak/termui/pos_test.go b/vendor/github.com/gizak/termui/pos_test.go new file mode 100644 index 0000000..448876b --- /dev/null +++ b/vendor/github.com/gizak/termui/pos_test.go @@ -0,0 +1,38 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "image" + "testing" +) + +func TestAlignArea(t *testing.T) { + p := image.Rect(0, 0, 100, 100) + c := image.Rect(10, 10, 20, 20) + + nc := AlignArea(p, c, AlignLeft) + if nc.Min.X != 0 || nc.Max.Y != 20 { + t.Errorf("AlignLeft failed:\n%+v", nc) + } + + nc = AlignArea(p, c, AlignCenter) + if nc.Min.X != 45 || nc.Max.Y != 55 { + t.Error("AlignCenter failed") + } + + nc = AlignArea(p, c, AlignBottom|AlignRight) + if nc.Min.X != 90 || nc.Max.Y != 100 { + t.Errorf("AlignBottom|AlignRight failed\n%+v", nc) + } +} + +func TestMoveArea(t *testing.T) { + a := image.Rect(10, 10, 20, 20) + a = MoveArea(a, 5, 10) + if a.Min.X != 15 || a.Min.Y != 20 || a.Max.X != 25 || a.Max.Y != 30 { + t.Error("MoveArea failed") + } +} diff --git a/vendor/github.com/gizak/termui/render.go b/vendor/github.com/gizak/termui/render.go new file mode 100644 index 0000000..5b58409 --- /dev/null +++ b/vendor/github.com/gizak/termui/render.go @@ -0,0 +1,164 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "image" + "io" + "sync" + "time" + + "fmt" + + "os" + + "runtime/debug" + + "bytes" + + "github.com/maruel/panicparse/stack" + tm "github.com/nsf/termbox-go" +) + +// Bufferer should be implemented by all renderable components. +type Bufferer interface { + Buffer() Buffer +} + +// Init initializes termui library. This function should be called before any others. +// After initialization, the library must be finalized by 'Close' function. +func Init() error { + if err := tm.Init(); err != nil { + return err + } + + sysEvtChs = make([]chan Event, 0) + go hookTermboxEvt() + + renderJobs = make(chan []Bufferer) + //renderLock = new(sync.RWMutex) + + Body = NewGrid() + Body.X = 0 + Body.Y = 0 + Body.BgColor = ThemeAttr("bg") + Body.Width = TermWidth() + + DefaultEvtStream.Init() + DefaultEvtStream.Merge("termbox", NewSysEvtCh()) + DefaultEvtStream.Merge("timer", NewTimerCh(time.Second)) + DefaultEvtStream.Merge("custom", usrEvtCh) + + DefaultEvtStream.Handle("/", DefualtHandler) + DefaultEvtStream.Handle("/sys/wnd/resize", func(e Event) { + w := e.Data.(EvtWnd) + Body.Width = w.Width + }) + + DefaultWgtMgr = NewWgtMgr() + DefaultEvtStream.Hook(DefaultWgtMgr.WgtHandlersHook()) + + go func() { + for bs := range renderJobs { + render(bs...) + } + }() + + return nil +} + +// Close finalizes termui library, +// should be called after successful initialization when termui's functionality isn't required anymore. +func Close() { + tm.Close() +} + +var renderLock sync.Mutex + +func termSync() { + renderLock.Lock() + tm.Sync() + termWidth, termHeight = tm.Size() + renderLock.Unlock() +} + +// TermWidth returns the current terminal's width. +func TermWidth() int { + termSync() + return termWidth +} + +// TermHeight returns the current terminal's height. +func TermHeight() int { + termSync() + return termHeight +} + +// Render renders all Bufferer in the given order from left to right, +// right could overlap on left ones. +func render(bs ...Bufferer) { + defer func() { + if e := recover(); e != nil { + Close() + fmt.Fprintf(os.Stderr, "Captured a panic(value=%v) when rendering Bufferer. Exit termui and clean terminal...\nPrint stack trace:\n\n", e) + //debug.PrintStack() + gs, err := stack.ParseDump(bytes.NewReader(debug.Stack()), os.Stderr) + if err != nil { + debug.PrintStack() + os.Exit(1) + } + p := &stack.Palette{} + buckets := stack.SortBuckets(stack.Bucketize(gs, stack.AnyValue)) + srcLen, pkgLen := stack.CalcLengths(buckets, false) + for _, bucket := range buckets { + io.WriteString(os.Stdout, p.BucketHeader(&bucket, false, len(buckets) > 1)) + io.WriteString(os.Stdout, p.StackLines(&bucket.Signature, srcLen, pkgLen, false)) + } + os.Exit(1) + } + }() + for _, b := range bs { + + buf := b.Buffer() + // set cels in buf + for p, c := range buf.CellMap { + if p.In(buf.Area) { + + tm.SetCell(p.X, p.Y, c.Ch, toTmAttr(c.Fg), toTmAttr(c.Bg)) + + } + } + + } + + renderLock.Lock() + // render + tm.Flush() + renderLock.Unlock() +} + +func Clear() { + tm.Clear(tm.ColorDefault, toTmAttr(ThemeAttr("bg"))) +} + +func clearArea(r image.Rectangle, bg Attribute) { + for i := r.Min.X; i < r.Max.X; i++ { + for j := r.Min.Y; j < r.Max.Y; j++ { + tm.SetCell(i, j, ' ', tm.ColorDefault, toTmAttr(bg)) + } + } +} + +func ClearArea(r image.Rectangle, bg Attribute) { + clearArea(r, bg) + tm.Flush() +} + +var renderJobs chan []Bufferer + +func Render(bs ...Bufferer) { + //go func() { renderJobs <- bs }() + renderJobs <- bs +} diff --git a/vendor/github.com/gizak/termui/sparkline.go b/vendor/github.com/gizak/termui/sparkline.go new file mode 100644 index 0000000..d906e49 --- /dev/null +++ b/vendor/github.com/gizak/termui/sparkline.go @@ -0,0 +1,167 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +// Sparkline is like: ▅▆▂▂▅▇▂▂▃▆▆▆▅▃. The data points should be non-negative integers. +/* + data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1} + spl := termui.NewSparkline() + spl.Data = data + spl.Title = "Sparkline 0" + spl.LineColor = termui.ColorGreen +*/ +type Sparkline struct { + Data []int + Height int + Title string + TitleColor Attribute + LineColor Attribute + displayHeight int + scale float32 + max int +} + +// Sparklines is a renderable widget which groups together the given sparklines. +/* + spls := termui.NewSparklines(spl0,spl1,spl2) //... + spls.Height = 2 + spls.Width = 20 +*/ +type Sparklines struct { + Block + Lines []Sparkline + displayLines int + displayWidth int +} + +var sparks = []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'} + +// Add appends a given Sparkline to s *Sparklines. +func (s *Sparklines) Add(sl Sparkline) { + s.Lines = append(s.Lines, sl) +} + +// NewSparkline returns a unrenderable single sparkline that intended to be added into Sparklines. +func NewSparkline() Sparkline { + return Sparkline{ + Height: 1, + TitleColor: ThemeAttr("sparkline.title.fg"), + LineColor: ThemeAttr("sparkline.line.fg")} +} + +// NewSparklines return a new *Spaklines with given Sparkline(s), you can always add a new Sparkline later. +func NewSparklines(ss ...Sparkline) *Sparklines { + s := &Sparklines{Block: *NewBlock(), Lines: ss} + return s +} + +func (sl *Sparklines) update() { + for i, v := range sl.Lines { + if v.Title == "" { + sl.Lines[i].displayHeight = v.Height + } else { + sl.Lines[i].displayHeight = v.Height + 1 + } + } + sl.displayWidth = sl.innerArea.Dx() + + // get how many lines gotta display + h := 0 + sl.displayLines = 0 + for _, v := range sl.Lines { + if h+v.displayHeight <= sl.innerArea.Dy() { + sl.displayLines++ + } else { + break + } + h += v.displayHeight + } + + for i := 0; i < sl.displayLines; i++ { + data := sl.Lines[i].Data + + max := 0 + for _, v := range data { + if max < v { + max = v + } + } + sl.Lines[i].max = max + if max != 0 { + sl.Lines[i].scale = float32(8*sl.Lines[i].Height) / float32(max) + } else { // when all negative + sl.Lines[i].scale = 0 + } + } +} + +// Buffer implements Bufferer interface. +func (sl *Sparklines) Buffer() Buffer { + buf := sl.Block.Buffer() + sl.update() + + oftY := 0 + for i := 0; i < sl.displayLines; i++ { + l := sl.Lines[i] + data := l.Data + + if len(data) > sl.innerArea.Dx() { + data = data[len(data)-sl.innerArea.Dx():] + } + + if l.Title != "" { + rs := trimStr2Runes(l.Title, sl.innerArea.Dx()) + oftX := 0 + for _, v := range rs { + w := charWidth(v) + c := Cell{ + Ch: v, + Fg: l.TitleColor, + Bg: sl.Bg, + } + x := sl.innerArea.Min.X + oftX + y := sl.innerArea.Min.Y + oftY + buf.Set(x, y, c) + oftX += w + } + } + + for j, v := range data { + // display height of the data point, zero when data is negative + h := int(float32(v)*l.scale + 0.5) + if v < 0 { + h = 0 + } + + barCnt := h / 8 + barMod := h % 8 + for jj := 0; jj < barCnt; jj++ { + c := Cell{ + Ch: ' ', // => sparks[7] + Bg: l.LineColor, + } + x := sl.innerArea.Min.X + j + y := sl.innerArea.Min.Y + oftY + l.Height - jj + + //p.Bg = sl.BgColor + buf.Set(x, y, c) + } + if barMod != 0 { + c := Cell{ + Ch: sparks[barMod-1], + Fg: l.LineColor, + Bg: sl.Bg, + } + x := sl.innerArea.Min.X + j + y := sl.innerArea.Min.Y + oftY + l.Height - barCnt + buf.Set(x, y, c) + } + } + + oftY += l.displayHeight + } + + return buf +} diff --git a/vendor/github.com/gizak/termui/table.go b/vendor/github.com/gizak/termui/table.go new file mode 100644 index 0000000..e3d1bbf --- /dev/null +++ b/vendor/github.com/gizak/termui/table.go @@ -0,0 +1,185 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "strings" + +/* Table is like: + +┌Awesome Table ────────────────────────────────────────────────┐ +│ Col0 | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | +│──────────────────────────────────────────────────────────────│ +│ Some Item #1 | AAA | 123 | CCCCC | EEEEE | GGGGG | IIIII | +│──────────────────────────────────────────────────────────────│ +│ Some Item #2 | BBB | 456 | DDDDD | FFFFF | HHHHH | JJJJJ | +└──────────────────────────────────────────────────────────────┘ + +Datapoints are a two dimensional array of strings: [][]string + +Example: + data := [][]string{ + {"Col0", "Col1", "Col3", "Col4", "Col5", "Col6"}, + {"Some Item #1", "AAA", "123", "CCCCC", "EEEEE", "GGGGG", "IIIII"}, + {"Some Item #2", "BBB", "456", "DDDDD", "FFFFF", "HHHHH", "JJJJJ"}, + } + + table := termui.NewTable() + table.Rows = data // type [][]string + table.FgColor = termui.ColorWhite + table.BgColor = termui.ColorDefault + table.Height = 7 + table.Width = 62 + table.Y = 0 + table.X = 0 + table.Border = true +*/ + +// Table tracks all the attributes of a Table instance +type Table struct { + Block + Rows [][]string + CellWidth []int + FgColor Attribute + BgColor Attribute + FgColors []Attribute + BgColors []Attribute + Separator bool + TextAlign Align +} + +// NewTable returns a new Table instance +func NewTable() *Table { + table := &Table{Block: *NewBlock()} + table.FgColor = ColorWhite + table.BgColor = ColorDefault + table.Separator = true + return table +} + +// CellsWidth calculates the width of a cell array and returns an int +func cellsWidth(cells []Cell) int { + width := 0 + for _, c := range cells { + width += c.Width() + } + return width +} + +// Analysis generates and returns an array of []Cell that represent all columns in the Table +func (table *Table) Analysis() [][]Cell { + var rowCells [][]Cell + length := len(table.Rows) + if length < 1 { + return rowCells + } + + if len(table.FgColors) == 0 { + table.FgColors = make([]Attribute, len(table.Rows)) + } + if len(table.BgColors) == 0 { + table.BgColors = make([]Attribute, len(table.Rows)) + } + + cellWidths := make([]int, len(table.Rows[0])) + + for y, row := range table.Rows { + if table.FgColors[y] == 0 { + table.FgColors[y] = table.FgColor + } + if table.BgColors[y] == 0 { + table.BgColors[y] = table.BgColor + } + for x, str := range row { + cells := DefaultTxBuilder.Build(str, table.FgColors[y], table.BgColors[y]) + cw := cellsWidth(cells) + if cellWidths[x] < cw { + cellWidths[x] = cw + } + rowCells = append(rowCells, cells) + } + } + table.CellWidth = cellWidths + return rowCells +} + +// SetSize calculates the table size and sets the internal value +func (table *Table) SetSize() { + length := len(table.Rows) + if table.Separator { + table.Height = length*2 + 1 + } else { + table.Height = length + 2 + } + table.Width = 2 + if length != 0 { + for _, cellWidth := range table.CellWidth { + table.Width += cellWidth + 3 + } + } +} + +// CalculatePosition ... +func (table *Table) CalculatePosition(x int, y int, coordinateX *int, coordinateY *int, cellStart *int) { + if table.Separator { + *coordinateY = table.innerArea.Min.Y + y*2 + } else { + *coordinateY = table.innerArea.Min.Y + y + } + if x == 0 { + *cellStart = table.innerArea.Min.X + } else { + *cellStart += table.CellWidth[x-1] + 3 + } + + switch table.TextAlign { + case AlignRight: + *coordinateX = *cellStart + (table.CellWidth[x] - len(table.Rows[y][x])) + 2 + case AlignCenter: + *coordinateX = *cellStart + (table.CellWidth[x]-len(table.Rows[y][x]))/2 + 2 + default: + *coordinateX = *cellStart + 2 + } +} + +// Buffer ... +func (table *Table) Buffer() Buffer { + buffer := table.Block.Buffer() + rowCells := table.Analysis() + pointerX := table.innerArea.Min.X + 2 + pointerY := table.innerArea.Min.Y + borderPointerX := table.innerArea.Min.X + for y, row := range table.Rows { + for x := range row { + table.CalculatePosition(x, y, &pointerX, &pointerY, &borderPointerX) + background := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+3), table.BgColors[y], table.BgColors[y]) + cells := rowCells[y*len(row)+x] + for i, back := range background { + buffer.Set(borderPointerX+i, pointerY, back) + } + + coordinateX := pointerX + for _, printer := range cells { + buffer.Set(coordinateX, pointerY, printer) + coordinateX += printer.Width() + } + + if x != 0 { + dividors := DefaultTxBuilder.Build("|", table.FgColors[y], table.BgColors[y]) + for _, dividor := range dividors { + buffer.Set(borderPointerX, pointerY, dividor) + } + } + } + + if table.Separator { + border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) + for i, cell := range border { + buffer.Set(i+1, pointerY+1, cell) + } + } + } + + return buffer +} diff --git a/vendor/github.com/gizak/termui/textbuilder.go b/vendor/github.com/gizak/termui/textbuilder.go new file mode 100644 index 0000000..12e2055 --- /dev/null +++ b/vendor/github.com/gizak/termui/textbuilder.go @@ -0,0 +1,278 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "regexp" + "strings" + + "github.com/mitchellh/go-wordwrap" +) + +// TextBuilder is a minimal interface to produce text []Cell using specific syntax (markdown). +type TextBuilder interface { + Build(s string, fg, bg Attribute) []Cell +} + +// DefaultTxBuilder is set to be MarkdownTxBuilder. +var DefaultTxBuilder = NewMarkdownTxBuilder() + +// MarkdownTxBuilder implements TextBuilder interface, using markdown syntax. +type MarkdownTxBuilder struct { + baseFg Attribute + baseBg Attribute + plainTx []rune + markers []marker +} + +type marker struct { + st int + ed int + fg Attribute + bg Attribute +} + +var colorMap = map[string]Attribute{ + "red": ColorRed, + "blue": ColorBlue, + "black": ColorBlack, + "cyan": ColorCyan, + "yellow": ColorYellow, + "white": ColorWhite, + "default": ColorDefault, + "green": ColorGreen, + "magenta": ColorMagenta, +} + +var attrMap = map[string]Attribute{ + "bold": AttrBold, + "underline": AttrUnderline, + "reverse": AttrReverse, +} + +func rmSpc(s string) string { + reg := regexp.MustCompile(`\s+`) + return reg.ReplaceAllString(s, "") +} + +// readAttr translates strings like `fg-red,fg-bold,bg-white` to fg and bg Attribute +func (mtb MarkdownTxBuilder) readAttr(s string) (Attribute, Attribute) { + fg := mtb.baseFg + bg := mtb.baseBg + + updateAttr := func(a Attribute, attrs []string) Attribute { + for _, s := range attrs { + // replace the color + if c, ok := colorMap[s]; ok { + a &= 0xFF00 // erase clr 0 ~ 8 bits + a |= c // set clr + } + // add attrs + if c, ok := attrMap[s]; ok { + a |= c + } + } + return a + } + + ss := strings.Split(s, ",") + fgs := []string{} + bgs := []string{} + for _, v := range ss { + subs := strings.Split(v, "-") + if len(subs) > 1 { + if subs[0] == "fg" { + fgs = append(fgs, subs[1]) + } + if subs[0] == "bg" { + bgs = append(bgs, subs[1]) + } + } + } + + fg = updateAttr(fg, fgs) + bg = updateAttr(bg, bgs) + return fg, bg +} + +func (mtb *MarkdownTxBuilder) reset() { + mtb.plainTx = []rune{} + mtb.markers = []marker{} +} + +// parse streams and parses text into normalized text and render sequence. +func (mtb *MarkdownTxBuilder) parse(str string) { + rs := str2runes(str) + normTx := []rune{} + square := []rune{} + brackt := []rune{} + accSquare := false + accBrackt := false + cntSquare := 0 + + reset := func() { + square = []rune{} + brackt = []rune{} + accSquare = false + accBrackt = false + cntSquare = 0 + } + // pipe stacks into normTx and clear + rollback := func() { + normTx = append(normTx, square...) + normTx = append(normTx, brackt...) + reset() + } + // chop first and last + chop := func(s []rune) []rune { + return s[1 : len(s)-1] + } + + for i, r := range rs { + switch { + // stacking brackt + case accBrackt: + brackt = append(brackt, r) + if ')' == r { + fg, bg := mtb.readAttr(string(chop(brackt))) + st := len(normTx) + ed := len(normTx) + len(square) - 2 + mtb.markers = append(mtb.markers, marker{st, ed, fg, bg}) + normTx = append(normTx, chop(square)...) + reset() + } else if i+1 == len(rs) { + rollback() + } + // stacking square + case accSquare: + switch { + // squares closed and followed by a '(' + case cntSquare == 0 && '(' == r: + accBrackt = true + brackt = append(brackt, '(') + // squares closed but not followed by a '(' + case cntSquare == 0: + rollback() + if '[' == r { + accSquare = true + cntSquare = 1 + brackt = append(brackt, '[') + } else { + normTx = append(normTx, r) + } + // hit the end + case i+1 == len(rs): + square = append(square, r) + rollback() + case '[' == r: + cntSquare++ + square = append(square, '[') + case ']' == r: + cntSquare-- + square = append(square, ']') + // normal char + default: + square = append(square, r) + } + // stacking normTx + default: + if '[' == r { + accSquare = true + cntSquare = 1 + square = append(square, '[') + } else { + normTx = append(normTx, r) + } + } + } + + mtb.plainTx = normTx +} + +func wrapTx(cs []Cell, wl int) []Cell { + tmpCell := make([]Cell, len(cs)) + copy(tmpCell, cs) + + // get the plaintext + plain := CellsToStr(cs) + + // wrap + plainWrapped := wordwrap.WrapString(plain, uint(wl)) + + // find differences and insert + finalCell := tmpCell // finalcell will get the inserts and is what is returned + + plainRune := []rune(plain) + plainWrappedRune := []rune(plainWrapped) + trigger := "go" + plainRuneNew := plainRune + + for trigger != "stop" { + plainRune = plainRuneNew + for i := range plainRune { + if plainRune[i] == plainWrappedRune[i] { + trigger = "stop" + } else if plainRune[i] != plainWrappedRune[i] && plainWrappedRune[i] == 10 { + trigger = "go" + cell := Cell{10, 0, 0} + j := i - 0 + + // insert a cell into the []Cell in correct position + tmpCell[i] = cell + + // insert the newline into plain so we avoid indexing errors + plainRuneNew = append(plainRune, 10) + copy(plainRuneNew[j+1:], plainRuneNew[j:]) + plainRuneNew[j] = plainWrappedRune[j] + + // restart the inner for loop until plain and plain wrapped are + // the same; yeah, it's inefficient, but the text amounts + // should be small + break + + } else if plainRune[i] != plainWrappedRune[i] && + plainWrappedRune[i-1] == 10 && // if the prior rune is a newline + plainRune[i] == 32 { // and this rune is a space + trigger = "go" + // need to delete plainRune[i] because it gets rid of an extra + // space + plainRuneNew = append(plainRune[:i], plainRune[i+1:]...) + break + + } else { + trigger = "stop" // stops the outer for loop + } + } + } + + finalCell = tmpCell + + return finalCell +} + +// Build implements TextBuilder interface. +func (mtb MarkdownTxBuilder) Build(s string, fg, bg Attribute) []Cell { + mtb.baseFg = fg + mtb.baseBg = bg + mtb.reset() + mtb.parse(s) + cs := make([]Cell, len(mtb.plainTx)) + for i := range cs { + cs[i] = Cell{Ch: mtb.plainTx[i], Fg: fg, Bg: bg} + } + for _, mrk := range mtb.markers { + for i := mrk.st; i < mrk.ed; i++ { + cs[i].Fg = mrk.fg + cs[i].Bg = mrk.bg + } + } + + return cs +} + +// NewMarkdownTxBuilder returns a TextBuilder employing markdown syntax. +func NewMarkdownTxBuilder() TextBuilder { + return MarkdownTxBuilder{} +} diff --git a/vendor/github.com/gizak/termui/textbuilder_test.go b/vendor/github.com/gizak/termui/textbuilder_test.go new file mode 100644 index 0000000..8f458ec --- /dev/null +++ b/vendor/github.com/gizak/termui/textbuilder_test.go @@ -0,0 +1,70 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "testing" + +func TestReadAttr(t *testing.T) { + m := MarkdownTxBuilder{} + m.baseFg = ColorCyan | AttrUnderline + m.baseBg = ColorBlue | AttrBold + fg, bg := m.readAttr("fg-red,bg-reverse") + if fg != ColorRed|AttrUnderline || bg != ColorBlue|AttrBold|AttrReverse { + t.Error("readAttr failed") + } +} + +func TestMTBParse(t *testing.T) { + /* + str := func(cs []Cell) string { + rs := make([]rune, len(cs)) + for i := range cs { + rs[i] = cs[i].Ch + } + return string(rs) + } + */ + + tbls := [][]string{ + {"hello world", "hello world"}, + {"[hello](fg-red) world", "hello world"}, + {"[[hello]](bg-red) world", "[hello] world"}, + {"[1] hello world", "[1] hello world"}, + {"[[1]](bg-white) [hello] world", "[1] [hello] world"}, + {"[hello world]", "[hello world]"}, + {"", ""}, + {"[hello world)", "[hello world)"}, + {"[0] [hello](bg-red)[ world](fg-blue)!", "[0] hello world!"}, + } + + m := MarkdownTxBuilder{} + m.baseFg = ColorWhite + m.baseBg = ColorDefault + for _, s := range tbls { + m.reset() + m.parse(s[0]) + res := string(m.plainTx) + if s[1] != res { + t.Errorf("\ninput :%s\nshould:%s\noutput:%s", s[0], s[1], res) + } + } + + m.reset() + m.parse("[0] [hello](bg-red)[ world](fg-blue)") + if len(m.markers) != 2 && + m.markers[0].st == 4 && + m.markers[0].ed == 11 && + m.markers[0].fg == ColorWhite && + m.markers[0].bg == ColorRed { + t.Error("markers dismatch") + } + + m2 := NewMarkdownTxBuilder() + cs := m2.Build("[0] [hellob-e) wrd]fgblue)!", ColorWhite, ColorBlack) + cs = m2.Build("[0] [hello](bg-red) [world](fg-blue)!", ColorWhite, ColorBlack) + if cs[4].Ch != 'h' && cs[4].Bg != ColorRed && cs[4].Fg != ColorWhite { + t.Error("dismatch in Build") + } +} diff --git a/vendor/github.com/gizak/termui/theme.go b/vendor/github.com/gizak/termui/theme.go new file mode 100644 index 0000000..21fb3bf --- /dev/null +++ b/vendor/github.com/gizak/termui/theme.go @@ -0,0 +1,140 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "strings" + +/* +// A ColorScheme represents the current look-and-feel of the dashboard. +type ColorScheme struct { + BodyBg Attribute + BlockBg Attribute + HasBorder bool + BorderFg Attribute + BorderBg Attribute + BorderLabelTextFg Attribute + BorderLabelTextBg Attribute + ParTextFg Attribute + ParTextBg Attribute + SparklineLine Attribute + SparklineTitle Attribute + GaugeBar Attribute + GaugePercent Attribute + LineChartLine Attribute + LineChartAxes Attribute + ListItemFg Attribute + ListItemBg Attribute + BarChartBar Attribute + BarChartText Attribute + BarChartNum Attribute + MBarChartBar Attribute + MBarChartText Attribute + MBarChartNum Attribute + TabActiveBg Attribute +} + +// default color scheme depends on the user's terminal setting. +var themeDefault = ColorScheme{HasBorder: true} + +var themeHelloWorld = ColorScheme{ + BodyBg: ColorBlack, + BlockBg: ColorBlack, + HasBorder: true, + BorderFg: ColorWhite, + BorderBg: ColorBlack, + BorderLabelTextBg: ColorBlack, + BorderLabelTextFg: ColorGreen, + ParTextBg: ColorBlack, + ParTextFg: ColorWhite, + SparklineLine: ColorMagenta, + SparklineTitle: ColorWhite, + GaugeBar: ColorRed, + GaugePercent: ColorWhite, + LineChartLine: ColorYellow | AttrBold, + LineChartAxes: ColorWhite, + ListItemBg: ColorBlack, + ListItemFg: ColorYellow, + BarChartBar: ColorRed, + BarChartNum: ColorWhite, + BarChartText: ColorCyan, + MBarChartBar: ColorRed, + MBarChartNum: ColorWhite, + MBarChartText: ColorCyan, + TabActiveBg: ColorMagenta, +} + +var theme = themeDefault // global dep + +// Theme returns the currently used theme. +func Theme() ColorScheme { + return theme +} + +// SetTheme sets a new, custom theme. +func SetTheme(newTheme ColorScheme) { + theme = newTheme +} + +// UseTheme sets a predefined scheme. Currently available: "hello-world" and +// "black-and-white". +func UseTheme(th string) { + switch th { + case "helloworld": + theme = themeHelloWorld + default: + theme = themeDefault + } +} +*/ + +var ColorMap = map[string]Attribute{ + "fg": ColorWhite, + "bg": ColorDefault, + "border.fg": ColorWhite, + "label.fg": ColorGreen, + "par.fg": ColorYellow, + "par.label.bg": ColorWhite, +} + +func ThemeAttr(name string) Attribute { + return lookUpAttr(ColorMap, name) +} + +func lookUpAttr(clrmap map[string]Attribute, name string) Attribute { + + a, ok := clrmap[name] + if ok { + return a + } + + ns := strings.Split(name, ".") + for i := range ns { + nn := strings.Join(ns[i:len(ns)], ".") + a, ok = ColorMap[nn] + if ok { + break + } + } + + return a +} + +// 0<=r,g,b <= 5 +func ColorRGB(r, g, b int) Attribute { + within := func(n int) int { + if n < 0 { + return 0 + } + + if n > 5 { + return 5 + } + + return n + } + + r, b, g = within(r), within(b), within(g) + return Attribute(0x0f + 36*r + 6*g + b) +} diff --git a/vendor/github.com/gizak/termui/theme_test.go b/vendor/github.com/gizak/termui/theme_test.go new file mode 100644 index 0000000..f3d327c --- /dev/null +++ b/vendor/github.com/gizak/termui/theme_test.go @@ -0,0 +1,35 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import "testing" + +var cmap = map[string]Attribute{ + "fg": ColorWhite, + "bg": ColorDefault, + "border.fg": ColorWhite, + "label.fg": ColorGreen, + "par.fg": ColorYellow, + "par.label.bg": ColorWhite, +} + +func TestLoopUpAttr(t *testing.T) { + tbl := []struct { + name string + should Attribute + }{ + {"par.label.bg", ColorWhite}, + {"par.label.fg", ColorGreen}, + {"par.bg", ColorDefault}, + {"bar.border.fg", ColorWhite}, + {"bar.label.bg", ColorDefault}, + } + + for _, v := range tbl { + if lookUpAttr(cmap, v.name) != v.should { + t.Error(v.name) + } + } +} diff --git a/vendor/github.com/gizak/termui/widget.go b/vendor/github.com/gizak/termui/widget.go new file mode 100644 index 0000000..80276bf --- /dev/null +++ b/vendor/github.com/gizak/termui/widget.go @@ -0,0 +1,94 @@ +// Copyright 2017 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. + +package termui + +import ( + "fmt" + "sync" +) + +// event mixins +type WgtMgr map[string]WgtInfo + +type WgtInfo struct { + Handlers map[string]func(Event) + WgtRef Widget + Id string +} + +type Widget interface { + Id() string +} + +func NewWgtInfo(wgt Widget) WgtInfo { + return WgtInfo{ + Handlers: make(map[string]func(Event)), + WgtRef: wgt, + Id: wgt.Id(), + } +} + +func NewWgtMgr() WgtMgr { + wm := WgtMgr(make(map[string]WgtInfo)) + return wm + +} + +func (wm WgtMgr) AddWgt(wgt Widget) { + wm[wgt.Id()] = NewWgtInfo(wgt) +} + +func (wm WgtMgr) RmWgt(wgt Widget) { + wm.RmWgtById(wgt.Id()) +} + +func (wm WgtMgr) RmWgtById(id string) { + delete(wm, id) +} + +func (wm WgtMgr) AddWgtHandler(id, path string, h func(Event)) { + if w, ok := wm[id]; ok { + w.Handlers[path] = h + } +} + +func (wm WgtMgr) RmWgtHandler(id, path string) { + if w, ok := wm[id]; ok { + delete(w.Handlers, path) + } +} + +var counter struct { + sync.RWMutex + count int +} + +func GenId() string { + counter.Lock() + defer counter.Unlock() + + counter.count += 1 + return fmt.Sprintf("%d", counter.count) +} + +func (wm WgtMgr) WgtHandlersHook() func(Event) { + return func(e Event) { + for _, v := range wm { + if k := findMatch(v.Handlers, e.Path); k != "" { + v.Handlers[k](e) + } + } + } +} + +var DefaultWgtMgr WgtMgr + +func (b *Block) Handle(path string, handler func(Event)) { + if _, ok := DefaultWgtMgr[b.Id()]; !ok { + DefaultWgtMgr.AddWgt(b) + } + + DefaultWgtMgr.AddWgtHandler(b.Id(), path, handler) +} diff --git a/vendor/github.com/gosuri/uilive/.travis.yml b/vendor/github.com/gosuri/uilive/.travis.yml deleted file mode 100644 index 04c834a..0000000 --- a/vendor/github.com/gosuri/uilive/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -sudo: false -install: - - go get ./... -go: - - 1.4 - - tip diff --git a/vendor/github.com/gosuri/uilive/LICENSE b/vendor/github.com/gosuri/uilive/LICENSE deleted file mode 100644 index e436d90..0000000 --- a/vendor/github.com/gosuri/uilive/LICENSE +++ /dev/null @@ -1,10 +0,0 @@ -MIT License -=========== - -Copyright (c) 2015, Greg Osuri - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/gosuri/uilive/README.md b/vendor/github.com/gosuri/uilive/README.md deleted file mode 100644 index 5de7d82..0000000 --- a/vendor/github.com/gosuri/uilive/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# uilive [![GoDoc](https://godoc.org/github.com/gosuri/uilive?status.svg)](https://godoc.org/github.com/gosuri/uilive) [![Build Status](https://travis-ci.org/gosuri/uilive.svg?branch=master)](https://travis-ci.org/gosuri/uilive) - -uilive is a go library for updating terminal output in realtime. It provides a buffered [io.Writer](https://golang.org/pkg/io/#Writer) that is flushed at a timed interval. uilive powers [uiprogress](https://github.com/gosuri/uiprogress). - -## Usage Example - -Calling `uilive.New()` will create a new writer. To start rendering, simply call `writer.Start()` and update the ui by writing to the `writer`. Full source for the below example is in [example/main.go](example/main.go). - -```go -writer := uilive.New() -// start listening for updates and render -writer.Start() - -for i := 0; i <= 100; i++ { - fmt.Fprintf(writer, "Downloading.. (%d/%d) GB\n", i, 100) - time.Sleep(time.Millisecond * 5) -} - -fmt.Fprintln(writer, "Finished: Downloaded 100GB") -writer.Stop() // flush and stop rendering -``` - -The above will render - -![example](doc/example.gif) - -## Installation - -```sh -$ go get -v github.com/gosuri/uilive -``` diff --git a/vendor/github.com/gosuri/uilive/doc.go b/vendor/github.com/gosuri/uilive/doc.go deleted file mode 100644 index d481098..0000000 --- a/vendor/github.com/gosuri/uilive/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package uilive provides a writer that live updates the terminal. It provides a buffered io.Writer that is flushed at a timed interval. -package uilive diff --git a/vendor/github.com/gosuri/uilive/doc/example.gif b/vendor/github.com/gosuri/uilive/doc/example.gif deleted file mode 100644 index f85bca2c50f15dba1039b6b7a2ddc8bb6b5c14cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159491 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%0DO#*>R2I(;7-d%bCoN)F?QYu9tk%@ylM#o1$@ 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�_Tlm?+b1=Q$R!m*NNpS;f}pNN%($Az;7@NREVcjFmE>e29-^dh0p-M z!G5z0_zlX2->3xq#>}>_7d}X~y*&;Cf+++bm?8oMQ>aUSN^sqMXMk}$HV{m~jeKtz z0fH$Uy-$RCUm%!L8@dPtQ<|?X@;Hkkil2aBia2_B@Wy=bHDyZ!_#$ZLx8s7m6Z9UB zvRijRxX%{4lepk!^p#9jbBk)Ixrcta1hU}po&D+6{L1wa;5Qg9#*)v(z5wWQJ$iD}Z+PWz`VF$7!Jt_H<$%yoaf=E52YLS-Ou!iM z8)S_75OV3eYA4z6=Pq;yMj(3^`ZE-w6Q=C!N?YO}Xv;6s2j8Adkh7%hv-~D4i?KsL zZH!SZI~j|9Mwl?C2!h+t1Ysx+WZygkk|3@Wi=#Ql4i~dlxzU(ITjZ0h#K-#QPw({K z?+w9YguhTV73$YH7cOV#7HLw>geQn)`4`aXnTlwb}g>tl_ppcF; z!-q<%lrpLEZ=JqHMpgfOaa8{TKg1$tdDk43SQrEU@iLz84OEEo`d~ZZ%fU+~Se$9y zT7(`VOL1Y{Qwucn@OA-j>Hq{>!RbG_`YlzurO(&l#4s>` z=dkuIWI#OO2US&N46XSnG4!le{+W?9IFc*#<;{(|sXj+L7gqKs5?J^_301%TvKGFM z%u;LD_YuNQbj-}#)T*K#Uk8tvYS9$jnC<2SMWgliyoiDl>*wDcP0G1UXe zMF^jUv$mHErDFU7U9uqdz!XjB8t*}2v zTt&W*I2=c%x!zNL)cK}3<(uMMAhX)-y;{T4rH^gr zj1+v&{wIeLWB0*g#}j4xEg=aYhw>|t!n(E6d6j+Nwm0VUtxSFkO566w{YJgHQ}v>K zwClJMJ9PYJ4uzy&fD+lrp#(O;9Qh&>-(C8iR*%)HkLz}+J}wf!Jtv}66_mcK>a1EO zs_i9iSUiR^q^J%q^-|Qb@gKV282Xcn5PL2_VC@bU^EES2&m5T;e%im-^Q(pbt77q3m&e@o#G=kg(eRxs$#lgNb@&pgCqKLjp?oEpU9%T! zqIAO|55~QTcUkR^3{vU-76)Dy#lV*FNxK>-~ajp)L*fC7(_jWxCT~bdb7&S~4fp z79qFLb1o$z^(KNcrFkOv@Y9eGs0?wj?=nH@>H!4;KYJ4PEN*5p;!~Av1GXYUU&h9L zbj$Vs1#f85i~A;RZP~=p9{U*ytCk(Aa;@?Q(n`(KdkT+A$M4!_wwx+7^hsejlAkBW z7kc{mTiq0$s2u6;*fi1hUOrt0pM(abyufG{XrjGNfB1xv;1j-Es5R@R30pcXsM!uO z^vb%<2F!O1B>9Jnu>8|g7!t$glhxdvvPkWuSyam-Xf}}D4p=^~3d@r?4D69f&nt&4 zHnEUquA`d(`rUsJnl(card~O5Nx>Qtke!g0NDSowqH^@R0Hf5Gbrlu5yX3nKT#4uElM^u&fonKnK-DUZ%UhnO; zeKi|OIn@^|F2C2p@l4Mq-XJ5rydH1j4H|$qWYPe<0Rr$w=AD1=hRZ*AL(4vGf1@BW z#~*WS8j5a4rF%brF08hgYqHEiD7dzy6F8M-U#WV0m&RnZ$)EWT>e5}ev=^K`9cQi{ znWM>^eGDzTdM4ue0S{MV9f^HNCKr=cSrwWus!}DHH+nbe2txq%i>v7c1W|Z-1~7OfKpP8gUjKas*PTC5U*{7Y#aI|SlZ1Tp`X zS}1sf+Q(x$S+*ZzrVh@4#HWdd2KDG<(of+(QjwWkr)FX@N`Sjq=fh1-4<8?&g|vRR zr%gUP6-uCqBO+Z?rLLl-)!s^7tG}zI!C(;NzTWrOAVz(NPD6^h82}Gn{KBePYh+t_ z+uYA#S%T%OgHT}hPeMU1cd_Yw}<5+ zXiV>#pKy&YsuEFzU5dPi>}CE)uHXI%GW-+R$vb`V!#$lYrBPB9B8{x*Fb!dil8JEU zr~M>*GQ12QpUi@m_j78$e_ww?9gfgOEUlnvnf!h=)|6h z$lUaE`-rd^e_NE;LVMJ6a5ONvU70TucRS$n{NrY-#@mTEQg6M<0tm+=<+Pr^goD~a9zr=y z0EB~x4l2e>Y!Hr<%bSD)w?Q~?FE$CsP__%%r1~%6z-iAzK7pazS|J zXjZk-Ro0Ya-eg1jDd$cV`XQK19!#cVyrH+MV7S92d%OXky`x#o#R*?{(@4U|Rg}1P zj}L$xjF!A0^?JI~^`;T_|8Km}{{MwH+&^}^FOIl>+Q1v`(|K0hAd$}i-q7)w6nw-r z0`P{%ilECk*rSy^k6-6KauXjdRC=tBJo?`5@%XU^Z~f7yw;qq6B#18Qy%=fPhy>qF zdTY<2kx9sW&gTRY3cwpeBd7bN5WlGcpGfEp$dNTuoG0{~Bx>oIiv&-GofC2Jl(h7e zz<5ejb0ja13je<$hsXaN$f34f0$Qt(clurWGjtfcr$;G^*%KLj`-H~Kz86-P`MzJc zs`SRg+DqMv%6-lk)Z<}B|7MnWND6~19f2%)=9LOxD_HHZTqqdL6iU`cPKG~yS*z$a z;%owRFU3`jN#fsv2GgF4>_2))zXuO=JHM86yWKgy7X6y{@IctnJuBbf;JdiQ5?{9qLxB5Z0deGF* zJf0i?ss&?a!N5WGzD>+VEy z(EDmXvJ7=kIUF3{!whcCwmrQW+eq1nZLH$Ih2|MPO$;kgDSvZGfI5_x73fvwBNV3y z3b?Ou#)pT2Y`f|<@W@O{idgS=&|*x+1HSzW@w^7#RdDV;)VUy(8#Q!$p*Y!&Tvyq- z8P=G7qEiX)`=GNA2y0Y7DEn_%BTo8nSR*Rn1HZ%qb~CIoJ!gF{a5JnyokZNl)IEyt zS5s;5)AP^0d|j3zusOlQmv{)6;Mrq5b?&p?`syygW>j?@>}qw~|6iM7UxUyDrXU{L zYU|cX71^fx{lyr^N~3L#;}B^vPH*BO;DzH2W0%!1#3;!b>X{JyJy;4gn^xapliOoO zmB#(i`D-zT+ZFY{;Qz50=Xt9=;*~E&QRT1J!=^iG1vg6?eaoZsEyVZAUu!l?8YR#E zEoq1}(G)voJgk15uT0x>Kx2fPjgp`Dd6n`bUwWFqzN8PV!s%VMQrKzcGI#FGTGB%9 z)<32|Ndvp}9eh9(o!B=n2!F_j>XLkMuupgEOQK|Zi@Tv*6v;d~u~f@?sg6h#C?`Fo z`#GA{Ke@b=LdvlARkY8B39UKhbbHZ9k=ig#lH7rguVCA}OqFVVDWN|;n03JH4PY)= zwGqLBF+Fky9eMH!kwqyjz1l}&5mH)gaNN&6Inz3}K#)d*L_7XKTXI&w5=-F9H};m; zq}{eWr3ETV3FXJfCfiQMX5Vs6rF{z&77FtR%Y2~n9bhYjB>zmc<_Nh+b?o7RRzNT< zius;c^3U_iX!*sxg!x?=t9hpdA>CIfMFyFEfmEkmGdUmyN`{2cmpdR~E)*^(0oYf> zAMq;rGweK>D|~tPrBZ25FVdkhHR$;BAgB}*bSZ{|7Ew@98D}~g+0Tfx>lqn(2?z1)Sk zQ2QwGMV43TCGI^@QHZ0yn!QMF%-a~8=JuUh_QpTfl!Z7p+(zlb_d(2#4&Hd8$b9DFd3dszb<96~$8r>Em<(w+4 z`4z6|>t3U8Tx(_$;&n}B9=eMXL109?(~ymDlkf$ETyl|&hSEhXjZnoXpn7o(=d*;& z^lK;Lny?_~4XVH&BnO%tSj7zAzYwXx;#?Hl4-bO}qvq8;#r(fRB_|ee8u5i&kE!aT z${hvA_dZE!9<0Q^gsRB~)MaKirtwk45Q(-#Lj8E+PG@p|Pwzf9-T z;qOabIhWZU;-A!OTM8-kFVOIdLe|AI{aciL2E)WopSqhIMiWzQ;s7ZN*R>(7H;*sk z>UxNuXY%gT1FxJ+;5htog1Yk3dv_MZ<%hWy+ZB9Oz9i)b|H&1n4A*v6;73%E-E+h~ zqaL-3^{_y))$#@C9dMAp#F1Gt*!N6_$~He?UeF?^SPHr^RMRaIBX%IP0A*8-D7+7H z-*xV(grT2nD;5wTS83`3L_&x0)8(l4ob=NjRsN%Bbwt7m(YuqqBh-gkoFSn)j_XOBPD!kpoP!! zYt#6BkqjZBu~Z)qSo@Ac*U?g$`ih2b`brPRgtZo`rw}*$p%#RUYQCby6m^n?_wvzS zDt%e`e)P9Tcl;{zWywDY?|y^->>gjY+j38JEcvrSe{V`SE$wKR!}A`PLAeb!icX5F z0u`o7y#ZMp3~VuFsbQQe$0R2kc@4T=1#&v`o_Ff{2Eum#n0W!$OEI&?o#@H)AIC!^ z6CpMqQZvC+HXooE1j2+e=fQ^=iLY@s|4|G>t>9xuDQfDD3ssW;Q4D)*1eU~vM1a5> z23AP%Y^CA>#en82fAu^0LlV4pRff_cd4%aNCY9hrLBA#`7y%H9TL*d)v?QP> z@xj39-?s@~E&P^bEPtz$#qH>?w2*T^OoAwwP2fxX?$HOuxXvJUfS3ec{?P_&_lltw zNidbb_Z@>^ zfMcDL&IUUe*rK;vP!(d9KAj!P0+~30nzp(4{XBP2)!%dkKE|ky_kZaKklLSg1csLq zZ%x}vM^N&`a`QCn3ZNkf;SP>_D;#z%2Cs7Xg}aBry{N`rlI%R55sj=KM9tt zX_c+Jl>KnI`sqU1R%hAH>$2aQWgsC6M4Q6wN@0zpz)C3WT@;Q<3Sx_b5-R7?F6VJA z=Zh>CC@B}}Di@h77h6K_#T`~GxFobI_64FP0+~b7Q1V@+d#?n-zLhgx36Lv+R|3j| zrK;MM>RpF$-zwGEV_m^wkzh8q7WqV(BG*+(F_OIX5;~V^16(`Uzf`q~)lBuR!hM5} z?sXh6WsdknPqg{V&T7xm$e{ij4{gCE8VB%-1=tEq3O0>IgZ-K2GG?0jo1a9E zq+MlQZ8UmamzH0YVjL62%^5Szi=x;&%T+yijJ-*!9=B+?vVH86HH0UAvWng1wWU%Fb@cp%5_9S)LH=z zYHxv-BREz$RBS?o%MptuD193$Duk+Vr8X$V^D9Vfm5vMlW+}Mt%_t*ms+uy&2qWTw zHf+*7NSy{|8urT%{M z>D*SLE6&j0M(UJ-;vTM_pg4#Ai|g1nrzn@@HoLwq-tV)#r+PRY=MZ1KQvh7QnTGP& z=JgF~&*fqxTo%+PA7WGO^t9;URnV1OF|s5C#0$1{VIee&D=SuW>$jJp43< zPBUW#OK`3TInBb+(s54|^k$~_?d1o)*6I&m(NEV`0@ch zr`>(pz{heIJnnY)Y^&#~S;$ZniVSieQS6>$Q3$zp!3=ir0Knp)+T0%?`+Sz zCseJJH_$XN+BNa7t^5*L#ou&n!N&^5Ig#%jU?6I6Z3Btl0UMLp>nY5=XU~5pAY`cg zmc#v?x$w%6$F^4NPtKv-$0oNtZJ?%oNPxMAY%2dSH>wcMja1wO9~(#8V^wTuh~JpQe)yDEfvBZv zQ+K7VcSi&k2v})ydKCU4gSk=29Z-z~P8~Q6LX5tY*aOQ4PJ@t!#PNKmD|<03L$N@O zIT{s7siI0w@*W2qMzw0YZT6X(433!_?Cxg6lvuEtHhfL{|L z0l!W)>27dllC48_?D}<8p@_~12Q-9}$F5)qF(6Q2CJ}-l96jLO!6wc&{~YL1Dap-K`?jt&DR3 zVPm=h!rp2@`f@N~@VIJ#ut6^m@gf6~4605{E(f4aT@?v|@i*&^vz5!?zv@d}fNqZn zMozq;gE-oCP5*QSR`}X4ym)vNwF$Cd9!KtwteEK|(&oL$r@nBeHn1@z(w9=l*2C^` zB5y_4?Cg`{%rvHU8gghF6wMpuY#E3}SpjwILn9DV(uGOtLy-~m0+}f<6Y(3z#sUIA zJS-exE}wVQs-P+TF$TnngKRY+tN56NN#HEACazq|QIxeJk!2Bc+Ga;q6pi%3&3r87 z@PvSUEPQ9XE!w9M?#9e!SKgI>eq+FipirLmc#I!6W@7?5_BqWM4o>w2qp(%{`*6%T zR5*Dl4-^*Avk`RJ2Dd!z%XK!MOoe6OZSLE?&qsA1G8a7H*1!@1RG|=*OHG!_xV5iL zH%H#ihI=d@jC011jTy4L{REfhatPD?SkvcIUnUFkW=m{fM`yl2)YFJFhQDn-yP=M~ zb$~O8<UQi5B<7LbUL1sh=EMT3M!9WPaH34C(F+!3(8C1#E`t#zBB3Lyiy|t zL(Er+dim$91s@XvC&-c*4CF{&_BKf$LQ4OMW9NB?JU{?xG~0%Q9@WXQfqauw))y16 zB+n-4ym9lDU1L#eg`6h9`*9q=7o#5(PbVwE^55q_J(x5)wyuO_HY;PZct6;7dZ}II zkyT zlm7Ha{aMrxf|4+u7&L9OlO%OQJ{it*>A}f%um)KnX1^hxXK6g@B+z(r;`<6!-OeWp zk^;5|5A${)&>tZvvG(C@C#q-9#e9J;)TEX7-2`zxfwhlR$_+N@_AhfC|A+%sV=X>r zJ}`5t2QS?sk~Si7-Ms zSEb}^UtuiP->^&_*qrDF6>#jaPLSTv?)W9a(L zPluoBg|Ld!T}vwLrV_u8tt^d;upke=OXFM09Rpv6MZIhHKW&&Jw#1%(gFjTe_kxf0 zq;0@$3By=g<`{EEk>d!(>a9uMgw&P3GsuSrvu@4!DkOAXHEc3pc`w6`LwWO*OoC^b zge)IFyK1i15GNYD@!E)#hb8ul>f&*6AV{_(aDkmYURlXVVf#_D9>i{>JaSq7Q8Ln1 zfTcWgcC;Tj>o`ha(z2he6%~=5>@B-c>LOw4C$bfs#A|t1R!HFR;=Z!=#LxlJlaqO@ zdYdwamiK>2LgH8-MC;5*+uc)J2KB66sx|)1e&A7}l+k7@C4dk8s5NG%b%8l8viRtw zq)-X#Ryt?)nj(T-0ah+}QFBdE%wc))V3{O@M&q#fo^~8kX*Dh@PLob&AAYs2{ar{G zw}DCGkyMt;hFZeBuf!liS;sjo*FST!N!OPbU2xtcBvCtbY`EAa?X8;)t&|ooL3N8} zukPpfqrD7nochj$$_|yS;0V0XjER{pnwFNI7=@NuxlON&M=sg?Jo<7iZH~mQ>0cui zvsk{K9ewa^+w)`Z^Z6W7CPy1siNvrJ1P^Y)0AY^lF&53v4s$f_o^F#9)0CDpK$sjT zTo(6M0!d`q#k#QObF-3ql4H9R*GE#hzCUXA7it2r;Gzv`c=aSxr`ax;`t1WD%@-m3 zboW6DXdGE_)?EB-I1DspC-_uRiKA`NhXt-emSgrY-Fj36H3TXocClc;cs8F2TuIsY z5Sa;Hf6@r>^7SpKbh(6cwftI+kAe`J?h4Rqz}PTf=BB45$FV183+BUQs9@%M{{%oy zxdJsG@Vj@>gjrEsL0>=dxfTgsR$F;^`xZs#eEDK!o~O{Y*Xj?Ze;f#Zf8(quk6b9+lW@9W$a{5(7RKUHtm z&%;o480`PImmQu!t}i+SI*HY86_^QOgh|J zl`E#mh*caFC$crek7ex9iB}B$S47Eiz~#a)s1ySD0J`!(^eSwKRfz)TOvQlrk&+62 zgOz@EBUwC&Bo={Q^!fhsn1A4K4o4EKpkGQbWYcT=5{8z>i%r|`@dUncv8@Z@jb6-| z9a@;ymkj?${IVvFla?Zc()98E=|3m@o*(kvApwD1D}xP!IA_1iaXpFm&LZWOSnixs z+tGxI`w**;6S%y9jwH*e8H5#ykbtRWQjxYzOA@Sv*`z|=57w4?w>@(J2I3OwEji|! zAL3UxOn5kI;{@cug1KCr0mhhkmvv4Yikk1wV+cG->r*&rlcQrxH!x2d9*Nz-By+9v zC16awi<~4MAWz8Wnr$3M^HB_BbVHH&_|GxXG?u*D&72EuHpq$a0#40O7Wl3~(pl6) zd4ATKbH1hrSrfq=M5z*BW+wWr=n=8Xw%X~pQHAg=*x}k$IQe(HaKCD5xOqA%a%4{X zv>jBH*uvq3PpFV!OVfK82lw5mh`JHtX6hw>wPY(vL(b1si44v-=?-;RH_x$57<=9n zXCcCMHP9|SJ<~p1Q9rgWTQ4yV?ybfo23eSJ5AlQ|FN1>9DKY?u({QUC*mepKXfr_;SMO&YKUX&v$QotRy?#o!fUN z;z^X}dW}=}XTLL1Z?`=+9y;CoR(&Ss>u0j?!q1qWAI@C-6@>n^^z%NG%t|y<>3fK* zbI;P@6;A#g0xacr4>XgQq@4MdZTp{I;f0m3gLmH}Qk?rA{GuA0M*HxbZ0i>{56RGS zcWh~zcyRCr5jHSNn;Iy3sN+b@3ds}}{pLJC_v^_j=AW04Wqy4R4F2E3TLD;jhk(^~ z^ZfK*yH)-;7`G&k6Zy445=zR_$~;R@{VexEQ=Xs0adOYJ`~U(4zJ zAO&rr7gcB@UIbPPjmZx{&+7#u1=`4bxo>V3LcA=;O}Q#9@0em&boh)qsAX7L0mS4SQ+nmn}Yhwx;px$5;BDt5H9l-qVsU%6yLuPI{fevRmZ` zV6fll)Q;wXiN^&J<1bu&a{c&R1LI!2bOTGS)0l$(Lxdxbx4$xfwnFi5Pk7;y@_H7{B#Ua$+xQoEC5}<9};z-@P@rb^N}L_@v6cHTU@Dv-WGdYi@sF%{{-w?QsiLd?cvr zbNij1J6!6FHFqi$SaYv9B=pL};`&vPW=enrKB?^zWM6xRxy#Zg~5Bvd(FD z$?ZVJ8-z~^sOC03NF%jhNchzsK=kc)79Whmy?NcS;nE}Jb0x8njhQ%UqB$E!2liiM zVk17@s;6<4ZAgFCRDCf!ZYCJ-1;ZN_nMJT(mF>lE$ivQFHj{^Q8$UhKubYfY*U!+B zVm+Wz7K4D7>iJMzg=wuh>X9*|CwhGXI3tO%z>T;+Ywj;EOdpBgf!Tz5dEe0bSP~(Y zySL_6`G@J?^~$MhI`_KiD&(ccjE`F=@{kI!=1x6iHHOD#jkHB8zuTD0J%-?t=fPZg zJyN3)M-AS8X3lJ?#OOBb6Pg7qAVuh2g<@=n5ety^l~H=0+AL6R>1M#kdKk}gahy{k zp9}&87f4cPIog#L*pp{iTlv<{durLh?&q9+Vg>CCe&N_Y^H8#aaG!0{9j z>v^%pjX{qoa56iQB=Q>zMJTL5luCdtH*SjhuB8araw{I*$Z#)#=02y=z=xx4TRAYs zsU34%(Z%uH$d@AfPq#ok$HAPFg!{dvt4tSH-WOo;_qiVulgnBp5Z7m0uIOSVxT+|x zRf>8zPt+%fZx9mvaYe8jhIu>Ytl$HhT~>l~ipu^US}vJ@kR26dIs5W&&H^0#y<|px zpN$2m@B5#)bPQNuA2`k|do37=02S*Ehd?+8BuGN5fqrQbDjT05G>UrQq-$oP=rbzn zTub7|n?2!kmk{TUqDA=+^qym$v8k4p6y~j>n{})Mtp$! zXjz6kpAd*1EfADn96k$zG6k0IV+}x!r&a+!$ahE*gbmO)m(PkRQGdCtws&+donvyW2FDi3Ya_)LX39-Ow9cpeD$EUUMt z`xz%PQ{s*uOnP3pb^N;W*H6bXx_E`?17jKs8*xEzM~9I9aqj1(K&+?H{Nq0ex45*H zRPws)dDR_cU%DCuTnGL@$Y#4K-hp$1dKX9C1uLb;4XF8`WQP~pn#f5(T=T9^Osy4N zBf7c0em?GLcIUr2Sq(nVTfy`oJN{Zz#22^wq`2?P$6IFw&qUns<$q!xck|iW!IU1 z4Gt?CLs@jDUIgQfI{V>9*&d#hI#CVW#feFOgQWf zbT8p0veM+d_<1q8SxaQ(B=-+WY+=%TwYStuZYa0aE{uVB%pGu>)eR#9dVMGNkC;yEz6 z+7`;;U~;TVban?ME(4i9)+YfvdhL_=nk6Uu7dgK5`A66vhSuO9msZV{14VToUVBNEA@^oPMzQ?KZOngOM<-Qu}DbZt&iZ5PpStytqtg%HokdTDp z%h8cXN_yQPLk}0)-Se70c3DzbP;}{8t)jcVlCxD~cjxOY*40geQ$%jO1!Dip;LPUm z9g`~~(#98(joA)T9;ja2XqoCUih1OEU6ZAU<|44dY1Q5Cok;^AUz`-j!!kw@_EdiT%c#pMATcaU)-BWVN3ru<$a>JlwOkJW z@r!5)60<2O45;akxb1wr2-37&pv3gGoJIguipxRumr?Iif}hHQM`U9J1!6ODV?qvT z+&{_KWH)ogtY8=geN&*IPh$%K0{Wm3?l@PLLyUm_lMs0zpdayw*uZ)|)i;StLeAsA z0evFhcM>ZT2%i!$hr-%rnj!36oSblL5L&rfvS9S~fE4*!3 z+tI%TeHUJM{!ipf%rRcPV$ejgt*v1b7#i&jt??5+bp9mN@hAf{2~0VXse7QQ{v6Wg zCmceR2_-v_r+JP~oc1enQsf5#qi7^6V{9JelW1NmVL6a!?VOI6OA5A2;;eumFdl@E zV>ez1U7;y){NU9gL`$dzHk(^%R5`}j#vb%fMoXL${Kgyj!2sA~8~l{JGac(?0P&V( zN5#7UlWg5Kct%lJR;tVVqW!sk*hGQ3em=)`2S0}5XaO<=g!7p*mTQ%K!IYGi=6QOeDuQ1kFV?oZ7&4Vne(!3vkgxQf0~ew>d9Vq7Gzi_E*r4Ujt#eet&`Bh zZ%I=H$GbMkGIrRpuVjH8cJT}>BZPRcCKJ@kyG%oVq(E_x3BV59C7-Dz4whkqRGLQ! z06T0FgF8DqcDZvUYIldN^pTnM(k^!rUY-QFGZ5g;m2@DEUAJ=C%K(-!qa8`|5GS(| z11^VSE}g_g7Kav{sV;JVSd^_L7MteMday`m+UV{p&M-_~pmE{xLi>}OMgVtauXzRc zGxGmIx%o#vA&+k6+h`St;|o?bd4U;r^y?!SR2ED^?9@QAnuKBqFvF&!;QiC^Bd}}W zP(&{YK0FN{$0DcekoTwI_gCO|USULemFISM*dHT+K>pRAX{e8wG{z1aRHh%!sibAR zXyMq4EBj$_70{PO3oda9N_*VZNqN+iApG4X1#RPDYpl{CT_H20O2;E*(<{`=wdCq6 z`gRrH8Z^}ogZ5I{&rDm}HYhc8t-x?bN3ues25 zoePc3CD#N^)|?T#?m0*Z?qtb(bUnSRR)ubv7Zq5UX?eZGr`9g5Hhi+i2II>p&R$n;S-p(nEUK@w8L8VSs&Cb9Xmf37Prr6ltKnQk!`;b-ds_`|Ee){T z2AXT*!^p;glE%TV#^K4vr(2AL_n3AQkmr9H*)&noG}+ZOHQDrTt7%&3#;o>@dDj~Y zkvA3<8ulQywjTXCkQu>_{-^$Wj3xWg5#~z?H+F~C%>bc(>#AKPHE%`o=?h_4t~6gm zHRyq>AvTnIKr0^9LdPJ!ZNfL4xQA(F_enfRZ3T)?i#VFi<7_n@-z*>061#N7ZVSG& z0oEU3Nne5Aq6f0*Y=Ya@>y)>_VjGmh+lB=|8lTL52Fn};W^$F_AD@m2e874{5j8p8 zRtkaO7114}Hj&5tkK|BG6gLct|GA-4YlXW9u&$mq3>Csy@ZRL@!_@7qt0{u9x32rc z9fIIo5jr0Jug`V8HhndHY@)z4Nwwows;P-Xgib48NeftW-n0bG&*0bT8`2GEv!qs) z$=iz`D=co+d5p+k0pJzWaB@!7Z$v8P!S!pOsp6|$At6|TYHm-eHL#{`{Q(!)T~o6M z3OkcTqiJ`%R_{cpL#zL;sjs|74z%W6JA`I)YhSpG>Q$(SQEam*vA3mzkR<@quJEF0 z&SsI_;ajRV$*q}7ol(Mf0`9~d3&AoL)kHsGLI->K{)u*hOpLDMCi3?-m{Spzg`s8i zu=gIXgZ;axCO{0vkJ|Iyiulg6MCKB*V&lLoTS@S8sUk&tI53K6`*Y~G@H=kcdmkf; zDJx(Uql0hgY|tyI-792uV$494ZwMt=ieAF=D&(RS8xbpTv~F%MI=8TFBmq!r^`-zjJ@eQyS(7~rj7){r~fHgHf={&bFAiO~~Y}P!;bu^15 zie+Q8;wjdk_b{Ut1Lmw09K`GXk5+b&+-I%poaJaW!;+Bl#` zD%eKp5Am*~hy9OuAEk15O1*Gu%D}X=uufq#mT6+YV33ovYIcdo1cS$grSiF;m@BJH zMNH`49o~Mc`ysjZcGn9JkX@@W*K%lxWh$|}A2A@wbT915bMljzZG*7eGGC*T+S-`* zk)^VRvgLmwW9zf`VO!CR)wJSJk9?5R06@QRU^PwkQfZMbey~fw6h`=79Z2R=z(YMG zR1b#@2y&Fhp(y<1(g{HWC`4@^N?;7sGPCa4uJ@ zGY)9LeQ{$2w&0d{#%vnh%~#5B-w{MNpHVlM=PFNByeRqkKKNA>nMx3+j_dGY?p6yv zzstdl0i6P7)0B~AqIp2RWfs@VuoXxi&Fv8!LAfbXf6HH>jp-RoeYzD~8XDtpO3l1d zt-}|ATvYrwc7G=sl?D1UmX2VIrPcqa@CYA;s&Y3Mo{^iNah$yo|FC$bd!2-G8R-z+ z>J<$Z!qndUqr$YmDh$%%rE>lTvGU-}qz2hbC858j)l^oPZ7KyNi7^mw-IJ{7Q4|hC zg5-d((P&8jEOLcjw_oo#dn>j`mVQQo93boOjX=?^!GkkmDyU&41*0x=f54*|`ahOhgC# z8A$7o=!{NPA!PT36@c%}GX~PC($klsh;RPN@l6TrAwZ7%g0Cd?z)Ar*9+`;t=F6&l zg`v!jUPV4{Ld6pH19Hp+Y^2Ex%YYoysoFC6TI(y?03Ca|BLe_B27R!7nqvddF-_hS zh}@IZk7PgmVf)Djh}@Gtsgy=^tDnV6N&%7kqNXtRr_(^>{&ds)7lI1VxMzQA)Q(_v z3*~2y4#*k>w_6E>pjE8*%+#{)zq05Au z-&YP}XsU{#_xORjJ&pfp)3KP}MiPK7lYNyE1%)w|LDH3WXY}M^s7xpIIlAsGr17uXK~m8M>zaghbA9_x+?_X0 zjD<9BJ+hVsB1VL6uLy!SzvUY0cc}fDMiar+ub01{%tbz!Kk~~MWWOf8gT)^?bKIC3 z=S#Vb>S6CREyXok{Pdjp7oM3%m?Vo@!=Ow#5X5^TlQMyM<2q;e6R^N)7x<7f13337eJd?I;u5tK5 z!1T?4^WsO_fwv1`k7AHdZiqS>UbOi|F_{wmUPmv0yS_uXg|Az@|79Qk;(SX(03}<;L*7(4J^ld8XWt!MW|`ZCL#|J%q}rLYCp z$ER;8q&Bg78C$Mn37DZmz}UQ2$Up8+t6aj$E#-gzD875ynguL=a|3LrRqbaO`#H9K zWdQ+)AtrWmFHvXuR4zVN8NuceFt%Y;1lBK9ljk1T(qHatVLxx0X~aZ4 z3osnR_Zt_8hrY|JS~~_z9o8zC!M!MB8wEwr;R`la%tAM3lSJfSNm~}=1ZB6g{WRhv z`pl%m=AMaUb4m0*-lkhfy*i3=b?+-YdW95xo?sZ2ecA5;6oHwLDKH=z!(Hng3f1fO zOHkPaDAF~8IS$A9RV?#Cs}P>vi)m0p{UYKQ*21qsN9SiMy!((CC4x#@=Zw*1oZI8Z z;&YN;aX+nw9^;ahwv;cI+fVi$tjd?9B)QL`6PeJ|^y82M(5H`iO$w{&U?I;w7Aw z=G^q;H2X6y_>bGc_XVaCc>nC5r7eK{^D(pY?At)RekrM3)y~3i#@@jtDaX^XOL?dg{_HlA*_?IW0w5nisbrV=0ua}c@i$ms#9X%#Xk3+(#1Q(!s2cy|qhWI6{7O|1%lA z;ZYaIMExtjj@hUYuW55#LPn@vXQ>>4svj`O7SZU3{TeaT&Hs>KyJI9$JYtG)IAD5S zcf?n^6uLCdm0wjv1M5&cn;JiIg;`Ochp9d&r^IWCSUE8t|4e09$zHwXR5=yfF(&;H zCRgW2+NaZ!Eth96ozcZzR7-onDwM}AzcuRgZu^mp90-EWG_?2%>V^7~A9{64aSz9=kKD^fQON2Zr<) zMiDYRpRoT9oBOnpevpYlLw?1gFYJwKk42MO5r>y?NiU)}B)NSM+#<3(ttAg7`*Xz} zEcOY>;w|>iSLDQf!SGuexx1`!LD{G31hpRr=-P)sAIw+6z%-IzNmUN==*f~zTzL~r zh?eNigbcMbU=P1U*3`vlyqSO+mKsz&n*YGfC14t z2-yLT+viQdxKi<;H&d0OGN~ja1oA(DlLrJY46LyyaBSm@yV(EV3f$HI9|dl7Mg9Ms zz#+aM@5RCCR!iR}*>Cd0@BR!h&)+^am6|fK5#meDb4bQJ1*Mr3y7QY}KRIIQ)JZm$Oam+0Rr1<@iB|8MsTa(KG95lL;j?1^gF`b3I<<5jj3bZ;)bC2U6 zfS5?PdJu7%wVVik--k|ND!K>WAJUJ;C5W=ER+=)SQ9aqX9(PJlgm@!99nnu>iBGFz!)pc9S3^kVqDsyn!u<}HLjlV=PEPy^R6E7CONWsxN zL8(d?8uvZ$c_H`H;L@!xxh}v(Y`Zu1yBD#q#eR4w)%-ykxQM+d2wcP-?+|Do+P#P^ z09?dgJM3qD<39{HyvuOY|4$5;9k1RI&r-F=a8sMe4$8j__i2gyYCEcFy8!<6p71}c z-z;}8VoQj*e~s>O>O)=xqRQM(42ATFKjMMHi$U8yJgkK7H zs;s{4mzKvWZh|acdl#|CzWc<;K_S7X<{&^*xhUB7rVNTc4Gj5GWr3)&dlW4r=}AXi z)+;>tMDq0^3`$Wvm~=#`6Ma^SG$O<<9K(<4<+IaA=29^nfGi{#|Xf<&)*~HE->!PKXK;6q5vmd zNe0DZ%2@ZM4z&JR_YGu<#%coVzFEcd|L3~zZpRJ2w(^jH$VWcQ?}@0jXLVkv6MufDzG=UgB>rE01`KTTa&q3z&CKo<*6i4Q*JTm@5M(R z;9%tp9w4En;*uZ%kM^nMJ-)ueBv7mh;e8F%l*xZ<%5jE3P1)WGX0}&TR;+w3$=|)W z8&hr?I>Cr3XB-CUY3Fnhp*STjS z;sxCeF3u@^l)VQrPc;s`gvvEm&2bU-J8-a6Xf#DPoWy+*s3|w?(3&?^2c2D$3&p7) znqWAlU5wl073S4^!oWCUe>F6KJf34R;xX2F5(UoISZ zQ&eejKQsjkM0vwkvp@nJChneZ5+*F?>u8xv_Ad4gS5F18G+rG%Y~>;|0^Gm$6HWA6 zUS*}qu}VHq?J30xk9Ya-HRnw=UZDCZxASRGe>%Xf-y8E7iNDM`>yV0&)=7_UUuZr5 zEB?eSt;g#(ekw+fX7ZRTx{wu^-IOUNv(zguy0tQH7j7yCCv6wZ&bFL+{8rwslE)Yd zJKF(Q@=^KRU=JBlmztQ2JL@Jj{J@5{zVGU?9gt9dLc+j|1PoE+(s_w-QvQKL1JJz# zt~);#nNCw#4i?RD96hyC{>7dc9YTsz80JsbarB90Q@r}9y^=l<1vbnp7@n7PTSymQ zjAK*Y_Ei1saK#q&j9&nwtQ_`w2$QO6Xn7^kb3wDqz_czX%q5{_Z1lmcq?VAAr3)P^ z<6|@;4dUrOdze0VOKq_!<#6rdb3+FnHLkTv?i2@$u#ctU(|yJq(Se%Ggh8!eOm1}s zabgc7%XS1FdXA+{V}lBZPb>$ui+F$N`F%VuIN4l>*c6loTzvL=oCxYEeZ3JF#=Z?R zJETwiGC8uIL(V@{DPOE?{;KO?LAGtJ+0{?Bb0Ky0?<|@9cWm9^ytSBt^O>c&f=RCg z9J$Ml9UQJ$SxmjThP&5cQ88&ljyCiHZeBYttC!7Os=;2SZ-m|)YH~UN?P})o?_nvp zfRKMgOw;@nj!g^Xx>y}DrI_+hnJP9Z3N)uEn=>k-0Yg)?Mn^d?9pS;sxp;QfCvVT4f`~6m5UCbbtGuA2Zb_ z=p_+%M7B4R&71-$8cC6yl&-6_9?jE|Q(fNLImK~Tr0*~>ePFknOzV90(oCFa%bvO; zdPiB{uJMwA0Bk9^IHnUDtV z97oC3_Mf;rldtu}ZzqT@yXBHj9Iz>geobKVd}Brz0oH;Izxo7NctW#2UL!k*=rJ$Q z6REx)XIxL7SDZ8ByRT%FZlEL+R3*V^CM&EXVz0wX7|rBk;TR>7@#zcS)wV&Vm-3M@ zCjS4joW)<3E8sN?As&;UUIadj)=yvjmdkOv4LETX$1W2W1;`xMoqd3WNVQ$SWocXTLg#kW? zJIlT5ijv*+xmv~g#WhO;B!YlO5dSfjC*vhf~F7z9Js~+2d>jvq3HrJz72ne=ziF{@8%}?9LP?7 z493ZV!0@@*A}kkO;*ybUTP@j`|3AE|oD;WOg-v16wpT>@81#(FOtHtR`eOK(;PsKZsCqfgdmPu8BU4?9~@b#$w?P+LD2Tbl%YwdktN z3bg!f?ngOaSLIqCke;98T354FyUmgp(8*HCetnc!YeU|(I*@e(a3I^VY|rYd>+8D* zYnHJM0r&>SRcmrXpz~jW8>~5Q(Uj@(N8oN>YJ!C{z57?-fW~syjW57~?5!IsLd|R1 z&FiksKO&nqN}9L2ns+AuHkS7eWJgiC4cN``ETOnY!E&l8wgNRnrQ_@NMvs@nsEmu& zD=mQ7aRt@$UuhAJs=964Dzx1g1FfZ#%NblZ-8xI8+@}*r>OCB&Ex7q=rRFTSVzw3V zI=_8&yozleCFoUxw%|Z3VhvutS4GA(If4qrsYmX1wRz3NOAp>U+Hj4*b=1b$THa6t z&LLT+Q>1pLmiB89NHAb^)JE)M{z<^v}4s@bH3cwxnx%M^mE%*HO6C1W_*GncAY=q zlDlFjPX9x8-CnERr_`a>|B_wHYouINw>TC(&5o8EDg)*$1yT2B)L-d~yE_Aa+>AQ=3RJpn;4B8pyqX*xiIQ zu>C7`AQ83)JdUbp4nW<=T&K5@+uJpN#BP*Zu*HubOdAvCXBy6KVq+HvG2+L{iM+<8 zl}0;#frY_pcl=y9_PCCbQ0C%5>yF;!D)0B7y7R1|lOcBasG0^;2u&j0Rp=`rI~@=^ z%Kr4OxY)Y__B072N`oTZ9}zHcDAE_MiD&xV!dHMZS;aFN$Tnng<0TFu9@lGQtVuWZ zU$?@^xrHCA8Kcb5U9nT%6FX9ecrt&7d~K(Ou5huvzb&XgqJ=^~^-_Im=^|+J;_MDS zOxJ<^$0qCx&R4o0@kElT@A$Llq-R&$3@^TtLEcU7R1@XKLv%v@Kw4pRYTIvTh=DM= z1q1GF6}jefz6!Wgy+Q!)RD&0|Vz^vS*+BMT+1P>3F(%8a9DKJ0ECfRj)AvHh#5U{3 zfWnq=48;yoF2RWsCd|Ua`_sm2jc155drQrl*%50l>3s^$!@}d7*m3w8MEnwi>#$c# zFw>Ch)G_65K5ymcYdx~DKE7vXAqoK3tq{b?FGIduo`NV8?pBUZ16)TQTOKh#V{DhR z_KLxEIG=ZLMD{N+-Nnui?fP=y8|AdNlQU#W;9|T663q^up4sBR2i<4=kj&gzWCa)No zbDe^GfdWUbLUJ(hC=8^)4*Z5bjU?c}Q9NkJdB%{_78r8k)k`EG3$m!en%7Z{IM)E_d3Pzz#e-RQ+`PHrKPG z>PC_)rmGkxWh%>OG6I1D{uMzaG<7l1jxr0N-Ea!RIN768z3{k}!t!$l+O^|f%Yk4k z7%h!ydEuzwb%H)WrelAmh9XE8vU`|X$aK)l1{$=x_+VVq!d8Z#tNI{BjUa}d(3hN$dsJYWNkig=As2wMG3MP97lF)ad7y0E z_=Nw2gjO*pDKfv+Tlm^chOGKD3OxKLUSaGtJ0QLj1HYXO2yt+!?USJ0+Ub=#|pUL3+gtW zQ8jjOL(VZlFwZ5~=t@7IJN(KiUgVEdB@?U3-n?~fak zRaSAVMR0T@=+v9nABEeLeiG;Y>vjj6TP{MGtpB(AWl-4iao?lus5$o2 zk16!0Pnur+fSME9-iJN2>)bt%y@7e)r6a-%T%Eoi56W_99GeDiO#>!3MgkdNSyf_} ztu&`KDM{s-f-GE0^ZTpsWzu8_q}DTDgZT@@Xpl|(K&8i<(=~VH(|R693eeg9@44a| z|C79s;xW;E@yUa;JLj#ZblO8c%(}abydSClB(hcX04V@GPN1*4eWWHGI`51l(iU>^ z6FJ4tZ5}xnmt34_8o*N_tQ2~rbZcd|-t2y!3I3x`aLhaB)Ru4Ab9!P`U1}Zk*LQiw zBNazqpVShHS4bzkXmDvxPs1H|yh}aqa>ZmjZo~b{sn0J#uQn4>vA@F$ohMejZxmqK zQXd&yD>q8zdTyPw=XO@yg@D`1T@-;9XD~&O$zQ;1>!{fYfy*wukG>d(&0L|i}DbQ`+ zQb0{H~M#s>#*1LpmzPWKHpSeTWfO)1$N zTQcQq(|Z@ENuvz3cfU!*Jcl=u(BDuG^cPk)UohFR8902|y>O-dWC zFftIBb@5Nxm`M>jpw%F6dT{XhOVc}9pG|wFENbe6s5AD=2{(35mPzb2i)R+)1vxg( zGMdHHZ-=EPzy)Bq8oo^B*zty|aT*;y+EH#@~QDKU@79E}p#>F0yxZ`oTDGb^7|pKUb%5jXCtR zz9Q>7;OsQbf&1x|vxTmH#>5);k7K!Ffj$;S37oF}GsXFGuU{346x_PuJLfo^Ab0l% zFh9!h%yc={5^w|U-le@sNC^GMB3Vk#y*Kr3FEe>d?4;&_zAN0;{tuG*s(Ruf%cle9 z<3wrM;|G#-H?XfR8<73Ia#;O-1=neL8;d(V@k`D;JDUgRkc2 zD@=H&W@g36zaYY8yNW<;?Swp*Cq^F885Yc%2a1O&%NK!n{stm5IbGu_`!)#~bZrzg zFS5;uQ%Sy5yA900%qizVpQh;4VtFw(D^BV(FUyUY%o^z|@l}u^sDzTrXWk>Kxk!_8 zo(45|8*|kTnKW_jyQ0Jal6-HOT$bA25V`DD&v3__OzVqwPMj_}kD$(UO5PefMeZDCA87XA_YK(>?k#*fTWMO^J6ToD=c z;ZEEc5ML!ejB%xKlolmG6rI5#%V50m;&ddL+8s22V@XDc=LnHwlB@gq#{VMX@<6F+z^DIfPOzhbXDdX+w^c9BbrMQIyItb4V0LA)?Hw zbkdYc4sXACe?On^Mb5Sq?J5N?cvZ!*mDZTTp9p;uilsum;+ znidIaNWfs(TnS!j*10+rkP?9`LuaNNP`E96XH(6h08saj&7AG>T!wUW9Yn;BK~N?j z?p<7B01my9?I7EtfI4tkxflM$!dKx?hV#}8@qVzqo=XcAr0x+ul+8fy24J@}Au{C~ z_J%kLQ~D%M5}VHu_@5sj&r@MWrpY_#L&?S^7egb5>nF}#OgC(}+4R>-pX1M;!M$wk z;d7P`>(f6Ogs!%1cY1;-W5B*IauBX;E8raMQXE05IFtKC8Amw0!^YFqi6cQ`HbBN9pYFtKGL!RR4TpBd^to=})LB6)|R0 zEqEF-#R241ft&PL6>0w%4RIlP*0;_m0)WcoA~or;C17eB-Dx8Yh`iVfN{2^yzH25k zw;Ixc-?|hBKct>0gd|E4%5;_-da!TaVXvumOr=3$?Kwif_C(xORJq@{`$=xI_RZRMB%x?4yNbHXYtgotW(vTZ`!E;3FP*IKp-6?2oA~v)Bgi+ z6&&g~f*k+}Ex+En(k_-jpDcE$FME=X+j(@dxBkY{EP{2Kf}=RCEm!lvEx*2d70<7# zxpWpg9+=v-BRcf+WZ!`qC3XLV(`VdjH0<0Q9`=rh3|BlpWm#reviC}r6cm5&JfEjE zw*w%gR9nl2S!HbhdF$5PBfaEH4M%66>E0B=T;Js#GX@z)_alMi_0r4BAn4_Ir;jPa zm0GTBAm7dPfK!u!-T9^EPuf4pI~+nV_s&ZAxw&Vm9s_*eS2w+c)%s|!kJ+7l@NGh* zLzI*ATy@42Lg=cdfE7KE9`4e~1)qAPkTN3GZtpzVcb-Ni3deLGgmb&ePNhh$Dgzr3Ib2ycwA<(!h;Qo0hzihydL9J$Dm762J1tZ z?HcP>Jmh((nnSBT+wfolE!iJlXjmH3?5;qU z4rEI09cHAF4(HLp;Zik2P63O9LrF69*1u$>fqcdYvLd@u2yH{{>OCfJ_-3B`M~vrf zwP=$&kMz|OzKQR9FoX$+e!q)#?c8dC2PZstM!h&!R2vw_O@HOMS@BR@*B) z-F@6=Qn%k3n@QJyQGLtyVo-Ij#rMW5FD-u!&$^^z^na2 zKWVhJNuh#Q*jc$ntC`mXw3>U}kfciS*7HmEi`*95S$!f)X=_r}>1}bRu(x$b#Ix|` zEOTo2xd_i~cZ)rq3w+UzSNMZ~!Bzs;)6;0TzBc*q;>1bMO@vcU!|;b~kq@EACyskg zrQF8S%;!2?%$^+zdQqzf+7xtv>m12GM!nnpo+~}`03aq^#@%_si0}=jd{$$@lx5WO z=X9d{*giR0-~Z5RKd|wjaYKx!UgN(rv)Lm$L5RdjopQmLFz-s54Ef=|s zWYit%k_Pq;k;WA@4s@=4e3Q}H`SfW+wd{*RnTAzlZM#xjM1$(Tpqhz0@a^0wy4b+& zH88eCQa}DzvlD1Hp^9)V!juah7P7%}tGkrzh+t9o>0?l^BFe_z?6oXWW%kR&6vU*l zbI%Mt)z@!U?G+n2$PxQPXZhNpux=EBcHJ1#awSK&7UfL1GhHJ3mno98Cm~swmM*l3 z0_Eu?LG|afk_=$EyAmd$IF&JOTmA}T9@L31EVUCQQNS+cnaUR_GN{w_nE3TXCB_<8 zsy8ajVfTRiX7=c!^O6qJ)LOJRc1rZ6K1|PG`x)XS%jj$a^SziV#849^(K3&?FsF+D zNa;BIme*!CUqhg+i^vYJd**jDo#3waXfz4p(|QuW1bwavI|G>)oI9sBs4D&H#aL)D zpjm|dyJwjBG($cyL$$x-PW}_!(@W_hr)Y!_udbR&K7JRhqxi^J*N1h!%9@w$qgJj6 z$`s5N{rettgix<~v!mc29?RUF#1LFW9?R%W!x~8EJjHSaA9j!;+m$z&``)YKytl&& zP!b7}!%O%@?l2Ms-uv`QV4Pv~HIkAHQxWI5)0+cAJfxy!HJ_rzY>H|k|(6e^etC@e_P zOTMQA7L!$UYoy@|Ujh*&jE#H6=t53cS%O!Y+XFJeYLq#WmTy2%T9lMi5lo#x4z%^M z5|v@gjOz3oU6r!Ie;yPx+BgoDo<4n6u~?zsd%**QzHHY5)N_- zbkKx|o2oOTHkF0%RB|fq_ePw&D%!7p+ip{_2p17y@vvC8-}o`t5JmF==A|x;b)%Pv zNgs`97u>xbS&b0cPb;!wy`U0dD_r4wRta*NW!J3Xw;0%?nfR4AifW@)=}8WPXmCQu z*RLHMtV+PMe+mpQlTNj)?+zoGs2z*G;^(QCJxiv3Q#v^)d`Z+G1E;|1t#dsZo6|oh z(R-D6b>ilg+h42oXMLV)4*o*M?uQ@&?iS)aA%W1_CTaLk9J z*F^4x_?YVB9-LkxD^-QnM6bRsRfhu zB>%|A94Qqc!4AwZ(3Keyo;Xv3Q)w643}dO~K@$j~G!&Ws_c@D_7?T&KXn5*QW4;K!FRQN|f7()C@7vLRyP6TMyPk*q^CQ2#^~1(Dvft~PxyVQ3<8GvW z85}Rt7xqrJaAn^Uj?l_$?T)l`Fn_xSwonV2+~gq@Ae^5N zOi0x*htwWWKR&Dh)ydppa(|-ugvO;wtjklEl~}V6Lm^L=QRI!-`?;yZvhTh)AlEE9 zm)>FqE%cN2-}2nSJAJlm<9)<;`ex!c3;iB*i{ac0rt>?*S57Y8m^~-m4h8y_FW{!y z|6~(Uz3l-Znyk&4r_SM*fXh^?_#W?E;QZ*%GbMijo!^JVmV{akfX{KH8t?D&7ECHf z3E5V~*+0TK%AEeL0oJ8BBcsr}VjOV~d_;WjjB!O);dVh$g1ER;Nf{ zg)|t#pOP@!xp2Y8*fUpmZ0Y`IIYL2Y=Eim4my$?Pj^OjY=#Jrl>LX`XEBDWgsr3#q z_Roc=SDi!&TEiUEwnQUAYq(tBBCt$Wz|B{d(J`Skqiiu`IVNgwC!P~-$OhXpqS{!v zdW1By!`q!NBj@!Wmo@ZsHZL?wSKzX8vP3V5ng(Yh>)DvFMD#FP%?_${Q&#BHq5Hw; z`Ar9{_fHvDmb1L;(_p3h`yXY94`xi^GL?y$^P$Hi$wE+IXAlu7@SFlT*_YL}M9@Am zbPJ+$b^HDc(JceFB-f|vkXOLjs5ew78`zRunUGL#UMxjp(Fto~3l$duK`*LPFsu_Renl*yF1g60u7u--)0ol>J80 zUv#VH{Q}(!(wqD`S8z`|A49@_Eve*s$$<_kKD8R^%oG3^dd9Sqi-l| zeZk+0*ZMC>U+5G6-?d-5D|VGH@|Z8uUUyIed+e`1x{)E$N~{wh-~Fjozez{mYTCl+ zBF`~z>h_HGVpj>G82NgDoJ>r|e&_%c(<#3 zxQ$CvdG{VJ?Nx}7CpU~GY%3MqtOQ3IJd(s>?$MERocqVuz$e!*M?_+egBzr<|BViV z!k&)8H?kj`i))Hni?RRGz)Ej|3Y=G7W43nFU2;>Nytq3X`4 zDQaJBXTL$1H0>R6}zWXI`+RuuT&zqYG0e64P0IKH1=-%ck8m!hvV8)Xzq zWm5s-tdU+TV7pseym$v&;~)>#oHsAk{QKXmFj4BDYn2~a9QV}@PtDy}>OQ1H(cKLQ zhJ>s5h?GBIW2!Q&RIJS_D4f>=0Y61V5+g4HjdeZLQ^ahZ;%8o%ZU$-8AE`~FF9TVGj)1q7I}Be*ln{~UxJca5M>@)Vmy5Aw;hETJ^eL|@;A**s z_H|QufB@>CdC&0K2VCAD17~;ibx>jt1|`)<-4*Y@`wCJ@1uB_x;unFZ#d7xH07bs< z(pQdRM?mKU9IRC&fa`notqWZdk5SLGU7y*-VrRZ~z?p_NTFIznxOXSAox;R3z(*KH zUt1LxMPL5V36A9M@UBPIGlYukDH~jA!?*DEb#N2CIYPe$@A~43(rnpQShR5y_2^fZwmB=wlLfDbd{2{W)Q1}d5Aio|s zBb<>q4BW%+F9GCg0qVD5h(6|Ro#ML=mT2b?LLal-ffpu^cy0iv(r{%@jM6KR z-=`)YjHBL-TR%5)A!0Hlgy0MpIMwnD%{aUhmHXNVcOEzam8UMHU~M8i2ytHm5>Qq| zi%UciYan}Yx~>!~m#r|X18h};0eC+JtMl-*^r{TvH>Qyf5(8AX@gS{Kbu<;M%Wrlw z7Q<4(J_n^&x?lQ~&UAc?I=c>Pnbmc9Ap!%73d|elMMxC|Fj<_&b7uQobM)Wu#2*^td%{PM!KZ5z-o zvAYrwNe4+walb?Kzx|K?x_BgWOMfLmB<2ttkoj5hZxU0wHk5B~&2J4>Df|CW@v0OV)osoXJI?_{y>(aF9c6wUFUQKMr_?4HAZvdhJW`?A@YIg=)L7{9f6HNoabR+9p)JY0nS^TTY3F` zik#G?PBp!E5^t5%te!pg1DLT)M{e80=S`QiCoZlEC~h^rJwjb&P@phRnMt9KDnx$# z+Lfj_Ksc1nrzI*U>fIL|t0N2draNBwr$r{5H+1pOt0$A-bi5PNP;29M3}5L+k=-i1 zWzfp`@wsLClhr2=-pS-XU3V=6DJQqbum02Y)A}A|FmZJ`o+ilZy2XDCIGVhW>FTP= zZ$wmnvD6eRa3yw%T89_nk8u%=p#fur z-m@vg`-;P=OVtZqPBcSG;*QEL*sy;5)lkx3|DkbhGf1b7f$9TR=@{&B<)umqWw#t# zxyZ;DCcN091k>5`4kwzv6t5XJf11-LGrkA{w44O=Ee)|;#67Ug`5FBVaIP^Yf@ACi z4)zL&zlnJaF6HdFxkjYhjGiroOhffAxv@!5<+Md8u$M4{J=C!4AsOLAOcIdaXN1J| zMQkuZQi%!6wUsV-Bq|ar$Ok(Z4sy|xlcliN>BHENXHHk|VRtB0sc>2GOxcA4Nxz%Y z;7A{SkAhBFcMslGZH$!YzwY=UL9Rd6K^zfkDx(~eGIXNn!ZJ7zv~x$A{ShEDfsK#3 zCE`}sZAk9a&^C&Dw$-UMqV9EoJS*9Zv1G@*Kl@QCup)kKL*{6L#N*J{Q}j78v)Swe zFPi;|6VWX3VRa*!7%q3XSjTe(^z6%>TqZ->p!CBV%wA_L-z0|P>GAZ!c(_m4&5FO* zSLzf^lsp~&?Fy5o;S{}qCb-Ywh`s;mjWA>l#*9>|d7&wTT46OKyOP*0*Aj1D0mw{z zt+){pvM7=a?VpME8sjy`!lpq5_F`kG79A(>Bzsl^Z{6dC93A3E>v z$4@yF?H;vD49Gv4@Jfie3HRV?1vd&Gc=)qZ*5Q>&KIo>FZukiMel^KH}S z{bR-Vm|BD<%Cocy@?#>SsIf!3n_y>PR&N;RP^Kv&n)=!TR9cy11M^gy2fT<$Iwx|( z{f8ALxloUC+_tcCl+G+8MX0f~bZ7O7Txk(Z@TuAC&$P{Ml_ma@(O zKeR@sm8K7E<`ZQN?xbvn!tk`xE-OA=*}^^Fe1V+dRo@1Sq2~Us`f>LDS^kGxQECI>Dfg{D50)am)tuB;F-Iv3FrI6hbgd8bW1Od1pd-wco9&}Nob@Mg zLyGm>Fs;i!uh-5^k#@p6yhlNDOACoe;h_S!4k=JFW8VGt*^wZC3O3BI*6?MZ7wNWz z+iNO!Y4SQ{|LUoT^GQs-AHZI|zD!AB9zjeEo93mi8s5sDak?Z@UMHGu9pP;Hy)=E3 z=?5nMWM6VEfQ)1On2JUssd7hB@*_h7m0%^?Wa0B@EjDkLhW-uIxvrjAzd&dMjAb#S zoCq?ciR)%3n9~QD_H_(U|MD#Qx7oh-54Lz~{X5pM+3eUs37Da#yy3Ajlc`2)8C(5C zGA>T&`nkO={}ftrckin`KcT(=%{KAMp~t3FO)VbVsfv^@aq6}_hy1G!2upt z5I_l43X+hl%e}Zbgq|NENY-W8=!`4pTfjgtDSDpy0t2F?!vKN0zCb-M`q^qd!kB75 zv94@zh#Ag8l!jhZZ>{maK1R# z_z^FpRr~2IR3)?{5p)Ddk$WKk_nLdj|AKo4g2rK42oHRo0M&}fTVax7%f=ulxwHy>l983(>KB9B-)|D(% zA_J-rniBjEIqO8VmE|h;Uxt4Lo`PPozPpdFf4L&(G;I^vgixxylF;HMVEF6_O9EkgtI-={QZaWHkt>fL@ZI-@ed#lWbg8 zlNo=>M)>fZ7?2M&Wym6OYNz$SW^D@dwE0z~rR+Zzg8?Vcy{4R{#RZ#(9y0D2oq-g( zKD72aQV|f_XNx2_s*}pvkloufZ?mTmoea+<9#jOb=`pARa#)sJgDOoM^1AaDj*#1qGm<}%)PB^xsEWzSim91yG;Bng6z9D`frmuT>j z4cWCgRmhO?Co-D1ANvGQa`bbCa#9AOr}!gDcWTsFa9+ z9X3runldna$V(9+WgjJ#!KA}H*ftKR`IvmmPp}F

?OR99f7!1pOv4kMq)w#3|e# z2VqfF!2SHq2(L`0sVaRTZKe9k?=i4@oldhuS)x~&;@d77Md>#|NZT>NZmA_~9Avhx z^TzAW)K6KtK*5BVP+NgCCN|+XV7~Acrnz0%_b*6>0T;Z2MrMNzFDJsxZvr?llw5ZC z?7bqCM)wl_H2}7OF$Hfuo1qvSzgxlJmPRveF&aPH|Q zpjmW`lep@Qkr%Xjdo7+f!-R-EeE^1vx)d_UiX2SLn3MBc!xDbe2b~(g|6%eLl<9D`S-7=(GZo zr|4n@n+${U^$M3`7Z7`hxk0f0{NldC$sSB^Ux}mz6Sm`ewJmPU_S9|!<`gSLGqHa; z)c}M{SxSp&NEn)A81fO5y~qibWaxSih5|dyXQda^o>$XN=VyMWAU7q=*&%Miov+0B zrZ4(p*^#So+Dft@JbbDkSGnMYvh3A(Q)B=aF6aUu<)d%N<(|VK{k#x@9{`aC3Ar!0 zgu>i&kAg$tK@Q0w^hcBQW-bqXHui1>P@mY#iit(e)nuKCeYs+j5;(*%9YWH$$%pyy z*oCy28rgUN`E4D3Jn$xTgB1xN9`c;OCk_51>GH$yrgt-&=3mm88WRPUGeDM`Ab&S>83Ryj#T z<~9azG&H#&EGI7d+|0G3`Bep7{T*9kh)t2*qo6N^**p)_lrN;oCAa~}?CEe9QGYj~ z;FmvJQDZf)b{n}?h98iLyK@ewYf$?#p8sHSta68~yUuZU`*?SU40p#8_r105``X-{ z2Hf|*b9esc?y})d5%X|W^l;PlIIzdVeZPl?zlY~>kAv|ZUKt+VB_2Mt9=>fJeghu< z?>r8D^EkZWK^60)DS8IzdIs(pJyc>B?2idL?imvA>E=Hgoa}kD*7I0}dzi=Qv3H&) zzKu@xjfO3Io>Dv*0e|zGa4>5Bo1;bte^U;|#J}-q6W&n`C60)l4)%;4I2bQBa(jiT zNgXCOzhRCYOwb*3YD>e?6V48ZG525+Hj<2M2hJuopAKEAyLIed!~M ze8#w24+aHB5m=?}X(_+F@{W6VYeH9Ky=kIMpt1YpJFlw)-gzT%Azt2rSXPn;D~th? zCXE-h9W2@JlNk&X0)ZX)NKQ0_oO%hh%jdL*PmR%72B|bj$}R56c#W8E?D3?WaA=ap zSh9zAos{oG+k+3~Q9H)qC_04kz$fy!Z|k;$F+d`d2bLsy8=Jy6B#W*L_;$^Eb~wP! z2V!LSNe#B_&OLs86`mcM_D+z z)fZgL{Qb>u<;vlW{UfJWQrxQ(HOG22s}pmV-lq3XZS1GI+X~Hp^J8Z_jd)OnJV)*u z@hTXCH)g7s@rdwgY7&>qe@DeikD%3cfor2!XBx$W)x2>?(vya}<^jv3$vKb6-k~XE ldM*smlrla0B)jnlrjpW(Tics3&1 |` + * [Fish](http://fishshell.com/) shell: `^|` + + +#### Longer version + +`pp` streams its stdin to stdout as long as it doesn't detect any panic. +`panic()` and Go's native deadlock detector [print to +stderr](https://golang.org/src/runtime/panic1.go) via the native [`print()` +function](https://golang.org/pkg/builtin/#print). + + +**Bash v4** or **zsh**: `|&` tells the shell to redirect stderr to stdout, +it's an alias for `2>&1 |` ([bash +v4](https://www.gnu.org/software/bash/manual/bash.html#Pipelines), +[zsh](http://zsh.sourceforge.net/Doc/Release/Shell-Grammar.html#Simple-Commands-_0026-Pipelines)): + + go test -v |&pp + + +**Windows or OSX native bash** [(which is +3.2.57)](http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/): They don't +have this shortcut, so use the long form: + + go test -v 2>&1 | pp + + +**Fish**: It uses [^ for stderr +redirection](http://fishshell.com/docs/current/tutorial.html#tut_pipes_and_redirections) +so the shortcut is `^|`: + + go test -v ^|pp + + +**PowerShell**: [It has broken `2>&1` redirection](https://connect.microsoft.com/PowerShell/feedback/details/765551/in-powershell-v3-you-cant-redirect-stderr-to-stdout-without-generating-error-records). The workaround is to shell out to cmd.exe. :( + + +### Investigate deadlock + +On POSIX, use `Ctrl-\` to send SIGQUIT to your process, `pp` will ignore +the signal and will parse the stack trace. + + +### Parsing from a file + +To dump to a file then parse, pass the file path of a stack trace + + go test 2> stack.txt + pp stack.txt + + +Tips +---- + +### GOTRACEBACK + +Starting with Go 1.6, [`GOTRACEBACK`](https://golang.org/pkg/runtime/) defaults +to `single` instead of `all` / `1` that was used in 1.5 and before. To get all +goroutines trace and not just the crashing one, set the environment variable: + + export GOTRACEBACK=all + +or `set GOTRACEBACK=all` on Windows. Probably worth to put it in your `.bashrc`. + + +### Updating bash on OSX + +Install bash v4+ on OSX via [homebrew](http://brew.sh) or +[macports](https://www.macports.org/). Your future self will appreciate having +done that. + + +### If you have `/usr/bin/pp` installed + +If you try `pp` for the first time and you get: + + Creating tables and indexes... + Done. + +and/or + + /usr/bin/pp5.18: No input files specified + +you may be running the _Perl PAR Packager_ instead of panicparse. + +You have two choices, either you put `$GOPATH/bin` at the begining of `$PATH` or +use long name `panicparse` with: + + go get github.com/maruel/panicparse + +then using `panicparse` instead of `pp`: + + go test 2> panicparse diff --git a/vendor/github.com/maruel/panicparse/main.go b/vendor/github.com/maruel/panicparse/main.go new file mode 100644 index 0000000..67d8e1a --- /dev/null +++ b/vendor/github.com/maruel/panicparse/main.go @@ -0,0 +1,31 @@ +// Copyright 2015 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +// panicparse: analyzes stack dump of Go processes and simplifies it. +// +// It is mostly useful on servers will large number of identical goroutines, +// making the crash dump harder to read than strictly necesary. +// +// Colors: +// - Magenta: first goroutine to be listed. +// - Yellow: main package. +// - Green: standard library. +// - Red: other packages. +// +// Bright colors are used for exported symbols. +package main + +import ( + "fmt" + "os" + + "github.com/maruel/panicparse/internal" +) + +func main() { + if err := internal.Main(); err != nil { + fmt.Fprintf(os.Stderr, "Failed: %s\n", err) + os.Exit(1) + } +} diff --git a/vendor/github.com/maruel/panicparse/stack/source.go b/vendor/github.com/maruel/panicparse/stack/source.go new file mode 100644 index 0000000..a747250 --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/source.go @@ -0,0 +1,302 @@ +// Copyright 2015 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +// This file contains the code to process sources, to be able to deduct the +// original types. + +package stack + +import ( + "bytes" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io/ioutil" + "log" + "math" + "strings" +) + +// cache is a cache of sources on the file system. +type cache struct { + files map[string][]byte + parsed map[string]*parsedFile +} + +// Augment processes source files to improve calls to be more descriptive. +// +// It modifies goroutines in place. +func Augment(goroutines []Goroutine) { + c := &cache{} + for i := range goroutines { + c.augmentGoroutine(&goroutines[i]) + } +} + +// augmentGoroutine processes source files to improve call to be more +// descriptive. +// +// It modifies the routine. +func (c *cache) augmentGoroutine(goroutine *Goroutine) { + if c.files == nil { + c.files = map[string][]byte{} + } + if c.parsed == nil { + c.parsed = map[string]*parsedFile{} + } + // For each call site, look at the next call and populate it. Then we can + // walk back and reformat things. + for i := range goroutine.Stack.Calls { + c.load(goroutine.Stack.Calls[i].SourcePath) + } + + // Once all loaded, we can look at the next call when available. + for i := 0; i < len(goroutine.Stack.Calls)-1; i++ { + // Get the AST from the previous call and process the call line with it. + if f := c.getFuncAST(&goroutine.Stack.Calls[i]); f != nil { + processCall(&goroutine.Stack.Calls[i], f) + } + } +} + +// Private stuff. + +// load loads a source file and parses the AST tree. Failures are ignored. +func (c *cache) load(fileName string) { + if _, ok := c.parsed[fileName]; ok { + return + } + c.parsed[fileName] = nil + if !strings.HasSuffix(fileName, ".go") { + // Ignore C and assembly. + c.files[fileName] = nil + return + } + log.Printf("load(%s)", fileName) + if _, ok := c.files[fileName]; !ok { + var err error + if c.files[fileName], err = ioutil.ReadFile(fileName); err != nil { + log.Printf("Failed to read %s: %s", fileName, err) + c.files[fileName] = nil + return + } + } + fset := token.NewFileSet() + src := c.files[fileName] + parsed, err := parser.ParseFile(fset, fileName, src, 0) + if err != nil { + log.Printf("Failed to parse %s: %s", fileName, err) + return + } + // Convert the line number into raw file offset. + offsets := []int{0, 0} + start := 0 + for l := 1; start < len(src); l++ { + start += bytes.IndexByte(src[start:], '\n') + 1 + offsets = append(offsets, start) + } + c.parsed[fileName] = &parsedFile{offsets, parsed} +} + +func (c *cache) getFuncAST(call *Call) *ast.FuncDecl { + if p := c.parsed[call.SourcePath]; p != nil { + return p.getFuncAST(call.Func.Name(), call.Line) + } + return nil +} + +type parsedFile struct { + lineToByteOffset []int + parsed *ast.File +} + +// getFuncAST gets the callee site function AST representation for the code +// inside the function f at line l. +func (p *parsedFile) getFuncAST(f string, l int) (d *ast.FuncDecl) { + if len(p.lineToByteOffset) <= l { + // The line number in the stack trace line does not exist in the file. That + // can only mean that the sources on disk do not match the sources used to + // build the binary. + // TODO(maruel): This should be surfaced, so that source parsing is + // completely ignored. + return + } + + // Walk the AST to find the lineToByteOffset that fits the line number. + var lastFunc *ast.FuncDecl + var found ast.Node + // Inspect() goes depth first. This means for example that a function like: + // func a() { + // b := func() {} + // c() + // } + // + // Were we are looking at the c() call can return confused values. It is + // important to look at the actual ast.Node hierarchy. + ast.Inspect(p.parsed, func(n ast.Node) bool { + if d != nil { + return false + } + if n == nil { + return true + } + if found != nil { + // We are walking up. + } + if int(n.Pos()) >= p.lineToByteOffset[l] { + // We are expecting a ast.CallExpr node. It can be harder to figure out + // when there are multiple calls on a single line, as the stack trace + // doesn't have file byte offset information, only line based. + // gofmt will always format to one function call per line but there can + // be edge cases, like: + // a = A{Foo(), Bar()} + d = lastFunc + //p.processNode(call, n) + return false + } else if f, ok := n.(*ast.FuncDecl); ok { + lastFunc = f + } + return true + }) + return +} + +func name(n ast.Node) string { + switch t := n.(type) { + case *ast.InterfaceType: + return "interface{}" + case *ast.Ident: + return t.Name + case *ast.SelectorExpr: + return t.Sel.Name + case *ast.StarExpr: + return "*" + name(t.X) + default: + return "" + } +} + +// fieldToType returns the type name and whether if it's an ellipsis. +func fieldToType(f *ast.Field) (string, bool) { + switch arg := f.Type.(type) { + case *ast.ArrayType: + return "[]" + name(arg.Elt), false + case *ast.Ellipsis: + return name(arg.Elt), true + case *ast.FuncType: + // Do not print the function signature to not overload the trace. + return "func", false + case *ast.Ident: + return arg.Name, false + case *ast.InterfaceType: + return "interface{}", false + case *ast.SelectorExpr: + return arg.Sel.Name, false + case *ast.StarExpr: + return "*" + name(arg.X), false + case *ast.MapType: + return fmt.Sprintf("map[%s]%s", name(arg.Key), name(arg.Value)), false + case *ast.ChanType: + return fmt.Sprintf("chan %s", name(arg.Value)), false + default: + // TODO(maruel): Implement anything missing. + return "", false + } +} + +// extractArgumentsType returns the name of the type of each input argument. +func extractArgumentsType(f *ast.FuncDecl) ([]string, bool) { + var fields []*ast.Field + if f.Recv != nil { + if len(f.Recv.List) != 1 { + panic("Expect only one receiver; please fix panicparse's code") + } + // If it is an object receiver (vs a pointer receiver), its address is not + // printed in the stack trace so it needs to be ignored. + if _, ok := f.Recv.List[0].Type.(*ast.StarExpr); ok { + fields = append(fields, f.Recv.List[0]) + } + } + var types []string + extra := false + for _, arg := range append(fields, f.Type.Params.List...) { + // Assert that extra is only set on the last item of fields? + var t string + t, extra = fieldToType(arg) + mult := len(arg.Names) + if mult == 0 { + mult = 1 + } + for i := 0; i < mult; i++ { + types = append(types, t) + } + } + return types, extra +} + +// processCall walks the function and populate call accordingly. +func processCall(call *Call, f *ast.FuncDecl) { + values := make([]uint64, len(call.Args.Values)) + for i := range call.Args.Values { + values[i] = call.Args.Values[i].Value + } + index := 0 + pop := func() uint64 { + if len(values) != 0 { + x := values[0] + values = values[1:] + index++ + return x + } + return 0 + } + popName := func() string { + n := call.Args.Values[index].Name + v := pop() + if len(n) == 0 { + return fmt.Sprintf("0x%x", v) + } + return n + } + + types, extra := extractArgumentsType(f) + for i := 0; len(values) != 0; i++ { + var t string + if i >= len(types) { + if !extra { + // These are unexpected value! Print them as hex. + call.Args.Processed = append(call.Args.Processed, popName()) + continue + } + t = types[len(types)-1] + } else { + t = types[i] + } + switch t { + case "float32": + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%g", math.Float32frombits(uint32(pop())))) + case "float64": + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%g", math.Float64frombits(pop()))) + case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64": + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%d", pop())) + case "string": + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%s(%s, len=%d)", t, popName(), pop())) + default: + if strings.HasPrefix(t, "*") { + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%s(%s)", t, popName())) + } else if strings.HasPrefix(t, "[]") { + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%s(%s len=%d cap=%d)", t, popName(), pop(), pop())) + } else { + // Assumes it's an interface. For now, discard the object value, which + // is probably not a good idea. + call.Args.Processed = append(call.Args.Processed, fmt.Sprintf("%s(%s)", t, popName())) + pop() + } + } + if len(values) == 0 && call.Args.Elided { + return + } + } +} diff --git a/vendor/github.com/maruel/panicparse/stack/source_test.go b/vendor/github.com/maruel/panicparse/stack/source_test.go new file mode 100644 index 0000000..1c5d194 --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/source_test.go @@ -0,0 +1,563 @@ +// Copyright 2015 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package stack + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/maruel/ut" +) + +func TestAugment(t *testing.T) { + data := []struct { + name string + input string + expected Stack + }{ + { + "Local function doesn't interfere", + `package main + func f(s string) { + a := func(i int) int { + return 1 + i + } + _ = a(3) + panic("ooh") + } + func main() { + f("yo") + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 7, Func: Function{"main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer, Name: ""}, {Value: 0x2}}, + }, + }, + {SourcePath: "main.go", Line: 10, Func: Function{"main.main"}}, + }, + }, + }, + { + "func", + `package main + func f(a func() string) { + panic(a()) + } + func main() { + f(func() string { return "ooh" }) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{Values: []Arg{{Value: pointer}}}, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "func ellipsis", + `package main + func f(a ...func() string) { + panic(a[0]()) + } + func main() { + f(func() string { return "ooh" }) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: 0x1}, {Value: 0x1}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "interface{}", + `package main + func f(a []interface{}) { + panic("ooh") + } + func main() { + f(make([]interface{}, 5, 7)) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: 0x5}, {Value: 0x7}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "[]int", + `package main + func f(a []int) { + panic("ooh") + } + func main() { + f(make([]int, 5, 7)) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: 5}, {Value: 7}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "[]interface{}", + `package main + func f(a []interface{}) { + panic(a[0].(string)) + } + func main() { + f([]interface{}{"ooh"}) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: 1}, {Value: 1}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "map[int]int", + `package main + func f(a map[int]int) { + panic("ooh") + } + func main() { + f(map[int]int{1: 2}) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "map[interface{}]interface{}", + `package main + func f(a map[interface{}]interface{}) { + panic("ooh") + } + func main() { + f(make(map[interface{}]interface{})) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "chan int", + `package main + func f(a chan int) { + panic("ooh") + } + func main() { + f(make(chan int)) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "chan interface{}", + `package main + func f(a chan interface{}) { + panic("ooh") + } + func main() { + f(make(chan interface{})) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "non-pointer method", + `package main + type S struct { + } + func (s S) f() { + panic("ooh") + } + func main() { + var s S + s.f() + }`, + Stack{ + Calls: []Call{ + {SourcePath: "main.go", Line: 5, Func: Function{Raw: "main.S.f"}}, + {SourcePath: "main.go", Line: 9, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "pointer method", + `package main + type S struct { + } + func (s *S) f() { + panic("ooh") + } + func main() { + var s S + s.f() + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 5, Func: Function{Raw: "main.(*S).f"}, + Args: Args{Values: []Arg{{Value: pointer}}}, + }, + {SourcePath: "main.go", Line: 9, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "string", + `package main + func f(s string) { + panic(s) + } + func main() { + f("ooh") + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{Values: []Arg{{Value: pointer}, {Value: 0x3}}}, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "string and int", + `package main + func f(s string, i int) { + panic(s) + } + func main() { + f("ooh", 42) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{Values: []Arg{{Value: pointer}, {Value: 0x3}, {Value: 42}}}, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "values are elided", + `package main + func f(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12 int, s13 interface{}) { + panic("ooh") + } + func main() { + f(0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 45, nil) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{}, {}, {}, {}, {}, {}, {}, {}, {Value: 42}, {Value: 43}}, + Elided: true, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "error", + `package main + import "errors" + func f(err error) { + panic(err.Error()) + } + func main() { + f(errors.New("ooh")) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 4, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 7, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "error unnamed", + `package main + import "errors" + func f(error) { + panic("ooh") + } + func main() { + f(errors.New("ooh")) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 4, Func: Function{Raw: "main.f"}, + Args: Args{ + Values: []Arg{{Value: pointer}, {Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 7, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "float32", + `package main + func f(v float32) { + panic("ooh") + } + func main() { + f(0.5) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + // The value is NOT a pointer but floating point encoding is not + // deterministic. + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + { + "float64", + `package main + func f(v float64) { + panic("ooh") + } + func main() { + f(0.5) + }`, + Stack{ + Calls: []Call{ + { + SourcePath: "main.go", Line: 3, Func: Function{Raw: "main.f"}, + Args: Args{ + // The value is NOT a pointer but floating point encoding is not + // deterministic. + Values: []Arg{{Value: pointer}}, + }, + }, + {SourcePath: "main.go", Line: 6, Func: Function{Raw: "main.main"}}, + }, + }, + }, + } + + for i, line := range data { + extra := bytes.Buffer{} + _, content := getCrash(t, line.input) + goroutines, err := ParseDump(bytes.NewBuffer(content), &extra) + if err != nil { + t.Fatalf("failed to parse input for test %s: %v", line.name, err) + } + // On go1.4, there's one less space. + actual := extra.String() + if actual != "panic: ooh\n\nexit status 2\n" && actual != "panic: ooh\nexit status 2\n" { + t.Fatalf("Unexpected panic output:\n%#v", actual) + } + s := goroutines[0].Signature.Stack + t.Logf("Test: %v", line.name) + zapPointers(t, line.name, &line.expected, &s) + zapPaths(&s) + ut.AssertEqualIndex(t, i, line.expected, s) + } +} + +func TestAugmentDummy(t *testing.T) { + goroutines := []Goroutine{ + { + Signature: Signature{ + Stack: Stack{ + Calls: []Call{{SourcePath: "missing.go"}}, + }, + }, + }, + } + Augment(goroutines) +} + +func TestLoad(t *testing.T) { + c := &cache{ + files: map[string][]byte{"bad.go": []byte("bad content")}, + parsed: map[string]*parsedFile{}, + } + c.load("foo.asm") + c.load("bad.go") + c.load("doesnt_exist.go") + if l := len(c.parsed); l != 3 { + t.Fatalf("expected 3, got %d", l) + } + if c.parsed["foo.asm"] != nil { + t.Fatalf("foo.asm is not present; should not have been loaded") + } + if c.parsed["bad.go"] != nil { + t.Fatalf("bad.go is not valid code; should not have been loaded") + } + if c.parsed["doesnt_exist.go"] != nil { + t.Fatalf("doesnt_exist.go is not present; should not have been loaded") + } + if c.getFuncAST(&Call{SourcePath: "other"}) != nil { + t.Fatalf("there's no 'other'") + } +} + +// + +const pointer = uint64(0xfffffffff) +const pointerStr = "0xfffffffff" + +func overrideEnv(env []string, key, value string) []string { + prefix := key + "=" + for i, e := range env { + if strings.HasPrefix(e, prefix) { + env[i] = prefix + value + return env + } + } + return append(env, prefix+value) +} + +func getCrash(t *testing.T, content string) (string, []byte) { + name, err := ioutil.TempDir("", "panicparse") + if err != nil { + t.Fatalf("failed to create temporary directory: %v", err) + } + defer func() { + if err := os.RemoveAll(name); err != nil { + t.Fatalf("failed to remove temporary directory %q: %v", name, err) + } + }() + main := filepath.Join(name, "main.go") + if err := ioutil.WriteFile(main, []byte(content), 0500); err != nil { + t.Fatalf("failed to write %q: %v", main, err) + } + cmd := exec.Command("go", "run", main) + // Use the Go 1.4 compatible format. + cmd.Env = overrideEnv(os.Environ(), "GOTRACEBACK", "1") + out, err := cmd.CombinedOutput() + if err == nil { + t.Fatal("expected error since this is supposed to crash") + } + return main, out +} + +// zapPointers zaps out pointers. +func zapPointers(t *testing.T, name string, expected, s *Stack) { + for i := range s.Calls { + if i >= len(expected.Calls) { + // When using GOTRACEBACK=2, it'll include runtime.main() and + // runtime.goexit(). Ignore these since they could be changed in a future + // version. + s.Calls = s.Calls[:len(expected.Calls)] + break + } + for j := range s.Calls[i].Args.Values { + if j >= len(expected.Calls[i].Args.Values) { + break + } + if expected.Calls[i].Args.Values[j].Value == pointer { + // Replace the pointer value. + if s.Calls[i].Args.Values[j].Value == 0 { + t.Fatalf("%s: Call %d, value %d, expected pointer, got 0", name, i, j) + } + old := fmt.Sprintf("0x%x", s.Calls[i].Args.Values[j].Value) + s.Calls[i].Args.Values[j].Value = pointer + for k := range s.Calls[i].Args.Processed { + s.Calls[i].Args.Processed[k] = strings.Replace(s.Calls[i].Args.Processed[k], old, pointerStr, -1) + } + } + } + } +} + +// zapPaths removes the directory part and only keep the base file name. +func zapPaths(s *Stack) { + for j := range s.Calls { + s.Calls[j].SourcePath = filepath.Base(s.Calls[j].SourcePath) + } +} diff --git a/vendor/github.com/maruel/panicparse/stack/stack.go b/vendor/github.com/maruel/panicparse/stack/stack.go new file mode 100644 index 0000000..a9917ed --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/stack.go @@ -0,0 +1,832 @@ +// Copyright 2015 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +// Package stack analyzes stack dump of Go processes and simplifies it. +// +// It is mostly useful on servers will large number of identical goroutines, +// making the crash dump harder to read than strictly necesary. +package stack + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "math" + "net/url" + "os" + "path/filepath" + "regexp" + "runtime" + "sort" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +const lockedToThread = "locked to thread" + +var ( + // TODO(maruel): Handle corrupted stack cases: + // - missed stack barrier + // - found next stack barrier at 0x123; expected + // - runtime: unexpected return pc for FUNC_NAME called from 0x123 + + reRoutineHeader = regexp.MustCompile("^goroutine (\\d+) \\[([^\\]]+)\\]\\:\r?\n$") + reMinutes = regexp.MustCompile("^(\\d+) minutes$") + reUnavail = regexp.MustCompile("^(?:\t| +)goroutine running on other thread; stack unavailable") + // See gentraceback() in src/runtime/traceback.go for more information. + // - Sometimes the source file comes up as "". It is the + // compiler than generated these, not the runtime. + // - The tab may be replaced with spaces when a user copy-paste it, handle + // this transparently. + // - "runtime.gopanic" is explicitly replaced with "panic" by gentraceback(). + // - The +0x123 byte offset is printed when frame.pc > _func.entry. _func is + // generated by the linker. + // - The +0x123 byte offset is not included with generated code, e.g. unnamed + // functions "func·006()" which is generally go func() { ... }() + // statements. Since the _func is generated at runtime, it's probably why + // _func.entry is not set. + // - C calls may have fp=0x123 sp=0x123 appended. I think it normally happens + // when a signal is not correctly handled. It is printed with m.throwing>0. + // These are discarded. + // - For cgo, the source file may be "??". + reFile = regexp.MustCompile("^(?:\t| +)(\\?\\?|\\|.+\\.(?:c|go|s))\\:(\\d+)(?:| \\+0x[0-9a-f]+)(?:| fp=0x[0-9a-f]+ sp=0x[0-9a-f]+)\r?\n$") + // Sadly, it doesn't note the goroutine number so we could cascade them per + // parenthood. + reCreated = regexp.MustCompile("^created by (.+)\r?\n$") + reFunc = regexp.MustCompile("^(.+)\\((.*)\\)\r?\n$") + reElided = regexp.MustCompile("^\\.\\.\\.additional frames elided\\.\\.\\.\r?\n$") + // Include frequent GOROOT value on Windows, distro provided and user + // installed path. This simplifies the user's life when processing a trace + // generated on another VM. + // TODO(maruel): Guess the path automatically via traces containing the + // 'runtime' package, which is very frequent. This would be "less bad" than + // throwing up random values at the parser. + goroots = []string{runtime.GOROOT(), "c:/go", "/usr/lib/go", "/usr/local/go"} +) + +// Similarity is the level at which two call lines arguments must match to be +// considered similar enough to coalesce them. +type Similarity int + +const ( + // ExactFlags requires same bits (e.g. Locked). + ExactFlags Similarity = iota + // ExactLines requests the exact same arguments on the call line. + ExactLines + // AnyPointer considers different pointers a similar call line. + AnyPointer + // AnyValue accepts any value as similar call line. + AnyValue +) + +// Function is a function call. +// +// Go stack traces print a mangled function call, this wrapper unmangle the +// string before printing and adds other filtering methods. +type Function struct { + Raw string +} + +// String is the fully qualified function name. +// +// Sadly Go is a bit confused when the package name doesn't match the directory +// containing the source file and will use the directory name instead of the +// real package name. +func (f Function) String() string { + s, _ := url.QueryUnescape(f.Raw) + return s +} + +// Name is the naked function name. +func (f Function) Name() string { + parts := strings.SplitN(filepath.Base(f.Raw), ".", 2) + if len(parts) == 1 { + return parts[0] + } + return parts[1] +} + +// PkgName is the package name for this function reference. +func (f Function) PkgName() string { + parts := strings.SplitN(filepath.Base(f.Raw), ".", 2) + if len(parts) == 1 { + return "" + } + s, _ := url.QueryUnescape(parts[0]) + return s +} + +// PkgDotName returns "." format. +func (f Function) PkgDotName() string { + parts := strings.SplitN(filepath.Base(f.Raw), ".", 2) + s, _ := url.QueryUnescape(parts[0]) + if len(parts) == 1 { + return parts[0] + } + if s != "" || parts[1] != "" { + return s + "." + parts[1] + } + return "" +} + +// IsExported returns true if the function is exported. +func (f Function) IsExported() bool { + name := f.Name() + parts := strings.Split(name, ".") + r, _ := utf8.DecodeRuneInString(parts[len(parts)-1]) + if unicode.ToUpper(r) == r { + return true + } + return f.PkgName() == "main" && name == "main" +} + +// Arg is an argument on a Call. +type Arg struct { + Value uint64 // Value is the raw value as found in the stack trace + Name string // Name is a pseudo name given to the argument +} + +// IsPtr returns true if we guess it's a pointer. It's only a guess, it can be +// easily be confused by a bitmask. +func (a *Arg) IsPtr() bool { + // Assumes all pointers are above 16Mb and positive. + return a.Value > 16*1024*1024 && a.Value < math.MaxInt64 +} + +func (a Arg) String() string { + if a.Name != "" { + return a.Name + } + if a.Value == 0 { + return "0" + } + return fmt.Sprintf("0x%x", a.Value) +} + +// Args is a series of function call arguments. +type Args struct { + Values []Arg // Values is the arguments as shown on the stack trace. They are mangled via simplification. + Processed []string // Processed is the arguments generated from processing the source files. It can have a length lower than Values. + Elided bool // If set, it means there was a trailing ", ..." +} + +func (a Args) String() string { + var v []string + if len(a.Processed) != 0 { + v = make([]string, 0, len(a.Processed)) + for _, item := range a.Processed { + v = append(v, item) + } + } else { + v = make([]string, 0, len(a.Values)) + for _, item := range a.Values { + v = append(v, item.String()) + } + } + if a.Elided { + v = append(v, "...") + } + return strings.Join(v, ", ") +} + +// Equal returns true only if both arguments are exactly equal. +func (a *Args) Equal(r *Args) bool { + if a.Elided != r.Elided || len(a.Values) != len(r.Values) { + return false + } + for i, l := range a.Values { + if l != r.Values[i] { + return false + } + } + return true +} + +// Similar returns true if the two Args are equal or almost but not quite +// equal. +func (a *Args) Similar(r *Args, similar Similarity) bool { + if a.Elided != r.Elided || len(a.Values) != len(r.Values) { + return false + } + if similar == AnyValue { + return true + } + for i, l := range a.Values { + switch similar { + case ExactFlags, ExactLines: + if l != r.Values[i] { + return false + } + default: + if l.IsPtr() != r.Values[i].IsPtr() || (!l.IsPtr() && l != r.Values[i]) { + return false + } + } + } + return true +} + +// Merge merges two similar Args, zapping out differences. +func (a *Args) Merge(r *Args) Args { + out := Args{ + Values: make([]Arg, len(a.Values)), + Elided: a.Elided, + } + for i, l := range a.Values { + if l != r.Values[i] { + out.Values[i].Name = "*" + out.Values[i].Value = l.Value + } else { + out.Values[i] = l + } + } + return out +} + +// Call is an item in the stack trace. +type Call struct { + SourcePath string // Full path name of the source file + Line int // Line number + Func Function // Fully qualified function name (encoded). + Args Args // Call arguments +} + +// Equal returns true only if both calls are exactly equal. +func (c *Call) Equal(r *Call) bool { + return c.SourcePath == r.SourcePath && c.Line == r.Line && c.Func == r.Func && c.Args.Equal(&r.Args) +} + +// Similar returns true if the two Call are equal or almost but not quite +// equal. +func (c *Call) Similar(r *Call, similar Similarity) bool { + return c.SourcePath == r.SourcePath && c.Line == r.Line && c.Func == r.Func && c.Args.Similar(&r.Args, similar) +} + +// Merge merges two similar Call, zapping out differences. +func (c *Call) Merge(r *Call) Call { + return Call{ + SourcePath: c.SourcePath, + Line: c.Line, + Func: c.Func, + Args: c.Args.Merge(&r.Args), + } +} + +// SourceName returns the base file name of the source file. +func (c *Call) SourceName() string { + return filepath.Base(c.SourcePath) +} + +// SourceLine returns "source.go:line", including only the base file name. +func (c *Call) SourceLine() string { + return fmt.Sprintf("%s:%d", c.SourceName(), c.Line) +} + +// FullSourceLine returns "/path/to/source.go:line". +func (c *Call) FullSourceLine() string { + return fmt.Sprintf("%s:%d", c.SourcePath, c.Line) +} + +// PkgSource is one directory plus the file name of the source file. +func (c *Call) PkgSource() string { + return filepath.Join(filepath.Base(filepath.Dir(c.SourcePath)), c.SourceName()) +} + +const testMainSource = "_test" + string(os.PathSeparator) + "_testmain.go" + +// IsStdlib returns true if it is a Go standard library function. This includes +// the 'go test' generated main executable. +func (c *Call) IsStdlib() bool { + for _, goroot := range goroots { + if strings.HasPrefix(c.SourcePath, goroot) { + return true + } + } + // Consider _test/_testmain.go as stdlib since it's injected by "go test". + return c.PkgSource() == testMainSource +} + +// IsPkgMain returns true if it is in the main package. +func (c *Call) IsPkgMain() bool { + return c.Func.PkgName() == "main" +} + +// Stack is a call stack. +type Stack struct { + Calls []Call // Call stack. First is original function, last is leaf function. + Elided bool // Happens when there's >100 items in Stack, currently hardcoded in package runtime. +} + +// Equal returns true on if both call stacks are exactly equal. +func (s *Stack) Equal(r *Stack) bool { + if len(s.Calls) != len(r.Calls) || s.Elided != r.Elided { + return false + } + for i := range s.Calls { + if !s.Calls[i].Equal(&r.Calls[i]) { + return false + } + } + return true +} + +// Similar returns true if the two Stack are equal or almost but not quite +// equal. +func (s *Stack) Similar(r *Stack, similar Similarity) bool { + if len(s.Calls) != len(r.Calls) || s.Elided != r.Elided { + return false + } + for i := range s.Calls { + if !s.Calls[i].Similar(&r.Calls[i], similar) { + return false + } + } + return true +} + +// Merge merges two similar Stack, zapping out differences. +func (s *Stack) Merge(r *Stack) *Stack { + // Assumes similar stacks have the same length. + out := &Stack{ + Calls: make([]Call, len(s.Calls)), + Elided: s.Elided, + } + for i := range s.Calls { + out.Calls[i] = s.Calls[i].Merge(&r.Calls[i]) + } + return out +} + +// Less compares two Stack, where the ones that are less are more +// important, so they come up front. A Stack with more private functions is +// 'less' so it is at the top. Inversely, a Stack with only public +// functions is 'more' so it is at the bottom. +func (s *Stack) Less(r *Stack) bool { + lStdlib := 0 + lPrivate := 0 + for _, c := range s.Calls { + if c.IsStdlib() { + lStdlib++ + } else { + lPrivate++ + } + } + rStdlib := 0 + rPrivate := 0 + for _, s := range r.Calls { + if s.IsStdlib() { + rStdlib++ + } else { + rPrivate++ + } + } + if lPrivate > rPrivate { + return true + } + if lPrivate < rPrivate { + return false + } + if lStdlib > rStdlib { + return false + } + if lStdlib < rStdlib { + return true + } + + // Stack lengths are the same. + for x := range s.Calls { + if s.Calls[x].Func.Raw < r.Calls[x].Func.Raw { + return true + } + if s.Calls[x].Func.Raw > r.Calls[x].Func.Raw { + return true + } + if s.Calls[x].PkgSource() < r.Calls[x].PkgSource() { + return true + } + if s.Calls[x].PkgSource() > r.Calls[x].PkgSource() { + return true + } + if s.Calls[x].Line < r.Calls[x].Line { + return true + } + if s.Calls[x].Line > r.Calls[x].Line { + return true + } + } + return false +} + +// Signature represents the signature of one or multiple goroutines. +// +// It is effectively the stack trace plus the goroutine internal bits, like +// it's state, if it is thread locked, which call site created this goroutine, +// etc. +type Signature struct { + // Use git grep 'gopark(|unlock)\(' to find them all plus everything listed + // in runtime/traceback.go. Valid values includes: + // - chan send, chan receive, select + // - finalizer wait, mark wait (idle), + // - Concurrent GC wait, GC sweep wait, force gc (idle) + // - IO wait, panicwait + // - semacquire, semarelease + // - sleep, timer goroutine (idle) + // - trace reader (blocked) + // Stuck cases: + // - chan send (nil chan), chan receive (nil chan), select (no cases) + // Runnable states: + // - idle, runnable, running, syscall, waiting, dead, enqueue, copystack, + // Scan states: + // - scan, scanrunnable, scanrunning, scansyscall, scanwaiting, scandead, + // scanenqueue + State string + CreatedBy Call // Which other goroutine which created this one. + SleepMin int // Wait time in minutes, if applicable. + SleepMax int // Wait time in minutes, if applicable. + Stack Stack + Locked bool // Locked to an OS thread. +} + +// Equal returns true only if both signatures are exactly equal. +func (s *Signature) Equal(r *Signature) bool { + if s.State != r.State || !s.CreatedBy.Equal(&r.CreatedBy) || s.Locked != r.Locked || s.SleepMin != r.SleepMin || s.SleepMax != r.SleepMax { + return false + } + return s.Stack.Equal(&r.Stack) +} + +// Similar returns true if the two Signature are equal or almost but not quite +// equal. +func (s *Signature) Similar(r *Signature, similar Similarity) bool { + if s.State != r.State || !s.CreatedBy.Similar(&r.CreatedBy, similar) { + return false + } + if similar == ExactFlags && s.Locked != r.Locked { + return false + } + return s.Stack.Similar(&r.Stack, similar) +} + +// Merge merges two similar Signature, zapping out differences. +func (s *Signature) Merge(r *Signature) *Signature { + min := s.SleepMin + if r.SleepMin < min { + min = r.SleepMin + } + max := s.SleepMax + if r.SleepMax > max { + max = r.SleepMax + } + return &Signature{ + State: s.State, // Drop right side. + CreatedBy: s.CreatedBy, // Drop right side. + SleepMin: min, + SleepMax: max, + Stack: *s.Stack.Merge(&r.Stack), + Locked: s.Locked || r.Locked, // TODO(maruel): This is weirdo. + } +} + +// Less compares two Signature, where the ones that are less are more +// important, so they come up front. A Signature with more private functions is +// 'less' so it is at the top. Inversely, a Signature with only public +// functions is 'more' so it is at the bottom. +func (s *Signature) Less(r *Signature) bool { + if s.Stack.Less(&r.Stack) { + return true + } + if r.Stack.Less(&s.Stack) { + return false + } + if s.Locked && !r.Locked { + return true + } + if r.Locked && !s.Locked { + return false + } + if s.State < r.State { + return true + } + if s.State > r.State { + return false + } + return false +} + +// Goroutine represents the state of one goroutine, including the stack trace. +type Goroutine struct { + Signature // It's stack trace, internal bits, state, which call site created it, etc. + ID int // Goroutine ID. + First bool // First is the goroutine first printed, normally the one that crashed. +} + +// Bucketize returns the number of similar goroutines. +func Bucketize(goroutines []Goroutine, similar Similarity) map[*Signature][]Goroutine { + out := map[*Signature][]Goroutine{} + // O(n²). Fix eventually. + for _, routine := range goroutines { + found := false + for key := range out { + // When a match is found, this effectively drops the other goroutine ID. + if key.Similar(&routine.Signature, similar) { + found = true + if !key.Equal(&routine.Signature) { + // Almost but not quite equal. There's different pointers passed + // around but the same values. Zap out the different values. + newKey := key.Merge(&routine.Signature) + out[newKey] = append(out[key], routine) + delete(out, key) + } else { + out[key] = append(out[key], routine) + } + break + } + } + if !found { + key := &Signature{} + *key = routine.Signature + out[key] = []Goroutine{routine} + } + } + return out +} + +// Bucket is a stack trace signature and the list of goroutines that fits this +// signature. +type Bucket struct { + Signature + Routines []Goroutine +} + +// First returns true if it contains the first goroutine, e.g. the ones that +// likely generated the panic() call, if any. +func (b *Bucket) First() bool { + for _, r := range b.Routines { + if r.First { + return true + } + } + return false +} + +// Less does reverse sort. +func (b *Bucket) Less(r *Bucket) bool { + if b.First() { + return true + } + if r.First() { + return false + } + return b.Signature.Less(&r.Signature) +} + +// Buckets is a list of Bucket sorted by repeation count. +type Buckets []Bucket + +func (b Buckets) Len() int { + return len(b) +} + +func (b Buckets) Less(i, j int) bool { + return b[i].Less(&b[j]) +} + +func (b Buckets) Swap(i, j int) { + b[j], b[i] = b[i], b[j] +} + +// SortBuckets creates a list of Bucket from each goroutine stack trace count. +func SortBuckets(buckets map[*Signature][]Goroutine) Buckets { + out := make(Buckets, 0, len(buckets)) + for signature, count := range buckets { + out = append(out, Bucket{*signature, count}) + } + sort.Sort(out) + return out +} + +// scanLines is similar to bufio.ScanLines except that it: +// - doesn't drop '\n' +// - doesn't strip '\r' +// - returns when the data is bufio.MaxScanTokenSize bytes +func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.IndexByte(data, '\n'); i >= 0 { + return i + 1, data[0 : i+1], nil + } + if atEOF { + return len(data), data, nil + } + if len(data) >= bufio.MaxScanTokenSize { + // Returns the line even if it is not at EOF nor has a '\n', otherwise the + // scanner will return bufio.ErrTooLong which is definitely not what we + // want. + return len(data), data, nil + } + return 0, nil, nil +} + +// ParseDump processes the output from runtime.Stack(). +// +// It supports piping from another command and assumes there is junk before the +// actual stack trace. The junk is streamed to out. +func ParseDump(r io.Reader, out io.Writer) ([]Goroutine, error) { + goroutines := make([]Goroutine, 0, 16) + var goroutine *Goroutine + scanner := bufio.NewScanner(r) + scanner.Split(scanLines) + // TODO(maruel): Use a formal state machine. Patterns follows: + // - reRoutineHeader + // Either: + // - reUnavail + // - reFunc + reFile in a loop + // - reElided + // Optionally ends with: + // - reCreated + reFile + // Between each goroutine stack dump: an empty line + created := false + // firstLine is the first line after the reRoutineHeader header line. + firstLine := false + for scanner.Scan() { + line := scanner.Text() + if line == "\n" || line == "\r\n" { + if goroutine != nil { + goroutine = nil + continue + } + } else if line[len(line)-1] == '\n' { + if goroutine == nil { + if match := reRoutineHeader.FindStringSubmatch(line); match != nil { + if id, err := strconv.Atoi(match[1]); err == nil { + // See runtime/traceback.go. + // ", \d+ minutes, locked to thread" + items := strings.Split(match[2], ", ") + sleep := 0 + locked := false + for i := 1; i < len(items); i++ { + if items[i] == lockedToThread { + locked = true + continue + } + // Look for duration, if any. + if match2 := reMinutes.FindStringSubmatch(items[i]); match2 != nil { + sleep, _ = strconv.Atoi(match2[1]) + } + } + goroutines = append(goroutines, Goroutine{ + Signature: Signature{ + State: items[0], + SleepMin: sleep, + SleepMax: sleep, + Locked: locked, + }, + ID: id, + First: len(goroutines) == 0, + }) + goroutine = &goroutines[len(goroutines)-1] + firstLine = true + continue + } + } + } else { + if firstLine { + firstLine = false + if match := reUnavail.FindStringSubmatch(line); match != nil { + // Generate a fake stack entry. + goroutine.Stack.Calls = []Call{{SourcePath: ""}} + continue + } + } + + if match := reFile.FindStringSubmatch(line); match != nil { + // Triggers after a reFunc or a reCreated. + num, err := strconv.Atoi(match[2]) + if err != nil { + return goroutines, fmt.Errorf("failed to parse int on line: \"%s\"", line) + } + if created { + created = false + goroutine.CreatedBy.SourcePath = match[1] + goroutine.CreatedBy.Line = num + } else { + i := len(goroutine.Stack.Calls) - 1 + if i < 0 { + return goroutines, errors.New("unexpected order") + } + goroutine.Stack.Calls[i].SourcePath = match[1] + goroutine.Stack.Calls[i].Line = num + } + continue + } + + if match := reCreated.FindStringSubmatch(line); match != nil { + created = true + goroutine.CreatedBy.Func.Raw = match[1] + continue + } + + if match := reFunc.FindStringSubmatch(line); match != nil { + args := Args{} + for _, a := range strings.Split(match[2], ", ") { + if a == "..." { + args.Elided = true + continue + } + if a == "" { + // Remaining values were dropped. + break + } + v, err := strconv.ParseUint(a, 0, 64) + if err != nil { + return goroutines, fmt.Errorf("failed to parse int on line: \"%s\"", line) + } + args.Values = append(args.Values, Arg{Value: v}) + } + goroutine.Stack.Calls = append(goroutine.Stack.Calls, Call{Func: Function{match[1]}, Args: args}) + continue + } + + if match := reElided.FindStringSubmatch(line); match != nil { + goroutine.Stack.Elided = true + continue + } + } + } + _, _ = io.WriteString(out, line) + goroutine = nil + } + nameArguments(goroutines) + return goroutines, scanner.Err() +} + +// Private stuff. + +func nameArguments(goroutines []Goroutine) { + // Set a name for any pointer occuring more than once. + type object struct { + args []*Arg + inPrimary bool + id int + } + objects := map[uint64]object{} + // Enumerate all the arguments. + for i := range goroutines { + for j := range goroutines[i].Stack.Calls { + for k := range goroutines[i].Stack.Calls[j].Args.Values { + arg := goroutines[i].Stack.Calls[j].Args.Values[k] + if arg.IsPtr() { + objects[arg.Value] = object{ + args: append(objects[arg.Value].args, &goroutines[i].Stack.Calls[j].Args.Values[k]), + inPrimary: objects[arg.Value].inPrimary || i == 0, + } + } + } + } + // CreatedBy.Args is never set. + } + order := uint64Slice{} + for k, obj := range objects { + if len(obj.args) > 1 && obj.inPrimary { + order = append(order, k) + } + } + sort.Sort(order) + nextID := 1 + for _, k := range order { + for _, arg := range objects[k].args { + arg.Name = fmt.Sprintf("#%d", nextID) + } + nextID++ + } + + // Now do the rest. This is done so the output is deterministic. + order = uint64Slice{} + for k := range objects { + order = append(order, k) + } + sort.Sort(order) + for _, k := range order { + // Process the remaining pointers, they were not referenced by primary + // thread so will have higher IDs. + if objects[k].inPrimary { + continue + } + for _, arg := range objects[k].args { + arg.Name = fmt.Sprintf("#%d", nextID) + } + nextID++ + } +} + +type uint64Slice []uint64 + +func (a uint64Slice) Len() int { return len(a) } +func (a uint64Slice) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a uint64Slice) Less(i, j int) bool { return a[i] < a[j] } diff --git a/vendor/github.com/maruel/panicparse/stack/stack_test.go b/vendor/github.com/maruel/panicparse/stack/stack_test.go new file mode 100644 index 0000000..883025b --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/stack_test.go @@ -0,0 +1,1018 @@ +// Copyright 2015 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package stack + +import ( + "bufio" + "bytes" + "errors" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/maruel/ut" +) + +var goroot = goroots[0] + +const crash = `panic: oh no! + +goroutine 1 [running]: +panic(0x0, 0x0) + /home/user/src/golang/src/runtime/panic.go:464 +0x3e6 +main.crash2(0x7fe50b49d028, 0xc82000a1e0) + /home/user/src/foo.go:45 +0x23 +main.main() + /home/user/src/foo.go:50 +0xa6 +` + +func Example() { + in := bytes.NewBufferString(crash) + goroutines, err := ParseDump(in, os.Stdout) + if err != nil { + return + } + + // Optional: Check for GOTRACEBACK being set, in particular if there is only + // one goroutine returned. + + // Use a color palette based on ANSI code. + p := &Palette{} + buckets := SortBuckets(Bucketize(goroutines, AnyValue)) + srcLen, pkgLen := CalcLengths(buckets, false) + for _, bucket := range buckets { + io.WriteString(os.Stdout, p.BucketHeader(&bucket, false, len(buckets) > 1)) + io.WriteString(os.Stdout, p.StackLines(&bucket.Signature, srcLen, pkgLen, false)) + } + // Output: + // panic: oh no! + // + // 1: running + // panic.go:464 panic(0, 0) + // main foo.go:45 crash2(0x7fe50b49d028, 0xc82000a1e0) + // main foo.go:50 main() +} + +func TestParseDump1(t *testing.T) { + // One call from main, one from stdlib, one from third party. + // Create a long first line that will be ignored. It is to guard against + // https://github.com/maruel/panicparse/issues/17. + long := strings.Repeat("a", bufio.MaxScanTokenSize+1) + data := []string{ + long, + "panic: reflect.Set: value of type", + "", + "goroutine 1 [running]:", + "github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek()", + " ??:0 +0x6d", + "gopkg.in/yaml%2ev2.handleErr(0xc208033b20)", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "reflect.Value.assignTo(0x570860, 0xc20803f3e0, 0x15)", + " " + goroot + "/src/reflect/value.go:2125 +0x368", + "main.main()", + " /gopath/src/github.com/foo/bar/baz.go:428 +0x27", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + ut.AssertEqual(t, long+"\npanic: reflect.Set: value of type\n\n", extra.String()) + expected := []Goroutine{ + { + Signature: Signature{ + State: "running", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "??", + Func: Function{"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek"}, + }, + { + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b20}}}, + }, + { + SourcePath: goroot + "/src/reflect/value.go", + Line: 2125, + Func: Function{"reflect.Value.assignTo"}, + Args: Args{Values: []Arg{{Value: 0x570860}, {Value: 0xc20803f3e0}, {Value: 0x15}}}, + }, + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 428, + Func: Function{"main.main"}, + }, + }, + }, + }, + ID: 1, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) +} + +func TestParseDumpLongWait(t *testing.T) { + // One call from main, one from stdlib, one from third party. + data := []string{ + "panic: bleh", + "", + "goroutine 1 [chan send, 100 minutes]:", + "gopkg.in/yaml%2ev2.handleErr(0xc208033b20)", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "", + "goroutine 2 [chan send, locked to thread]:", + "gopkg.in/yaml%2ev2.handleErr(0xc208033b21)", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "", + "goroutine 3 [chan send, 101 minutes, locked to thread]:", + "gopkg.in/yaml%2ev2.handleErr(0xc208033b22)", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + ut.AssertEqual(t, "panic: bleh\n\n", extra.String()) + expected := []Goroutine{ + { + Signature: Signature{ + State: "chan send", + SleepMin: 100, + SleepMax: 100, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b20}}}, + }, + }, + }, + }, + ID: 1, + First: true, + }, + { + Signature: Signature{ + State: "chan send", + Locked: true, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b21, Name: "#1"}}}, + }, + }, + }, + }, + ID: 2, + }, + { + Signature: Signature{ + State: "chan send", + SleepMin: 101, + SleepMax: 101, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b22, Name: "#2"}}}, + }, + }, + }, + Locked: true, + }, + ID: 3, + }, + } + ut.AssertEqual(t, expected, goroutines) +} + +func TestParseDumpAsm(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 16 [garbage collection]:", + "runtime.switchtoM()", + "\t" + goroot + "/src/runtime/asm_amd64.s:198 fp=0xc20cfb80d8 sp=0xc20cfb80d0", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "garbage collection", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: goroot + "/src/runtime/asm_amd64.s", + Line: 198, + Func: Function{Raw: "runtime.switchtoM"}, + }, + }, + }, + }, + ID: 16, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) + ut.AssertEqual(t, "panic: reflect.Set: value of type\n\n", extra.String()) +} + +func TestParseDumpLineErr(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 1 [running]:", + "github.com/foo/bar.recurseType()", + "\t/gopath/src/github.com/foo/bar/baz.go:12345678901234567890", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, errors.New("failed to parse int on line: \"\t/gopath/src/github.com/foo/bar/baz.go:12345678901234567890\n\""), err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "running", + Stack: Stack{Calls: []Call{{Func: Function{Raw: "github.com/foo/bar.recurseType"}}}}, + }, + ID: 1, + First: true, + }, + } + + ut.AssertEqual(t, expected, goroutines) +} + +func TestParseDumpValueErr(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 1 [running]:", + "github.com/foo/bar.recurseType(123456789012345678901)", + "\t/gopath/src/github.com/foo/bar/baz.go:9", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, errors.New("failed to parse int on line: \"github.com/foo/bar.recurseType(123456789012345678901)\n\""), err) + expected := []Goroutine{ + { + Signature: Signature{State: "running"}, + ID: 1, + First: true, + }, + } + + ut.AssertEqual(t, expected, goroutines) +} + +func TestParseDumpOrderErr(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 16 [garbage collection]:", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "runtime.switchtoM()", + "\t" + goroot + "/src/runtime/asm_amd64.s:198 fp=0xc20cfb80d8 sp=0xc20cfb80d0", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, errors.New("unexpected order"), err) + expected := []Goroutine{ + { + Signature: Signature{State: "garbage collection"}, + ID: 16, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) + ut.AssertEqual(t, "panic: reflect.Set: value of type\n\n", extra.String()) +} + +func TestParseDumpElided(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 16 [garbage collection]:", + "github.com/foo/bar.recurseType(0x7f4fa9a3ec70, 0xc208062580, 0x7f4fa9a3e818, 0x50a820, 0xc20803a8a0)", + "\t/gopath/src/github.com/foo/bar/baz.go:53 +0x845 fp=0xc20cfc66d8 sp=0xc20cfc6470", + "...additional frames elided...", + "created by testing.RunTests", + "\t" + goroot + "/src/testing/testing.go:555 +0xa8b", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "garbage collection", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 53, + Func: Function{Raw: "github.com/foo/bar.recurseType"}, + Args: Args{ + Values: []Arg{ + {Value: 0x7f4fa9a3ec70}, + {Value: 0xc208062580}, + {Value: 0x7f4fa9a3e818}, + {Value: 0x50a820}, + {Value: 0xc20803a8a0}, + }, + }, + }, + }, + Elided: true, + }, + CreatedBy: Call{ + SourcePath: goroot + "/src/testing/testing.go", + Line: 555, + Func: Function{Raw: "testing.RunTests"}, + }, + }, + ID: 16, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) + ut.AssertEqual(t, "panic: reflect.Set: value of type\n\n", extra.String()) +} + +func TestParseDumpSysCall(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 5 [syscall]:", + "runtime.notetsleepg(0x918100, 0xffffffffffffffff, 0x1)", + "\t" + goroot + "/src/runtime/lock_futex.go:201 +0x52 fp=0xc208018f68 sp=0xc208018f40", + "runtime.signal_recv(0x0)", + "\t" + goroot + "/src/runtime/sigqueue.go:109 +0x135 fp=0xc208018fa0 sp=0xc208018f68", + "os/signal.loop()", + "\t" + goroot + "/src/os/signal/signal_unix.go:21 +0x1f fp=0xc208018fe0 sp=0xc208018fa0", + "runtime.goexit()", + "\t" + goroot + "/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc208018fe8 sp=0xc208018fe0", + "created by os/signal.init·1", + "\t" + goroot + "/src/os/signal/signal_unix.go:27 +0x35", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "syscall", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: goroot + "/src/runtime/lock_futex.go", + Line: 201, + Func: Function{Raw: "runtime.notetsleepg"}, + Args: Args{ + Values: []Arg{ + {Value: 0x918100}, + {Value: 0xffffffffffffffff}, + {Value: 0x1}, + }, + }, + }, + { + SourcePath: goroot + "/src/runtime/sigqueue.go", + Line: 109, + Func: Function{Raw: "runtime.signal_recv"}, + Args: Args{ + Values: []Arg{{}}, + }, + }, + { + SourcePath: goroot + "/src/os/signal/signal_unix.go", + Line: 21, + Func: Function{Raw: "os/signal.loop"}, + }, + { + SourcePath: goroot + "/src/runtime/asm_amd64.s", + Line: 2232, + Func: Function{Raw: "runtime.goexit"}, + }, + }, + }, + CreatedBy: Call{ + SourcePath: goroot + "/src/os/signal/signal_unix.go", + Line: 27, + Func: Function{Raw: "os/signal.init·1"}, + }, + }, + ID: 5, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) + ut.AssertEqual(t, "panic: reflect.Set: value of type\n\n", extra.String()) +} + +func TestParseDumpUnavail(t *testing.T) { + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 24 [running]:", + "\tgoroutine running on other thread; stack unavailable", + "created by github.com/foo.New", + "\t/gopath/src/github.com/foo/bar.go:131 +0x381", + "", + } + extra := &bytes.Buffer{} + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), extra) + ut.AssertEqual(t, nil, err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "running", + Stack: Stack{ + Calls: []Call{{SourcePath: ""}}, + }, + CreatedBy: Call{ + SourcePath: "/gopath/src/github.com/foo/bar.go", + Line: 131, + Func: Function{Raw: "github.com/foo.New"}, + }, + }, + ID: 24, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) + ut.AssertEqual(t, "panic: reflect.Set: value of type\n\n", extra.String()) +} + +func TestParseDumpSameBucket(t *testing.T) { + // 2 goroutines with the same signature + data := []string{ + "panic: runtime error: index out of range", + "", + "goroutine 6 [chan receive]:", + "main.func·001()", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "created by main.mainImpl", + " /gopath/src/github.com/foo/bar/baz.go:74 +0xeb", + "", + "goroutine 7 [chan receive]:", + "main.func·001()", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "created by main.mainImpl", + " /gopath/src/github.com/foo/bar/baz.go:74 +0xeb", + "", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{ + State: "chan receive", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + }, + }, + }, + CreatedBy: Call{ + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 74, + Func: Function{"main.mainImpl"}, + }, + }, + ID: 6, + First: true, + }, + { + Signature: Signature{ + State: "chan receive", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + }, + }, + }, + CreatedBy: Call{ + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 74, + Func: Function{"main.mainImpl"}, + }, + }, + ID: 7, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) + expectedBuckets := Buckets{{expectedGR[0].Signature, []Goroutine{expectedGR[0], expectedGR[1]}}} + ut.AssertEqual(t, expectedBuckets, SortBuckets(Bucketize(goroutines, ExactLines))) +} + +func TestBucketizeNotAggressive(t *testing.T) { + // 2 goroutines with the same signature + data := []string{ + "panic: runtime error: index out of range", + "", + "goroutine 6 [chan receive]:", + "main.func·001(0x11000000, 2)", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "", + "goroutine 7 [chan receive]:", + "main.func·001(0x21000000, 2)", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{ + State: "chan receive", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x11000000, ""}, {Value: 2}}}, + }, + }, + }, + }, + ID: 6, + First: true, + }, + { + Signature: Signature{ + State: "chan receive", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x21000000, "#1"}, {Value: 2}}}, + }, + }, + }, + }, + ID: 7, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) + expectedBuckets := Buckets{ + {expectedGR[0].Signature, []Goroutine{expectedGR[0]}}, + {expectedGR[1].Signature, []Goroutine{expectedGR[1]}}, + } + ut.AssertEqual(t, expectedBuckets, SortBuckets(Bucketize(goroutines, ExactLines))) +} + +func TestBucketizeAggressive(t *testing.T) { + // 2 goroutines with the same signature + data := []string{ + "panic: runtime error: index out of range", + "", + "goroutine 6 [chan receive, 10 minutes]:", + "main.func·001(0x11000000, 2)", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "", + "goroutine 7 [chan receive, 50 minutes]:", + "main.func·001(0x21000000, 2)", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "", + "goroutine 8 [chan receive, 100 minutes]:", + "main.func·001(0x21000000, 2)", + " /gopath/src/github.com/foo/bar/baz.go:72 +0x49", + "", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{ + State: "chan receive", + SleepMin: 10, + SleepMax: 10, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x11000000, ""}, {Value: 2}}}, + }, + }, + }, + }, + ID: 6, + First: true, + }, + { + Signature: Signature{ + State: "chan receive", + SleepMin: 50, + SleepMax: 50, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x21000000, "#1"}, {Value: 2}}}, + }, + }, + }, + }, + ID: 7, + }, + { + Signature: Signature{ + State: "chan receive", + SleepMin: 100, + SleepMax: 100, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x21000000, "#1"}, {Value: 2}}}, + }, + }, + }, + }, + ID: 8, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) + signature := Signature{ + State: "chan receive", + SleepMin: 10, + SleepMax: 100, + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 72, + Func: Function{"main.func·001"}, + Args: Args{Values: []Arg{{0x11000000, "*"}, {Value: 2}}}, + }, + }, + }, + } + expectedBuckets := Buckets{{signature, []Goroutine{expectedGR[0], expectedGR[1], expectedGR[2]}}} + ut.AssertEqual(t, expectedBuckets, SortBuckets(Bucketize(goroutines, AnyPointer))) +} + +func TestParseDumpNoOffset(t *testing.T) { + data := []string{ + "panic: runtime error: index out of range", + "", + "goroutine 37 [runnable]:", + "github.com/foo.func·002()", + " /gopath/src/github.com/foo/bar.go:110", + "created by github.com/foo.New", + " /gopath/src/github.com/foo/bar.go:113 +0x43b", + "", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{ + State: "runnable", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "/gopath/src/github.com/foo/bar.go", + Line: 110, + Func: Function{"github.com/foo.func·002"}, + }, + }, + }, + CreatedBy: Call{ + SourcePath: "/gopath/src/github.com/foo/bar.go", + Line: 113, + Func: Function{"github.com/foo.New"}, + }, + }, + ID: 37, + First: true, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) +} + +func TestParseDumpJunk(t *testing.T) { + // For coverage of scanLines. + data := []string{ + "panic: reflect.Set: value of type", + "", + "goroutine 1 [running]:", + "junk", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{State: "running"}, + ID: 1, + First: true, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) +} + +func TestParseCCode(t *testing.T) { + data := []string{ + "SIGQUIT: quit", + "PC=0x43f349", + "", + "goroutine 0 [idle]:", + "runtime.epollwait(0x4, 0x7fff671c7118, 0xffffffff00000080, 0x0, 0xffffffff0028c1be, 0x0, 0x0, 0x0, 0x0, 0x0, ...)", + " " + goroot + "/src/runtime/sys_linux_amd64.s:400 +0x19", + "runtime.netpoll(0x901b01, 0x0)", + " " + goroot + "/src/runtime/netpoll_epoll.go:68 +0xa3", + "findrunnable(0xc208012000)", + " " + goroot + "/src/runtime/proc.c:1472 +0x485", + "schedule()", + " " + goroot + "/src/runtime/proc.c:1575 +0x151", + "runtime.park_m(0xc2080017a0)", + " " + goroot + "/src/runtime/proc.c:1654 +0x113", + "runtime.mcall(0x432684)", + " " + goroot + "/src/runtime/asm_amd64.s:186 +0x5a", + "", + } + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\n")), &bytes.Buffer{}) + ut.AssertEqual(t, nil, err) + expectedGR := []Goroutine{ + { + Signature: Signature{ + State: "idle", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: goroot + "/src/runtime/sys_linux_amd64.s", + Line: 400, + Func: Function{"runtime.epollwait"}, + Args: Args{ + Values: []Arg{ + {Value: 0x4}, + {Value: 0x7fff671c7118}, + {Value: 0xffffffff00000080}, + {}, + {Value: 0xffffffff0028c1be}, + {}, + {}, + {}, + {}, + {}, + }, + Elided: true, + }, + }, + { + SourcePath: goroot + "/src/runtime/netpoll_epoll.go", + Line: 68, + Func: Function{"runtime.netpoll"}, + Args: Args{Values: []Arg{{Value: 0x901b01}, {}}}, + }, + { + SourcePath: goroot + "/src/runtime/proc.c", + Line: 1472, + Func: Function{"findrunnable"}, + Args: Args{Values: []Arg{{Value: 0xc208012000}}}, + }, + { + SourcePath: goroot + "/src/runtime/proc.c", + Line: 1575, + Func: Function{"schedule"}, + }, + { + SourcePath: goroot + "/src/runtime/proc.c", + Line: 1654, + Func: Function{"runtime.park_m"}, + Args: Args{Values: []Arg{{Value: 0xc2080017a0}}}, + }, + { + SourcePath: goroot + "/src/runtime/asm_amd64.s", + Line: 186, + Func: Function{"runtime.mcall"}, + Args: Args{Values: []Arg{{Value: 0x432684}}}, + }, + }, + }, + }, + ID: 0, + First: true, + }, + } + ut.AssertEqual(t, expectedGR, goroutines) +} + +func TestParseWithCarriageReturn(t *testing.T) { + data := []string{ + "goroutine 1 [running]:", + "github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek()", + " ??:0 +0x6d", + "gopkg.in/yaml%2ev2.handleErr(0xc208033b20)", + " /gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6", + "reflect.Value.assignTo(0x570860, 0xc20803f3e0, 0x15)", + " " + goroot + "/src/reflect/value.go:2125 +0x368", + "main.main()", + " /gopath/src/github.com/foo/bar/baz.go:428 +0x27", + "", + } + + goroutines, err := ParseDump(bytes.NewBufferString(strings.Join(data, "\r\n")), ioutil.Discard) + ut.AssertEqual(t, nil, err) + expected := []Goroutine{ + { + Signature: Signature{ + State: "running", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: "??", + Func: Function{"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek"}, + }, + { + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b20}}}, + }, + { + SourcePath: goroot + "/src/reflect/value.go", + Line: 2125, + Func: Function{"reflect.Value.assignTo"}, + Args: Args{Values: []Arg{{Value: 0x570860}, {Value: 0xc20803f3e0}, {Value: 0x15}}}, + }, + { + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 428, + Func: Function{"main.main"}, + }, + }, + }, + }, + ID: 1, + First: true, + }, + } + ut.AssertEqual(t, expected, goroutines) +} + +func TestCallPkg1(t *testing.T) { + c := Call{ + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.handleErr"}, + Args: Args{Values: []Arg{{Value: 0xc208033b20}}}, + } + ut.AssertEqual(t, "yaml.go", c.SourceName()) + ut.AssertEqual(t, filepath.Join("yaml.v2", "yaml.go"), c.PkgSource()) + ut.AssertEqual(t, "gopkg.in/yaml.v2.handleErr", c.Func.String()) + ut.AssertEqual(t, "handleErr", c.Func.Name()) + // This is due to directory name not matching the package name. + ut.AssertEqual(t, "yaml.v2", c.Func.PkgName()) + ut.AssertEqual(t, false, c.Func.IsExported()) + ut.AssertEqual(t, false, c.IsStdlib()) + ut.AssertEqual(t, false, c.IsPkgMain()) +} + +func TestCallPkg2(t *testing.T) { + c := Call{ + SourcePath: "/gopath/src/gopkg.in/yaml.v2/yaml.go", + Line: 153, + Func: Function{"gopkg.in/yaml%2ev2.(*decoder).unmarshal"}, + Args: Args{Values: []Arg{{Value: 0xc208033b20}}}, + } + ut.AssertEqual(t, "yaml.go", c.SourceName()) + ut.AssertEqual(t, filepath.Join("yaml.v2", "yaml.go"), c.PkgSource()) + // TODO(maruel): Using '/' for this function is inconsistent on Windows + // w.r.t. other functions. + ut.AssertEqual(t, "gopkg.in/yaml.v2.(*decoder).unmarshal", c.Func.String()) + ut.AssertEqual(t, "(*decoder).unmarshal", c.Func.Name()) + // This is due to directory name not matching the package name. + ut.AssertEqual(t, "yaml.v2", c.Func.PkgName()) + ut.AssertEqual(t, false, c.Func.IsExported()) + ut.AssertEqual(t, false, c.IsStdlib()) + ut.AssertEqual(t, false, c.IsPkgMain()) +} + +func TestCallStdlib(t *testing.T) { + c := Call{ + SourcePath: goroot + "/src/reflect/value.go", + Line: 2125, + Func: Function{"reflect.Value.assignTo"}, + Args: Args{Values: []Arg{{Value: 0x570860}, {Value: 0xc20803f3e0}, {Value: 0x15}}}, + } + ut.AssertEqual(t, "value.go", c.SourceName()) + ut.AssertEqual(t, "value.go:2125", c.SourceLine()) + ut.AssertEqual(t, filepath.Join("reflect", "value.go"), c.PkgSource()) + ut.AssertEqual(t, "reflect.Value.assignTo", c.Func.String()) + ut.AssertEqual(t, "Value.assignTo", c.Func.Name()) + ut.AssertEqual(t, "reflect", c.Func.PkgName()) + ut.AssertEqual(t, false, c.Func.IsExported()) + ut.AssertEqual(t, true, c.IsStdlib()) + ut.AssertEqual(t, false, c.IsPkgMain()) +} + +func TestCallMain(t *testing.T) { + c := Call{ + SourcePath: "/gopath/src/github.com/foo/bar/main.go", + Line: 428, + Func: Function{"main.main"}, + } + ut.AssertEqual(t, "main.go", c.SourceName()) + ut.AssertEqual(t, "main.go:428", c.SourceLine()) + ut.AssertEqual(t, filepath.Join("bar", "main.go"), c.PkgSource()) + ut.AssertEqual(t, "main.main", c.Func.String()) + ut.AssertEqual(t, "main", c.Func.Name()) + ut.AssertEqual(t, "main", c.Func.PkgName()) + ut.AssertEqual(t, true, c.Func.IsExported()) + ut.AssertEqual(t, false, c.IsStdlib()) + ut.AssertEqual(t, true, c.IsPkgMain()) +} + +func TestCallC(t *testing.T) { + c := Call{ + SourcePath: goroot + "/src/runtime/proc.c", + Line: 1472, + Func: Function{"findrunnable"}, + Args: Args{Values: []Arg{{Value: 0xc208012000}}}, + } + ut.AssertEqual(t, "proc.c", c.SourceName()) + ut.AssertEqual(t, "proc.c:1472", c.SourceLine()) + ut.AssertEqual(t, filepath.Join("runtime", "proc.c"), c.PkgSource()) + ut.AssertEqual(t, "findrunnable", c.Func.String()) + ut.AssertEqual(t, "findrunnable", c.Func.Name()) + ut.AssertEqual(t, "", c.Func.PkgName()) + ut.AssertEqual(t, false, c.Func.IsExported()) + ut.AssertEqual(t, true, c.IsStdlib()) + ut.AssertEqual(t, false, c.IsPkgMain()) +} + +func TestArgs(t *testing.T) { + a := Args{ + Values: []Arg{ + {Value: 0x4}, + {Value: 0x7fff671c7118}, + {Value: 0xffffffff00000080}, + {}, + {Value: 0xffffffff0028c1be}, + {}, + {}, + {}, + {}, + {}, + }, + Elided: true, + } + ut.AssertEqual(t, "0x4, 0x7fff671c7118, 0xffffffff00000080, 0, 0xffffffff0028c1be, 0, 0, 0, 0, 0, ...", a.String()) +} + +func TestFunctionAnonymous(t *testing.T) { + f := Function{"main.func·001"} + ut.AssertEqual(t, "main.func·001", f.String()) + ut.AssertEqual(t, "main.func·001", f.PkgDotName()) + ut.AssertEqual(t, "func·001", f.Name()) + ut.AssertEqual(t, "main", f.PkgName()) + ut.AssertEqual(t, false, f.IsExported()) +} + +func TestFunctionGC(t *testing.T) { + f := Function{"gc"} + ut.AssertEqual(t, "gc", f.String()) + ut.AssertEqual(t, "gc", f.PkgDotName()) + ut.AssertEqual(t, "gc", f.Name()) + ut.AssertEqual(t, "", f.PkgName()) + ut.AssertEqual(t, false, f.IsExported()) +} diff --git a/vendor/github.com/maruel/panicparse/stack/ui.go b/vendor/github.com/maruel/panicparse/stack/ui.go new file mode 100644 index 0000000..b125fc9 --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/ui.go @@ -0,0 +1,139 @@ +// Copyright 2016 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package stack + +import ( + "fmt" + "strings" +) + +// Palette defines the color used. +// +// An empty object Palette{} can be used to disable coloring. +type Palette struct { + EOLReset string + + // Routine header. + RoutineFirst string // The first routine printed. + Routine string // Following routines. + CreatedBy string + + // Call line. + Package string + SourceFile string + FunctionStdLib string + FunctionStdLibExported string + FunctionMain string + FunctionOther string + FunctionOtherExported string + Arguments string +} + +// CalcLengths returns the maximum length of the source lines and package names. +func CalcLengths(buckets Buckets, fullPath bool) (int, int) { + srcLen := 0 + pkgLen := 0 + for _, bucket := range buckets { + for _, line := range bucket.Signature.Stack.Calls { + l := 0 + if fullPath { + l = len(line.FullSourceLine()) + } else { + l = len(line.SourceLine()) + } + if l > srcLen { + srcLen = l + } + l = len(line.Func.PkgName()) + if l > pkgLen { + pkgLen = l + } + } + } + return srcLen, pkgLen +} + +// functionColor returns the color to be used for the function name based on +// the type of package the function is in. +func (p *Palette) functionColor(line *Call) string { + if line.IsStdlib() { + if line.Func.IsExported() { + return p.FunctionStdLibExported + } + return p.FunctionStdLib + } else if line.IsPkgMain() { + return p.FunctionMain + } else if line.Func.IsExported() { + return p.FunctionOtherExported + } + return p.FunctionOther +} + +// routineColor returns the color for the header of the goroutines bucket. +func (p *Palette) routineColor(bucket *Bucket, multipleBuckets bool) string { + if bucket.First() && multipleBuckets { + return p.RoutineFirst + } + return p.Routine +} + +// BucketHeader prints the header of a goroutine signature. +func (p *Palette) BucketHeader(bucket *Bucket, fullPath, multipleBuckets bool) string { + extra := "" + if bucket.SleepMax != 0 { + if bucket.SleepMin != bucket.SleepMax { + extra += fmt.Sprintf(" [%d~%d minutes]", bucket.SleepMin, bucket.SleepMax) + } else { + extra += fmt.Sprintf(" [%d minutes]", bucket.SleepMax) + } + } + if bucket.Locked { + extra += " [locked]" + } + created := bucket.CreatedBy.Func.PkgDotName() + if created != "" { + created += " @ " + if fullPath { + created += bucket.CreatedBy.FullSourceLine() + } else { + created += bucket.CreatedBy.SourceLine() + } + extra += p.CreatedBy + " [Created by " + created + "]" + } + return fmt.Sprintf( + "%s%d: %s%s%s\n", + p.routineColor(bucket, multipleBuckets), len(bucket.Routines), + bucket.State, extra, + p.EOLReset) +} + +// callLine prints one stack line. +func (p *Palette) callLine(line *Call, srcLen, pkgLen int, fullPath bool) string { + src := "" + if fullPath { + src = line.FullSourceLine() + } else { + src = line.SourceLine() + } + return fmt.Sprintf( + " %s%-*s %s%-*s %s%s%s(%s)%s", + p.Package, pkgLen, line.Func.PkgName(), + p.SourceFile, srcLen, src, + p.functionColor(line), line.Func.Name(), + p.Arguments, line.Args, + p.EOLReset) +} + +// StackLines prints one complete stack trace, without the header. +func (p *Palette) StackLines(signature *Signature, srcLen, pkgLen int, fullPath bool) string { + out := make([]string, len(signature.Stack.Calls)) + for i := range signature.Stack.Calls { + out[i] = p.callLine(&signature.Stack.Calls[i], srcLen, pkgLen, fullPath) + } + if signature.Stack.Elided { + out = append(out, " (...)") + } + return strings.Join(out, "\n") + "\n" +} diff --git a/vendor/github.com/maruel/panicparse/stack/ui_test.go b/vendor/github.com/maruel/panicparse/stack/ui_test.go new file mode 100644 index 0000000..d50c588 --- /dev/null +++ b/vendor/github.com/maruel/panicparse/stack/ui_test.go @@ -0,0 +1,149 @@ +// Copyright 2016 Marc-Antoine Ruel. All rights reserved. +// Use of this source code is governed under the Apache License, Version 2.0 +// that can be found in the LICENSE file. + +package stack + +import ( + "testing" + + "github.com/maruel/ut" +) + +var p = &Palette{ + EOLReset: "A", + RoutineFirst: "B", + Routine: "C", + CreatedBy: "D", + Package: "E", + SourceFile: "F", + FunctionStdLib: "G", + FunctionStdLibExported: "H", + FunctionMain: "I", + FunctionOther: "J", + FunctionOtherExported: "K", + Arguments: "L", +} + +func TestCalcLengths(t *testing.T) { + t.Parallel() + b := Buckets{ + { + Signature{Stack: Stack{Calls: []Call{{SourcePath: "/gopath/baz.go", Func: Function{"main.func·001"}}}}}, + nil, + }, + } + srcLen, pkgLen := CalcLengths(b, true) + ut.AssertEqual(t, 16, srcLen) + ut.AssertEqual(t, 4, pkgLen) + srcLen, pkgLen = CalcLengths(b, false) + ut.AssertEqual(t, 8, srcLen) + ut.AssertEqual(t, 4, pkgLen) +} + +func TestBucketHeader(t *testing.T) { + t.Parallel() + b := &Bucket{ + Signature{ + State: "chan receive", + CreatedBy: Call{ + SourcePath: "/gopath/src/github.com/foo/bar/baz.go", + Line: 74, + Func: Function{"main.mainImpl"}, + }, + SleepMax: 6, + SleepMin: 2, + }, + []Goroutine{ + { + First: true, + }, + {}, + }, + } + ut.AssertEqual(t, "B2: chan receive [2~6 minutes]D [Created by main.mainImpl @ /gopath/src/github.com/foo/bar/baz.go:74]A\n", p.BucketHeader(b, true, true)) + ut.AssertEqual(t, "C2: chan receive [2~6 minutes]D [Created by main.mainImpl @ /gopath/src/github.com/foo/bar/baz.go:74]A\n", p.BucketHeader(b, true, false)) + ut.AssertEqual(t, "B2: chan receive [2~6 minutes]D [Created by main.mainImpl @ baz.go:74]A\n", p.BucketHeader(b, false, true)) + ut.AssertEqual(t, "C2: chan receive [2~6 minutes]D [Created by main.mainImpl @ baz.go:74]A\n", p.BucketHeader(b, false, false)) + + b = &Bucket{ + Signature{ + State: "b0rked", + SleepMax: 6, + SleepMin: 6, + Locked: true, + }, + nil, + } + ut.AssertEqual(t, "C0: b0rked [6 minutes] [locked]A\n", p.BucketHeader(b, false, false)) +} + +func TestStackLines(t *testing.T) { + t.Parallel() + s := &Signature{ + State: "idle", + Stack: Stack{ + Calls: []Call{ + { + SourcePath: goroot + "/src/runtime/sys_linux_amd64.s", + Line: 400, + Func: Function{"runtime.Epollwait"}, + Args: Args{ + Values: []Arg{ + {Value: 0x4}, + {Value: 0x7fff671c7118}, + {Value: 0xffffffff00000080}, + {}, + {Value: 0xffffffff0028c1be}, + {}, + {}, + {}, + {}, + {}, + }, + Elided: true, + }, + }, + { + SourcePath: goroot + "/src/runtime/netpoll_epoll.go", + Line: 68, + Func: Function{"runtime.netpoll"}, + Args: Args{Values: []Arg{{Value: 0x901b01}, {}}}, + }, + { + SourcePath: "/src/main.go", + Line: 1472, + Func: Function{"main.Main"}, + Args: Args{Values: []Arg{{Value: 0xc208012000}}}, + }, + { + SourcePath: "/src/foo/bar.go", + Line: 1575, + Func: Function{"foo.OtherExported"}, + }, + { + SourcePath: "/src/foo/bar.go", + Line: 10, + Func: Function{"foo.otherPrivate"}, + }, + }, + Elided: true, + }, + } + expected := "" + + " Eruntime F" + goroot + "/src/runtime/sys_linux_amd64.s:400 HEpollwaitL(0x4, 0x7fff671c7118, 0xffffffff00000080, 0, 0xffffffff0028c1be, 0, 0, 0, 0, 0, ...)A\n" + + " Eruntime F" + goroot + "/src/runtime/netpoll_epoll.go:68 GnetpollL(0x901b01, 0)A\n" + + " Emain F/src/main.go:1472 IMainL(0xc208012000)A\n" + + " Efoo F/src/foo/bar.go:1575 KOtherExportedL()A\n" + + " Efoo F/src/foo/bar.go:10 JotherPrivateL()A\n" + + " (...)\n" + ut.AssertEqual(t, expected, p.StackLines(s, 10, 10, true)) + expected = "" + + " Eruntime Fsys_linux_amd64.s:400 HEpollwaitL(0x4, 0x7fff671c7118, 0xffffffff00000080, 0, 0xffffffff0028c1be, 0, 0, 0, 0, 0, ...)A\n" + + " Eruntime Fnetpoll_epoll.go:68 GnetpollL(0x901b01, 0)A\n" + + " Emain Fmain.go:1472 IMainL(0xc208012000)A\n" + + " Efoo Fbar.go:1575 KOtherExportedL()A\n" + + " Efoo Fbar.go:10 JotherPrivateL()A\n" + + " (...)\n" + ut.AssertEqual(t, expected, p.StackLines(s, 10, 10, false)) +} diff --git a/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go b/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go deleted file mode 100644 index 8cbcb90..0000000 --- a/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - - "github.com/mattn/go-colorable" -) - -func main() { - stdOut := bufio.NewWriter(colorable.NewColorableStdout()) - - fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") - fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") - stdOut.Flush() -} diff --git a/vendor/github.com/mattn/go-colorable/_example/logrus/main.go b/vendor/github.com/mattn/go-colorable/_example/logrus/main.go deleted file mode 100644 index c569164..0000000 --- a/vendor/github.com/mattn/go-colorable/_example/logrus/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "github.com/mattn/go-colorable" - "github.com/sirupsen/logrus" -) - -func main() { - logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) - logrus.SetOutput(colorable.NewColorableStdout()) - - logrus.Info("succeeded") - logrus.Warn("not correct") - logrus.Error("something error") - logrus.Fatal("panic") -} diff --git a/vendor/github.com/mattn/go-colorable/_example/title/main.go b/vendor/github.com/mattn/go-colorable/_example/title/main.go deleted file mode 100644 index e208870..0000000 --- a/vendor/github.com/mattn/go-colorable/_example/title/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - "os" - . "github.com/mattn/go-colorable" -) - -func main() { - out := NewColorableStdout() - fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") - var c [1]byte - os.Stdin.Read(c[:]) -} diff --git a/vendor/github.com/mattn/go-runewidth/.travis.yml b/vendor/github.com/mattn/go-runewidth/.travis.yml new file mode 100644 index 0000000..5c9c2a3 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/.travis.yml @@ -0,0 +1,8 @@ +language: go +go: + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 0000000..91b5cef --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd new file mode 100644 index 0000000..66663a9 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/README.mkd @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go new file mode 100644 index 0000000..2164497 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -0,0 +1,1223 @@ +package runewidth + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth = IsEastAsian() + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{EastAsianWidth} +) + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + // func (t table) IncludesRune(r rune) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) / 2 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, + {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, + {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, + {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, + {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, + {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, + {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, + {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, + {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, + {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, + {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, + {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, + {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, + {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, + {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, + {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, + {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, + {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, + {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, + {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, + {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, + {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, + {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, + {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, + {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, + {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, + {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, + {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, + {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, + {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, + {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, + {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, + {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, + {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, + {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, + {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, + {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, + {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, + {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, + {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, + {0xE0100, 0xE01EF}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, + {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, + {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, + {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, + {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, + {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, + {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} + +var emoji = table{ + {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, + {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, + {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, + {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, + {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, + {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, + {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, + {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, + {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, + {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, + {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, + {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, + {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, +} + +var notassigned = table{ + {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, + {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, + {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, + {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, + {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, + {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, + {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, + {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, + {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, + {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, + {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, + {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, + {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, + {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, + {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, + {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, + {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, + {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, + {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, + {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, + {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, + {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, + {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, + {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, + {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, + {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, + {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, + {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, + {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, + {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, + {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, + {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, + {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, + {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, + {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, + {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, + {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, + {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, + {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, + {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, + {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, + {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, + {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, + {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, + {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, + {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, + {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, + {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, + {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, + {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, + {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, + {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, + {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, + {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, + {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, + {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, + {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, + {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, + {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, + {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, + {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, + {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, + {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, + {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, + {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, + {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, + {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, + {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, + {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, + {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, + {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, + {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, + {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, + {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, + {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, + {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, + {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, + {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, + {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, + {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, + {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, + {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, + {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, + {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, + {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, + {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, + {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, + {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, + {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, + {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, + {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, + {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, + {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, + {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, + {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, + {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, + {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, + {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, + {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, + {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, + {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, + {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, + {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, + {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, + {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, + {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, + {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, + {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, + {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, + {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, + {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, + {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, + {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, + {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, + {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, + {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, + {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, + {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, + {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, + {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, + {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, + {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, + {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, + {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, + {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, + {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, + {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, + {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, + {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, + {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, + {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, + {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, + {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, + {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, + {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, + {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, + {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, + {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, + {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, + {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, + {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, + {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, + {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, + {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, + {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, + {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, + {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, + {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, + {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, + {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, + {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, + {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, + {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, + {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, + {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, + {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, + {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, + {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, + {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, + {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, + {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, + {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, + {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, + {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, + {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, + {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, + {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, + {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, + {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, + {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, + {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, + {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, + {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, + {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, + {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, + {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, + {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, + {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, + {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, + {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, + {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, + {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, + {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, + {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, + {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, + {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, + {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, + {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, + {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, + {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, + {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, + {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, + {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, + {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, + {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, + {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, + {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, + {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, + {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, + {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, + {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, + {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, + {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, + {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, + {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, + {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, + {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, + {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, + {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, + {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, + {0xFFFFE, 0xFFFFF}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, + {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, + {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, + {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, + {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, + {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, + {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, + {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, + {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, + {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, + {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, + {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, + {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, + {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, + {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, + {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, + {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, + {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, + {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, + {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, + {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, + {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, + {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, + {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, + {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, + {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, + {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, + {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, + {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, + {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, + {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, + {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, + {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, + {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, + {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, + {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, + {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, + {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, + {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, + {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, + {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, + {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, + {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, + {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, + {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, + {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, + {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, + {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, + {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, + {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, + {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, + {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, + {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, + {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, + {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, + {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, + {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, + {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, + {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, + {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, + {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, + {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, + {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, + {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, + {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, + {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, + {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, + {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, + {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, + {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, + {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, + {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, + {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, + {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, + {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, + {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, + {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, + {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, + {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, + {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, + {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, + {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, + {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, + {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, + {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, + {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, + {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, + {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, + {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, + {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, + {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, + {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, + {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, + {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, + {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, + {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, + {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, + {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, + {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, + {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, + {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, + {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, + {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, + {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, + {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, + {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, + {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, + {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, + {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, + {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, + {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, + {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, + {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, + {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, + {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, + {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, + {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, + {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, + {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, + {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, + {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, + {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, + {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, + {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, + {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, + {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, + {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, + {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, + {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, + {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, + {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, + {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, + {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, + {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, + {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, + {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, + {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, + {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, + {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, + {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, + {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, + {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, + {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, + {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, + {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, + {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, + {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, + {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, + {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, + {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, + {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, + {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, + {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, + {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, + {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, + {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, + {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, + {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, + {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, + {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, + {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, + {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, + {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, + {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, + {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, + {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, + {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, + {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, + {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, + {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, + {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, + {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, + {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, + {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, + {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, + {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, + {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, + {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, + {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, + {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, + {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, + {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, + {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, + {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, + {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, + {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, + {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, + {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, + {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, + {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, + {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, + {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, + {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, + {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, + {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, + {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, + {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, + {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, + {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, + {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, + {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, + {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, + {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, + {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, + {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, + {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, + {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, + {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, + {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, + {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, + {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, + {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, + {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, + {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, + {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, + {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, + {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, + {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, + {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, + {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, + {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, + {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, + {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, + {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, + {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, + {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, + {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, + {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, + {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, + {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, + {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, + {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, + {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, + {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, + {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, + {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, + {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, + {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, + {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, + {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, + {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, + {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, + {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, + {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, + {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, + {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, + {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, + {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, + {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, + {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, + {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, + {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, + {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, + {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, + {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, + {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, + {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, + {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, + {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, + {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, + {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, + {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, + {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, + {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, + {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, + {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, + {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, + {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, + {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, + {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, + {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, + {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, + {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, + {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, + {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, + {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, + {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, + {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, + {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, + {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, + {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, + {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, + {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, + {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, + {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, + {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, + {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, + {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, + {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, + {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, + {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, + {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, + {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, + {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, + {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, + {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, + {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, + {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, + {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, + {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, + {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, + {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, + {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, + {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, + {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, + {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, + {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, + {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, + {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, + {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, + {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, + {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, + {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, + {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, + {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, + {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, + {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, + {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, + {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, + {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, + {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, + {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, + {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, + {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, + {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, + {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, + {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, + {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, + {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, + {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, + {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, + {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, + {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, + {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, + {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, + {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, + {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, + {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, + {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, + {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, + {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, + {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, + {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, + {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, + {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, + {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, + {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, + {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, + {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, + {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, + {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, + {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, + {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, + {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, + {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, + {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, + {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, + {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, + {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, + {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, + {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, + {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, + {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, + {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, + {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, + {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, + {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, + {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, + {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, + {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, + {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, + {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, + {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, + {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, + {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, + {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, + {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, + {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, + {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, + {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, + {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, + {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, + {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, + {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, + {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, + {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, + {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, + {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, + {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, + {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, + {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, + {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, + {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, + {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, + {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, + {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, + {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, + {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, + {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, + {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, + {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, + {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, + {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, + {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, + {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, + {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, + {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, + {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, + {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, + {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, + {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, + {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, + {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, + {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, + {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, + {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, + {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, + {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, + {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, + {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, + {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, + {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, + {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, + {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, + {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, + {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, + {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, + {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, + {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, + {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, + {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, + {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, + {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, + {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, + {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, + {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, + {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, + {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, + {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, + {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, + {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, + {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, + {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, + {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, + {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, + {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, + {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, + {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, + {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, + {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, + {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, + {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, + {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, + {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, + {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, + {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, + {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, + {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, + {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, + {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, + {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, + {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, + {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, + {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, + {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, + {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, + {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, + {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, + {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, + {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, + {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, + {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, + {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, + {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, + {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, + {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, + {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, + {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, + {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, + {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, + {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, + {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, + {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, + {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, + {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, + {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, + {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, + {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, + {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, + {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, + {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, + {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, + {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, + {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, + {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, + {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, + {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, + {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, + {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, + {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, + {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, + {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, + {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, + {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, + {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, + {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, + {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, + {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, + {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, + {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, + {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, + {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, + {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, + {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, + {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, + {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, + {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, + {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, + {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, + {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, + {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, + {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, + {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, + {0xE0020, 0xE007F}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{EastAsianWidth} +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || + inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || + inTables(r, doublewidth, emoji): + return 2 + default: + return 1 + } +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go new file mode 100644 index 0000000..0ce32c5 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go @@ -0,0 +1,8 @@ +// +build js + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go new file mode 100644 index 0000000..c579e9a --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -0,0 +1,77 @@ +// +build !windows,!js + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_test.go b/vendor/github.com/mattn/go-runewidth/runewidth_test.go new file mode 100644 index 0000000..b0378a1 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_test.go @@ -0,0 +1,275 @@ +package runewidth + +import ( + "sort" + "testing" +) + +var _ sort.Interface = (*table)(nil) + +func (t table) Len() int { + return len(t) +} + +func (t table) Less(i, j int) bool { + return t[i].first < t[j].first +} + +func (t *table) Swap(i, j int) { + (*t)[i], (*t)[j] = (*t)[j], (*t)[i] +} + +var tables = []table{ + private, + nonprint, + combining, + doublewidth, + ambiguous, + emoji, + notassigned, + neutral, +} + +func TestSorted(t *testing.T) { + for _, tbl := range tables { + if !sort.IsSorted(&tbl) { + t.Errorf("not sorted") + } + } +} + +var runewidthtests = []struct { + in rune + out int + eaout int +}{ + {'世', 2, 2}, + {'界', 2, 2}, + {'セ', 1, 1}, + {'カ', 1, 1}, + {'イ', 1, 1}, + {'☆', 1, 2}, // double width in ambiguous + {'\x00', 0, 0}, + {'\x01', 0, 0}, + {'\u0300', 0, 0}, +} + +func TestRuneWidth(t *testing.T) { + c := NewCondition() + for _, tt := range runewidthtests { + if out := c.RuneWidth(tt.in); out != tt.out { + t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.out) + } + } + c.EastAsianWidth = true + for _, tt := range runewidthtests { + if out := c.RuneWidth(tt.in); out != tt.eaout { + t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.eaout) + } + } +} + +var isambiguouswidthtests = []struct { + in rune + out bool +}{ + {'世', false}, + {'■', true}, + {'界', false}, + {'○', true}, + {'㈱', false}, + {'①', true}, + {'②', true}, + {'③', true}, + {'④', true}, + {'⑤', true}, + {'⑥', true}, + {'⑦', true}, + {'⑧', true}, + {'⑨', true}, + {'⑩', true}, + {'⑪', true}, + {'⑫', true}, + {'⑬', true}, + {'⑭', true}, + {'⑮', true}, + {'⑯', true}, + {'⑰', true}, + {'⑱', true}, + {'⑲', true}, + {'⑳', true}, + {'☆', true}, +} + +func TestIsAmbiguousWidth(t *testing.T) { + for _, tt := range isambiguouswidthtests { + if out := IsAmbiguousWidth(tt.in); out != tt.out { + t.Errorf("IsAmbiguousWidth(%q) = %v, want %v", tt.in, out, tt.out) + } + } +} + +var stringwidthtests = []struct { + in string + out int + eaout int +}{ + {"■㈱の世界①", 10, 12}, + {"スター☆", 7, 8}, + {"つのだ☆HIRO", 11, 12}, +} + +func TestStringWidth(t *testing.T) { + c := NewCondition() + for _, tt := range stringwidthtests { + if out := c.StringWidth(tt.in); out != tt.out { + t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.out) + } + } + c.EastAsianWidth = true + for _, tt := range stringwidthtests { + if out := c.StringWidth(tt.in); out != tt.eaout { + t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.eaout) + } + } +} + +func TestStringWidthInvalid(t *testing.T) { + s := "こんにちわ\x00世界" + if out := StringWidth(s); out != 14 { + t.Errorf("StringWidth(%q) = %q, want %q", s, out, 14) + } +} + +func TestTruncateSmaller(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := Truncate(s, 10, "..."); out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } +} + +func TestTruncate(t *testing.T) { + s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 79 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 79, width) + } +} + +func TestTruncateFit(t *testing.T) { + s := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." + + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 80 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) + } +} + +func TestTruncateJustFit(t *testing.T) { + s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 80 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) + } +} + +func TestWrap(t *testing.T) { + s := `東京特許許可局局長はよく柿喰う客だ/東京特許許可局局長はよく柿喰う客だ +123456789012345678901234567890 + +END` + expected := `東京特許許可局局長はよく柿喰う +客だ/東京特許許可局局長はよく +柿喰う客だ +123456789012345678901234567890 + +END` + + if out := Wrap(s, 30); out != expected { + t.Errorf("Wrap(%q) = %q, want %q", s, out, expected) + } +} + +func TestTruncateNoNeeded(t *testing.T) { + s := "あいうえおあい" + expected := "あいうえおあい" + + if out := Truncate(s, 80, "..."); out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } +} + +var isneutralwidthtests = []struct { + in rune + out bool +}{ + {'→', false}, + {'┊', false}, + {'┈', false}, + {'~', false}, + {'└', false}, + {'⣀', true}, + {'⣀', true}, +} + +func TestIsNeutralWidth(t *testing.T) { + for _, tt := range isneutralwidthtests { + if out := IsNeutralWidth(tt.in); out != tt.out { + t.Errorf("IsNeutralWidth(%q) = %v, want %v", tt.in, out, tt.out) + } + } +} + +func TestFillLeft(t *testing.T) { + s := "あxいうえお" + expected := " あxいうえお" + + if out := FillLeft(s, 15); out != expected { + t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillLeftFit(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := FillLeft(s, 10); out != expected { + t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillRight(t *testing.T) { + s := "あxいうえお" + expected := "あxいうえお " + + if out := FillRight(s, 15); out != expected { + t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillRightFit(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := FillRight(s, 10); out != expected { + t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) + } +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go new file mode 100644 index 0000000..0258876 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -0,0 +1,25 @@ +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go b/vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go deleted file mode 100644 index 85657e6..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/custom_func/main.go +++ /dev/null @@ -1,133 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "math" - "math/rand" - - sqlite "github.com/mattn/go-sqlite3" -) - -// Computes x^y -func pow(x, y int64) int64 { - return int64(math.Pow(float64(x), float64(y))) -} - -// Computes the bitwise exclusive-or of all its arguments -func xor(xs ...int64) int64 { - var ret int64 - for _, x := range xs { - ret ^= x - } - return ret -} - -// Returns a random number. It's actually deterministic here because -// we don't seed the RNG, but it's an example of a non-pure function -// from SQLite's POV. -func getrand() int64 { - return rand.Int63() -} - -// Computes the standard deviation of a GROUPed BY set of values -type stddev struct { - xs []int64 - // Running average calculation - sum int64 - n int64 -} - -func newStddev() *stddev { return &stddev{} } - -func (s *stddev) Step(x int64) { - s.xs = append(s.xs, x) - s.sum += x - s.n++ -} - -func (s *stddev) Done() float64 { - mean := float64(s.sum) / float64(s.n) - var sqDiff []float64 - for _, x := range s.xs { - sqDiff = append(sqDiff, math.Pow(float64(x)-mean, 2)) - } - var dev float64 - for _, x := range sqDiff { - dev += x - } - dev /= float64(len(sqDiff)) - return math.Sqrt(dev) -} - -func main() { - sql.Register("sqlite3_custom", &sqlite.SQLiteDriver{ - ConnectHook: func(conn *sqlite.SQLiteConn) error { - if err := conn.RegisterFunc("pow", pow, true); err != nil { - return err - } - if err := conn.RegisterFunc("xor", xor, true); err != nil { - return err - } - if err := conn.RegisterFunc("rand", getrand, false); err != nil { - return err - } - if err := conn.RegisterAggregator("stddev", newStddev, true); err != nil { - return err - } - return nil - }, - }) - - db, err := sql.Open("sqlite3_custom", ":memory:") - if err != nil { - log.Fatal("Failed to open database:", err) - } - defer db.Close() - - var i int64 - err = db.QueryRow("SELECT pow(2,3)").Scan(&i) - if err != nil { - log.Fatal("POW query error:", err) - } - fmt.Println("pow(2,3) =", i) // 8 - - err = db.QueryRow("SELECT xor(1,2,3,4,5,6)").Scan(&i) - if err != nil { - log.Fatal("XOR query error:", err) - } - fmt.Println("xor(1,2,3,4,5) =", i) // 7 - - err = db.QueryRow("SELECT rand()").Scan(&i) - if err != nil { - log.Fatal("RAND query error:", err) - } - fmt.Println("rand() =", i) // pseudorandom - - _, err = db.Exec("create table foo (department integer, profits integer)") - if err != nil { - log.Fatal("Failed to create table:", err) - } - _, err = db.Exec("insert into foo values (1, 10), (1, 20), (1, 45), (2, 42), (2, 115)") - if err != nil { - log.Fatal("Failed to insert records:", err) - } - - rows, err := db.Query("select department, stddev(profits) from foo group by department") - if err != nil { - log.Fatal("STDDEV query error:", err) - } - defer rows.Close() - for rows.Next() { - var dept int64 - var dev float64 - if err := rows.Scan(&dept, &dev); err != nil { - log.Fatal(err) - } - fmt.Printf("dept=%d stddev=%f\n", dept, dev) - } - if err := rows.Err(); err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go b/vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go deleted file mode 100644 index 6023181..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/hook/hook.go +++ /dev/null @@ -1,78 +0,0 @@ -package main - -import ( - "database/sql" - "log" - "os" - - "github.com/mattn/go-sqlite3" -) - -func main() { - sqlite3conn := []*sqlite3.SQLiteConn{} - sql.Register("sqlite3_with_hook_example", - &sqlite3.SQLiteDriver{ - ConnectHook: func(conn *sqlite3.SQLiteConn) error { - sqlite3conn = append(sqlite3conn, conn) - conn.RegisterUpdateHook(func(op int, db string, table string, rowid int64) { - switch op { - case sqlite3.SQLITE_INSERT: - log.Println("Notified of insert on db", db, "table", table, "rowid", rowid) - } - }) - return nil - }, - }) - os.Remove("./foo.db") - os.Remove("./bar.db") - - srcDb, err := sql.Open("sqlite3_with_hook_example", "./foo.db") - if err != nil { - log.Fatal(err) - } - defer srcDb.Close() - srcDb.Ping() - - _, err = srcDb.Exec("create table foo(id int, value text)") - if err != nil { - log.Fatal(err) - } - _, err = srcDb.Exec("insert into foo values(1, 'foo')") - if err != nil { - log.Fatal(err) - } - _, err = srcDb.Exec("insert into foo values(2, 'bar')") - if err != nil { - log.Fatal(err) - } - _, err = srcDb.Query("select * from foo") - if err != nil { - log.Fatal(err) - } - destDb, err := sql.Open("sqlite3_with_hook_example", "./bar.db") - if err != nil { - log.Fatal(err) - } - defer destDb.Close() - destDb.Ping() - - bk, err := sqlite3conn[1].Backup("main", sqlite3conn[0], "main") - if err != nil { - log.Fatal(err) - } - - _, err = bk.Step(-1) - if err != nil { - log.Fatal(err) - } - _, err = destDb.Query("select * from foo") - if err != nil { - log.Fatal(err) - } - _, err = destDb.Exec("insert into foo values(3, 'bar')") - if err != nil { - log.Fatal(err) - } - - bk.Finish() -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/limit/limit.go b/vendor/github.com/mattn/go-sqlite3/_example/limit/limit.go deleted file mode 100644 index 4e4b897..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/limit/limit.go +++ /dev/null @@ -1,113 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "os" - "strings" - - "github.com/mattn/go-sqlite3" -) - -func createBulkInsertQuery(n int, start int) (query string, args []interface{}) { - values := make([]string, n) - args = make([]interface{}, n*2) - pos := 0 - for i := 0; i < n; i++ { - values[i] = "(?, ?)" - args[pos] = start + i - args[pos+1] = fmt.Sprintf("こんにちわ世界%03d", i) - pos += 2 - } - query = fmt.Sprintf( - "insert into foo(id, name) values %s", - strings.Join(values, ", "), - ) - return -} - -func bukInsert(db *sql.DB, query string, args []interface{}) (err error) { - stmt, err := db.Prepare(query) - if err != nil { - return - } - - _, err = stmt.Exec(args...) - if err != nil { - return - } - - return -} - -func main() { - var sqlite3conn *sqlite3.SQLiteConn - sql.Register("sqlite3_with_limit", &sqlite3.SQLiteDriver{ - ConnectHook: func(conn *sqlite3.SQLiteConn) error { - sqlite3conn = conn - return nil - }, - }) - - os.Remove("./foo.db") - db, err := sql.Open("sqlite3_with_limit", "./foo.db") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - sqlStmt := ` - create table foo (id integer not null primary key, name text); - delete from foo; - ` - _, err = db.Exec(sqlStmt) - if err != nil { - log.Printf("%q: %s\n", err, sqlStmt) - return - } - - if sqlite3conn == nil { - log.Fatal("not set sqlite3 connection") - } - - limitVariableNumber := sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("default SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - num := 400 - query, args := createBulkInsertQuery(num, 0) - err = bukInsert(db, query, args) - if err != nil { - log.Fatal(err) - } - - smallLimitVariableNumber := 100 - sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, smallLimitVariableNumber) - - limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - query, args = createBulkInsertQuery(num, num) - err = bukInsert(db, query, args) - if err != nil { - if err != nil { - log.Printf("expect failed since SQLITE_LIMIT_VARIABLE_NUMBER is too small: %v", err) - } - } - - bigLimitVariableNumber := 999999 - sqlite3conn.SetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, bigLimitVariableNumber) - limitVariableNumber = sqlite3conn.GetLimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER) - log.Printf("set SQLITE_LIMIT_VARIABLE_NUMBER: %d", bigLimitVariableNumber) - log.Printf("updated SQLITE_LIMIT_VARIABLE_NUMBER: %d", limitVariableNumber) - - query, args = createBulkInsertQuery(500, num+num) - err = bukInsert(db, query, args) - if err != nil { - if err != nil { - log.Fatal(err) - } - } - - log.Println("no error if SQLITE_LIMIT_VARIABLE_NUMBER > 999") -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile b/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile deleted file mode 100644 index 97b1e0f..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -ifeq ($(OS),Windows_NT) -EXE=extension.exe -EXT=sqlite3_mod_regexp.dll -RM=cmd /c del -LDFLAG= -else -EXE=extension -EXT=sqlite3_mod_regexp.so -RM=rm -LDFLAG=-fPIC -endif - -all : $(EXE) $(EXT) - -$(EXE) : extension.go - go build $< - -$(EXT) : sqlite3_mod_regexp.c - gcc $(LDFLAG) -shared -o $@ $< -lsqlite3 -lpcre - -clean : - @-$(RM) $(EXE) $(EXT) diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go b/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go deleted file mode 100644 index 61ceb55..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/extension.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "github.com/mattn/go-sqlite3" - "log" -) - -func main() { - sql.Register("sqlite3_with_extensions", - &sqlite3.SQLiteDriver{ - Extensions: []string{ - "sqlite3_mod_regexp", - }, - }) - - db, err := sql.Open("sqlite3_with_extensions", ":memory:") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - // Force db to make a new connection in pool - // by putting the original in a transaction - tx, err := db.Begin() - if err != nil { - log.Fatal(err) - } - defer tx.Commit() - - // New connection works (hopefully!) - rows, err := db.Query("select 'hello world' where 'hello world' regexp '^hello.*d$'") - if err != nil { - log.Fatal(err) - } - defer rows.Close() - for rows.Next() { - var helloworld string - rows.Scan(&helloworld) - fmt.Println(helloworld) - } -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c b/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c deleted file mode 100644 index 277764d..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_regexp/sqlite3_mod_regexp.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include - -SQLITE_EXTENSION_INIT1 -static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) { - if (argc >= 2) { - const char *target = (const char *)sqlite3_value_text(argv[1]); - const char *pattern = (const char *)sqlite3_value_text(argv[0]); - const char* errstr = NULL; - int erroff = 0; - int vec[500]; - int n, rc; - pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL); - rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); - if (rc <= 0) { - sqlite3_result_error(context, errstr, 0); - return; - } - sqlite3_result_int(context, 1); - } -} - -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) { - SQLITE_EXTENSION_INIT2(api); - return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, (void*)db, regexp_func, NULL, NULL); -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile b/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile deleted file mode 100644 index cdd4853..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -ifeq ($(OS),Windows_NT) -EXE=extension.exe -EXT=sqlite3_mod_vtable.dll -RM=cmd /c del -LIBCURL=-lcurldll -LDFLAG= -else -EXE=extension -EXT=sqlite3_mod_vtable.so -RM=rm -LDFLAG=-fPIC -LIBCURL=-lcurl -endif - -all : $(EXE) $(EXT) - -$(EXE) : extension.go - go build $< - -$(EXT) : sqlite3_mod_vtable.cc - g++ $(LDFLAG) -shared -o $@ $< -lsqlite3 $(LIBCURL) - -clean : - @-$(RM) $(EXE) $(EXT) diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go b/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go deleted file mode 100644 index f738af6..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/extension.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - - "github.com/mattn/go-sqlite3" -) - -func main() { - sql.Register("sqlite3_with_extensions", - &sqlite3.SQLiteDriver{ - Extensions: []string{ - "sqlite3_mod_vtable", - }, - }) - - db, err := sql.Open("sqlite3_with_extensions", ":memory:") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - db.Exec("create virtual table repo using github(id, full_name, description, html_url)") - - rows, err := db.Query("select id, full_name, description, html_url from repo") - if err != nil { - log.Fatal(err) - } - defer rows.Close() - for rows.Next() { - var id, fullName, description, htmlURL string - rows.Scan(&id, &fullName, &description, &htmlURL) - fmt.Printf("%s: %s\n\t%s\n\t%s\n\n", id, fullName, description, htmlURL) - } -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h b/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h deleted file mode 100644 index 2142647..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/picojson.h +++ /dev/null @@ -1,1040 +0,0 @@ -/* - * Copyright 2009-2010 Cybozu Labs, Inc. - * Copyright 2011 Kazuho Oku - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are - * those of the authors and should not be interpreted as representing official - * policies, either expressed or implied, of Cybozu Labs, Inc. - * - */ -#ifndef picojson_h -#define picojson_h - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _MSC_VER - #define SNPRINTF _snprintf_s - #pragma warning(push) - #pragma warning(disable : 4244) // conversion from int to char -#else - #define SNPRINTF snprintf -#endif - -namespace picojson { - - enum { - null_type, - boolean_type, - number_type, - string_type, - array_type, - object_type - }; - - struct null {}; - - class value { - public: - typedef std::vector array; - typedef std::map object; - union _storage { - bool boolean_; - double number_; - std::string* string_; - array* array_; - object* object_; - }; - protected: - int type_; - _storage u_; - public: - value(); - value(int type, bool); - explicit value(bool b); - explicit value(double n); - explicit value(const std::string& s); - explicit value(const array& a); - explicit value(const object& o); - explicit value(const char* s); - value(const char* s, size_t len); - ~value(); - value(const value& x); - value& operator=(const value& x); - void swap(value& x); - template bool is() const; - template const T& get() const; - template T& get(); - bool evaluate_as_boolean() const; - const value& get(size_t idx) const; - const value& get(const std::string& key) const; - bool contains(size_t idx) const; - bool contains(const std::string& key) const; - std::string to_str() const; - template void serialize(Iter os) const; - std::string serialize() const; - private: - template value(const T*); // intentionally defined to block implicit conversion of pointer to bool - }; - - typedef value::array array; - typedef value::object object; - - inline value::value() : type_(null_type) {} - - inline value::value(int type, bool) : type_(type) { - switch (type) { -#define INIT(p, v) case p##type: u_.p = v; break - INIT(boolean_, false); - INIT(number_, 0.0); - INIT(string_, new std::string()); - INIT(array_, new array()); - INIT(object_, new object()); -#undef INIT - default: break; - } - } - - inline value::value(bool b) : type_(boolean_type) { - u_.boolean_ = b; - } - - inline value::value(double n) : type_(number_type) { - u_.number_ = n; - } - - inline value::value(const std::string& s) : type_(string_type) { - u_.string_ = new std::string(s); - } - - inline value::value(const array& a) : type_(array_type) { - u_.array_ = new array(a); - } - - inline value::value(const object& o) : type_(object_type) { - u_.object_ = new object(o); - } - - inline value::value(const char* s) : type_(string_type) { - u_.string_ = new std::string(s); - } - - inline value::value(const char* s, size_t len) : type_(string_type) { - u_.string_ = new std::string(s, len); - } - - inline value::~value() { - switch (type_) { -#define DEINIT(p) case p##type: delete u_.p; break - DEINIT(string_); - DEINIT(array_); - DEINIT(object_); -#undef DEINIT - default: break; - } - } - - inline value::value(const value& x) : type_(x.type_) { - switch (type_) { -#define INIT(p, v) case p##type: u_.p = v; break - INIT(string_, new std::string(*x.u_.string_)); - INIT(array_, new array(*x.u_.array_)); - INIT(object_, new object(*x.u_.object_)); -#undef INIT - default: - u_ = x.u_; - break; - } - } - - inline value& value::operator=(const value& x) { - if (this != &x) { - this->~value(); - new (this) value(x); - } - return *this; - } - - inline void value::swap(value& x) { - std::swap(type_, x.type_); - std::swap(u_, x.u_); - } - -#define IS(ctype, jtype) \ - template <> inline bool value::is() const { \ - return type_ == jtype##_type; \ - } - IS(null, null) - IS(bool, boolean) - IS(int, number) - IS(double, number) - IS(std::string, string) - IS(array, array) - IS(object, object) -#undef IS - -#define GET(ctype, var) \ - template <> inline const ctype& value::get() const { \ - assert("type mismatch! call vis() before get()" \ - && is()); \ - return var; \ - } \ - template <> inline ctype& value::get() { \ - assert("type mismatch! call is() before get()" \ - && is()); \ - return var; \ - } - GET(bool, u_.boolean_) - GET(double, u_.number_) - GET(std::string, *u_.string_) - GET(array, *u_.array_) - GET(object, *u_.object_) -#undef GET - - inline bool value::evaluate_as_boolean() const { - switch (type_) { - case null_type: - return false; - case boolean_type: - return u_.boolean_; - case number_type: - return u_.number_ != 0; - case string_type: - return ! u_.string_->empty(); - default: - return true; - } - } - - inline const value& value::get(size_t idx) const { - static value s_null; - assert(is()); - return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; - } - - inline const value& value::get(const std::string& key) const { - static value s_null; - assert(is()); - object::const_iterator i = u_.object_->find(key); - return i != u_.object_->end() ? i->second : s_null; - } - - inline bool value::contains(size_t idx) const { - assert(is()); - return idx < u_.array_->size(); - } - - inline bool value::contains(const std::string& key) const { - assert(is()); - object::const_iterator i = u_.object_->find(key); - return i != u_.object_->end(); - } - - inline std::string value::to_str() const { - switch (type_) { - case null_type: return "null"; - case boolean_type: return u_.boolean_ ? "true" : "false"; - case number_type: { - char buf[256]; - double tmp; - SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_); - return buf; - } - case string_type: return *u_.string_; - case array_type: return "array"; - case object_type: return "object"; - default: assert(0); -#ifdef _MSC_VER - __assume(0); -#endif - } - return std::string(); - } - - template void copy(const std::string& s, Iter oi) { - std::copy(s.begin(), s.end(), oi); - } - - template void serialize_str(const std::string& s, Iter oi) { - *oi++ = '"'; - for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) { - switch (*i) { -#define MAP(val, sym) case val: copy(sym, oi); break - MAP('"', "\\\""); - MAP('\\', "\\\\"); - MAP('/', "\\/"); - MAP('\b', "\\b"); - MAP('\f', "\\f"); - MAP('\n', "\\n"); - MAP('\r', "\\r"); - MAP('\t', "\\t"); -#undef MAP - default: - if ((unsigned char)*i < 0x20 || *i == 0x7f) { - char buf[7]; - SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff); - copy(buf, buf + 6, oi); - } else { - *oi++ = *i; - } - break; - } - } - *oi++ = '"'; - } - - template void value::serialize(Iter oi) const { - switch (type_) { - case string_type: - serialize_str(*u_.string_, oi); - break; - case array_type: { - *oi++ = '['; - for (array::const_iterator i = u_.array_->begin(); - i != u_.array_->end(); - ++i) { - if (i != u_.array_->begin()) { - *oi++ = ','; - } - i->serialize(oi); - } - *oi++ = ']'; - break; - } - case object_type: { - *oi++ = '{'; - for (object::const_iterator i = u_.object_->begin(); - i != u_.object_->end(); - ++i) { - if (i != u_.object_->begin()) { - *oi++ = ','; - } - serialize_str(i->first, oi); - *oi++ = ':'; - i->second.serialize(oi); - } - *oi++ = '}'; - break; - } - default: - copy(to_str(), oi); - break; - } - } - - inline std::string value::serialize() const { - std::string s; - serialize(std::back_inserter(s)); - return s; - } - - template class input { - protected: - Iter cur_, end_; - int last_ch_; - bool ungot_; - int line_; - public: - input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {} - int getc() { - if (ungot_) { - ungot_ = false; - return last_ch_; - } - if (cur_ == end_) { - last_ch_ = -1; - return -1; - } - if (last_ch_ == '\n') { - line_++; - } - last_ch_ = *cur_++ & 0xff; - return last_ch_; - } - void ungetc() { - if (last_ch_ != -1) { - assert(! ungot_); - ungot_ = true; - } - } - Iter cur() const { return cur_; } - int line() const { return line_; } - void skip_ws() { - while (1) { - int ch = getc(); - if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { - ungetc(); - break; - } - } - } - bool expect(int expect) { - skip_ws(); - if (getc() != expect) { - ungetc(); - return false; - } - return true; - } - bool match(const std::string& pattern) { - for (std::string::const_iterator pi(pattern.begin()); - pi != pattern.end(); - ++pi) { - if (getc() != *pi) { - ungetc(); - return false; - } - } - return true; - } - }; - - template inline int _parse_quadhex(input &in) { - int uni_ch = 0, hex; - for (int i = 0; i < 4; i++) { - if ((hex = in.getc()) == -1) { - return -1; - } - if ('0' <= hex && hex <= '9') { - hex -= '0'; - } else if ('A' <= hex && hex <= 'F') { - hex -= 'A' - 0xa; - } else if ('a' <= hex && hex <= 'f') { - hex -= 'a' - 0xa; - } else { - in.ungetc(); - return -1; - } - uni_ch = uni_ch * 16 + hex; - } - return uni_ch; - } - - template inline bool _parse_codepoint(String& out, input& in) { - int uni_ch; - if ((uni_ch = _parse_quadhex(in)) == -1) { - return false; - } - if (0xd800 <= uni_ch && uni_ch <= 0xdfff) { - if (0xdc00 <= uni_ch) { - // a second 16-bit of a surrogate pair appeared - return false; - } - // first 16-bit of surrogate pair, get the next one - if (in.getc() != '\\' || in.getc() != 'u') { - in.ungetc(); - return false; - } - int second = _parse_quadhex(in); - if (! (0xdc00 <= second && second <= 0xdfff)) { - return false; - } - uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff); - uni_ch += 0x10000; - } - if (uni_ch < 0x80) { - out.push_back(uni_ch); - } else { - if (uni_ch < 0x800) { - out.push_back(0xc0 | (uni_ch >> 6)); - } else { - if (uni_ch < 0x10000) { - out.push_back(0xe0 | (uni_ch >> 12)); - } else { - out.push_back(0xf0 | (uni_ch >> 18)); - out.push_back(0x80 | ((uni_ch >> 12) & 0x3f)); - } - out.push_back(0x80 | ((uni_ch >> 6) & 0x3f)); - } - out.push_back(0x80 | (uni_ch & 0x3f)); - } - return true; - } - - template inline bool _parse_string(String& out, input& in) { - while (1) { - int ch = in.getc(); - if (ch < ' ') { - in.ungetc(); - return false; - } else if (ch == '"') { - return true; - } else if (ch == '\\') { - if ((ch = in.getc()) == -1) { - return false; - } - switch (ch) { -#define MAP(sym, val) case sym: out.push_back(val); break - MAP('"', '\"'); - MAP('\\', '\\'); - MAP('/', '/'); - MAP('b', '\b'); - MAP('f', '\f'); - MAP('n', '\n'); - MAP('r', '\r'); - MAP('t', '\t'); -#undef MAP - case 'u': - if (! _parse_codepoint(out, in)) { - return false; - } - break; - default: - return false; - } - } else { - out.push_back(ch); - } - } - return false; - } - - template inline bool _parse_array(Context& ctx, input& in) { - if (! ctx.parse_array_start()) { - return false; - } - size_t idx = 0; - if (in.expect(']')) { - return ctx.parse_array_stop(idx); - } - do { - if (! ctx.parse_array_item(in, idx)) { - return false; - } - idx++; - } while (in.expect(',')); - return in.expect(']') && ctx.parse_array_stop(idx); - } - - template inline bool _parse_object(Context& ctx, input& in) { - if (! ctx.parse_object_start()) { - return false; - } - if (in.expect('}')) { - return true; - } - do { - std::string key; - if (! in.expect('"') - || ! _parse_string(key, in) - || ! in.expect(':')) { - return false; - } - if (! ctx.parse_object_item(in, key)) { - return false; - } - } while (in.expect(',')); - return in.expect('}'); - } - - template inline bool _parse_number(double& out, input& in) { - std::string num_str; - while (1) { - int ch = in.getc(); - if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == '.' - || ch == 'e' || ch == 'E') { - num_str.push_back(ch); - } else { - in.ungetc(); - break; - } - } - char* endp; - out = strtod(num_str.c_str(), &endp); - return endp == num_str.c_str() + num_str.size(); - } - - template inline bool _parse(Context& ctx, input& in) { - in.skip_ws(); - int ch = in.getc(); - switch (ch) { -#define IS(ch, text, op) case ch: \ - if (in.match(text) && op) { \ - return true; \ - } else { \ - return false; \ - } - IS('n', "ull", ctx.set_null()); - IS('f', "alse", ctx.set_bool(false)); - IS('t', "rue", ctx.set_bool(true)); -#undef IS - case '"': - return ctx.parse_string(in); - case '[': - return _parse_array(ctx, in); - case '{': - return _parse_object(ctx, in); - default: - if (('0' <= ch && ch <= '9') || ch == '-') { - in.ungetc(); - double f; - if (_parse_number(f, in)) { - ctx.set_number(f); - return true; - } else { - return false; - } - } - break; - } - in.ungetc(); - return false; - } - - class deny_parse_context { - public: - bool set_null() { return false; } - bool set_bool(bool) { return false; } - bool set_number(double) { return false; } - template bool parse_string(input&) { return false; } - bool parse_array_start() { return false; } - template bool parse_array_item(input&, size_t) { - return false; - } - bool parse_array_stop(size_t) { return false; } - bool parse_object_start() { return false; } - template bool parse_object_item(input&, const std::string&) { - return false; - } - }; - - class default_parse_context { - protected: - value* out_; - public: - default_parse_context(value* out) : out_(out) {} - bool set_null() { - *out_ = value(); - return true; - } - bool set_bool(bool b) { - *out_ = value(b); - return true; - } - bool set_number(double f) { - *out_ = value(f); - return true; - } - template bool parse_string(input& in) { - *out_ = value(string_type, false); - return _parse_string(out_->get(), in); - } - bool parse_array_start() { - *out_ = value(array_type, false); - return true; - } - template bool parse_array_item(input& in, size_t) { - array& a = out_->get(); - a.push_back(value()); - default_parse_context ctx(&a.back()); - return _parse(ctx, in); - } - bool parse_array_stop(size_t) { return true; } - bool parse_object_start() { - *out_ = value(object_type, false); - return true; - } - template bool parse_object_item(input& in, const std::string& key) { - object& o = out_->get(); - default_parse_context ctx(&o[key]); - return _parse(ctx, in); - } - private: - default_parse_context(const default_parse_context&); - default_parse_context& operator=(const default_parse_context&); - }; - - class null_parse_context { - public: - struct dummy_str { - void push_back(int) {} - }; - public: - null_parse_context() {} - bool set_null() { return true; } - bool set_bool(bool) { return true; } - bool set_number(double) { return true; } - template bool parse_string(input& in) { - dummy_str s; - return _parse_string(s, in); - } - bool parse_array_start() { return true; } - template bool parse_array_item(input& in, size_t) { - return _parse(*this, in); - } - bool parse_array_stop(size_t) { return true; } - bool parse_object_start() { return true; } - template bool parse_object_item(input& in, const std::string&) { - return _parse(*this, in); - } - private: - null_parse_context(const null_parse_context&); - null_parse_context& operator=(const null_parse_context&); - }; - - // obsolete, use the version below - template inline std::string parse(value& out, Iter& pos, const Iter& last) { - std::string err; - pos = parse(out, pos, last, &err); - return err; - } - - template inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) { - input in(first, last); - if (! _parse(ctx, in) && err != NULL) { - char buf[64]; - SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line()); - *err = buf; - while (1) { - int ch = in.getc(); - if (ch == -1 || ch == '\n') { - break; - } else if (ch >= ' ') { - err->push_back(ch); - } - } - } - return in.cur(); - } - - template inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) { - default_parse_context ctx(&out); - return _parse(ctx, first, last, err); - } - - inline std::string parse(value& out, std::istream& is) { - std::string err; - parse(out, std::istreambuf_iterator(is.rdbuf()), - std::istreambuf_iterator(), &err); - return err; - } - - template struct last_error_t { - static std::string s; - }; - template std::string last_error_t::s; - - inline void set_last_error(const std::string& s) { - last_error_t::s = s; - } - - inline const std::string& get_last_error() { - return last_error_t::s; - } - - inline bool operator==(const value& x, const value& y) { - if (x.is()) - return y.is(); -#define PICOJSON_CMP(type) \ - if (x.is()) \ - return y.is() && x.get() == y.get() - PICOJSON_CMP(bool); - PICOJSON_CMP(double); - PICOJSON_CMP(std::string); - PICOJSON_CMP(array); - PICOJSON_CMP(object); -#undef PICOJSON_CMP - assert(0); -#ifdef _MSC_VER - __assume(0); -#endif - return false; - } - - inline bool operator!=(const value& x, const value& y) { - return ! (x == y); - } -} - -namespace std { - template<> inline void swap(picojson::value& x, picojson::value& y) - { - x.swap(y); - } -} - -inline std::istream& operator>>(std::istream& is, picojson::value& x) -{ - picojson::set_last_error(std::string()); - std::string err = picojson::parse(x, is); - if (! err.empty()) { - picojson::set_last_error(err); - is.setstate(std::ios::failbit); - } - return is; -} - -inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) -{ - x.serialize(std::ostream_iterator(os)); - return os; -} -#ifdef _MSC_VER - #pragma warning(pop) -#endif - -#endif -#ifdef TEST_PICOJSON -#ifdef _MSC_VER - #pragma warning(disable : 4127) // conditional expression is constant -#endif - -using namespace std; - -static void plan(int num) -{ - printf("1..%d\n", num); -} - -static bool success = true; - -static void ok(bool b, const char* name = "") -{ - static int n = 1; - if (! b) - success = false; - printf("%s %d - %s\n", b ? "ok" : "ng", n++, name); -} - -template void is(const T& x, const T& y, const char* name = "") -{ - if (x == y) { - ok(true, name); - } else { - ok(false, name); - } -} - -#include -#include -#include -#include - -int main(void) -{ - plan(85); - - // constructors -#define TEST(expr, expected) \ - is(picojson::value expr .serialize(), string(expected), "picojson::value" #expr) - - TEST( (true), "true"); - TEST( (false), "false"); - TEST( (42.0), "42"); - TEST( (string("hello")), "\"hello\""); - TEST( ("hello"), "\"hello\""); - TEST( ("hello", 4), "\"hell\""); - - { - double a = 1; - for (int i = 0; i < 1024; i++) { - picojson::value vi(a); - std::stringstream ss; - ss << vi; - picojson::value vo; - ss >> vo; - double b = vo.get(); - if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) { - printf("ng i=%d a=%.18e b=%.18e\n", i, a, b); - } - a *= 2; - } - } - -#undef TEST - -#define TEST(in, type, cmp, serialize_test) { \ - picojson::value v; \ - const char* s = in; \ - string err = picojson::parse(v, s, s + strlen(s)); \ - ok(err.empty(), in " no error"); \ - ok(v.is(), in " check type"); \ - is(v.get(), cmp, in " correct output"); \ - is(*s, '\0', in " read to eof"); \ - if (serialize_test) { \ - is(v.serialize(), string(in), in " serialize"); \ - } \ - } - TEST("false", bool, false, true); - TEST("true", bool, true, true); - TEST("90.5", double, 90.5, false); - TEST("1.7976931348623157e+308", double, DBL_MAX, false); - TEST("\"hello\"", string, string("hello"), true); - TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"), - true); - TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string, - string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"), false); - TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false); -#undef TEST - -#define TEST(type, expr) { \ - picojson::value v; \ - const char *s = expr; \ - string err = picojson::parse(v, s, s + strlen(s)); \ - ok(err.empty(), "empty " #type " no error"); \ - ok(v.is(), "empty " #type " check type"); \ - ok(v.get().empty(), "check " #type " array size"); \ - } - TEST(array, "[]"); - TEST(object, "{}"); -#undef TEST - - { - picojson::value v; - const char *s = "[1,true,\"hello\"]"; - string err = picojson::parse(v, s, s + strlen(s)); - ok(err.empty(), "array no error"); - ok(v.is(), "array check type"); - is(v.get().size(), size_t(3), "check array size"); - ok(v.contains(0), "check contains array[0]"); - ok(v.get(0).is(), "check array[0] type"); - is(v.get(0).get(), 1.0, "check array[0] value"); - ok(v.contains(1), "check contains array[1]"); - ok(v.get(1).is(), "check array[1] type"); - ok(v.get(1).get(), "check array[1] value"); - ok(v.contains(2), "check contains array[2]"); - ok(v.get(2).is(), "check array[2] type"); - is(v.get(2).get(), string("hello"), "check array[2] value"); - ok(!v.contains(3), "check not contains array[3]"); - } - - { - picojson::value v; - const char *s = "{ \"a\": true }"; - string err = picojson::parse(v, s, s + strlen(s)); - ok(err.empty(), "object no error"); - ok(v.is(), "object check type"); - is(v.get().size(), size_t(1), "check object size"); - ok(v.contains("a"), "check contains property"); - ok(v.get("a").is(), "check bool property exists"); - is(v.get("a").get(), true, "check bool property value"); - is(v.serialize(), string("{\"a\":true}"), "serialize object"); - ok(!v.contains("z"), "check not contains property"); - } - -#define TEST(json, msg) do { \ - picojson::value v; \ - const char *s = json; \ - string err = picojson::parse(v, s, s + strlen(s)); \ - is(err, string("syntax error at line " msg), msg); \ - } while (0) - TEST("falsoa", "1 near: oa"); - TEST("{]", "1 near: ]"); - TEST("\n\bbell", "2 near: bell"); - TEST("\"abc\nd\"", "1 near: "); -#undef TEST - - { - picojson::value v1, v2; - const char *s; - string err; - s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; - err = picojson::parse(v1, s, s + strlen(s)); - s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }"; - err = picojson::parse(v2, s, s + strlen(s)); - ok((v1 == v2), "check == operator in deep comparison"); - } - - { - picojson::value v1, v2; - const char *s; - string err; - s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; - err = picojson::parse(v1, s, s + strlen(s)); - s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }"; - err = picojson::parse(v2, s, s + strlen(s)); - ok((v1 != v2), "check != operator for array in deep comparison"); - } - - { - picojson::value v1, v2; - const char *s; - string err; - s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; - err = picojson::parse(v1, s, s + strlen(s)); - s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }"; - err = picojson::parse(v2, s, s + strlen(s)); - ok((v1 != v2), "check != operator for object in deep comparison"); - } - - { - picojson::value v1, v2; - const char *s; - string err; - s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }"; - err = picojson::parse(v1, s, s + strlen(s)); - picojson::object& o = v1.get(); - o.erase("b"); - picojson::array& a = o["a"].get(); - picojson::array::iterator i; - i = std::remove(a.begin(), a.end(), picojson::value(std::string("three"))); - a.erase(i, a.end()); - s = "{ \"a\": [1,2], \"d\": 2 }"; - err = picojson::parse(v2, s, s + strlen(s)); - ok((v1 == v2), "check erase()"); - } - - ok(picojson::value(3.0).serialize() == "3", - "integral number should be serialized as a integer"); - - { - const char* s = "{ \"a\": [1,2], \"d\": 2 }"; - picojson::null_parse_context ctx; - string err; - picojson::_parse(ctx, s, s + strlen(s), &err); - ok(err.empty(), "null_parse_context"); - } - - { - picojson::value v1, v2; - v1 = picojson::value(true); - swap(v1, v2); - ok(v1.is(), "swap (null)"); - ok(v2.get() == true, "swap (bool)"); - - v1 = picojson::value("a"); - v2 = picojson::value(1.0); - swap(v1, v2); - ok(v1.get() == 1.0, "swap (dobule)"); - ok(v2.get() == "a", "swap (string)"); - - v1 = picojson::value(picojson::object()); - v2 = picojson::value(picojson::array()); - swap(v1, v2); - ok(v1.is(), "swap (array)"); - ok(v2.is(), "swap (object)"); - } - - return success ? 0 : 1; -} - -#endif diff --git a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc b/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc deleted file mode 100644 index 5bd4e66..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/mod_vtable/sqlite3_mod_vtable.cc +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include -#include -#include -#include -#include "picojson.h" - -#ifdef _WIN32 -# define EXPORT __declspec(dllexport) -#else -# define EXPORT -#endif - -SQLITE_EXTENSION_INIT1; - -typedef struct { - char* data; // response data from server - size_t size; // response size of data -} MEMFILE; - -MEMFILE* -memfopen() { - MEMFILE* mf = (MEMFILE*) malloc(sizeof(MEMFILE)); - if (mf) { - mf->data = NULL; - mf->size = 0; - } - return mf; -} - -void -memfclose(MEMFILE* mf) { - if (mf->data) free(mf->data); - free(mf); -} - -size_t -memfwrite(char* ptr, size_t size, size_t nmemb, void* stream) { - MEMFILE* mf = (MEMFILE*) stream; - int block = size * nmemb; - if (!mf) return block; // through - if (!mf->data) - mf->data = (char*) malloc(block); - else - mf->data = (char*) realloc(mf->data, mf->size + block); - if (mf->data) { - memcpy(mf->data + mf->size, ptr, block); - mf->size += block; - } - return block; -} - -char* -memfstrdup(MEMFILE* mf) { - char* buf; - if (mf->size == 0) return NULL; - buf = (char*) malloc(mf->size + 1); - memcpy(buf, mf->data, mf->size); - buf[mf->size] = 0; - return buf; -} - -static int -my_connect(sqlite3 *db, void *pAux, int argc, const char * const *argv, sqlite3_vtab **ppVTab, char **c) { - std::stringstream ss; - ss << "CREATE TABLE " << argv[0] - << "(id int, full_name text, description text, html_url text)"; - int rc = sqlite3_declare_vtab(db, ss.str().c_str()); - *ppVTab = (sqlite3_vtab *) sqlite3_malloc(sizeof(sqlite3_vtab)); - memset(*ppVTab, 0, sizeof(sqlite3_vtab)); - return rc; -} - -static int -my_create(sqlite3 *db, void *pAux, int argc, const char * const * argv, sqlite3_vtab **ppVTab, char **c) { - return my_connect(db, pAux, argc, argv, ppVTab, c); -} - -static int my_disconnect(sqlite3_vtab *pVTab) { - sqlite3_free(pVTab); - return SQLITE_OK; -} - -static int -my_destroy(sqlite3_vtab *pVTab) { - sqlite3_free(pVTab); - return SQLITE_OK; -} - -typedef struct { - sqlite3_vtab_cursor base; - int index; - picojson::value* rows; -} cursor; - -static int -my_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { - MEMFILE* mf; - CURL* curl; - char* json; - CURLcode res = CURLE_OK; - char error[CURL_ERROR_SIZE] = {0}; - char* cert_file = getenv("SSL_CERT_FILE"); - - mf = memfopen(); - curl = curl_easy_init(); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.29.0"); - curl_easy_setopt(curl, CURLOPT_URL, "https://api.github.com/repositories"); - if (cert_file) - curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - if (res != CURLE_OK) { - std::cerr << error << std::endl; - return SQLITE_FAIL; - } - - picojson::value* v = new picojson::value; - std::string err; - picojson::parse(*v, mf->data, mf->data + mf->size, &err); - memfclose(mf); - - if (!err.empty()) { - delete v; - std::cerr << err << std::endl; - return SQLITE_FAIL; - } - - cursor *c = (cursor *)sqlite3_malloc(sizeof(cursor)); - c->rows = v; - c->index = 0; - *ppCursor = &c->base; - return SQLITE_OK; -} - -static int -my_close(cursor *c) { - delete c->rows; - sqlite3_free(c); - return SQLITE_OK; -} - -static int -my_filter(cursor *c, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { - c->index = 0; - return SQLITE_OK; -} - -static int -my_next(cursor *c) { - c->index++; - return SQLITE_OK; -} - -static int -my_eof(cursor *c) { - return c->index >= c->rows->get().size() ? 1 : 0; -} - -static int -my_column(cursor *c, sqlite3_context *ctxt, int i) { - picojson::value v = c->rows->get()[c->index]; - picojson::object row = v.get(); - const char* p = NULL; - switch (i) { - case 0: - p = row["id"].to_str().c_str(); - break; - case 1: - p = row["full_name"].to_str().c_str(); - break; - case 2: - p = row["description"].to_str().c_str(); - break; - case 3: - p = row["html_url"].to_str().c_str(); - break; - } - sqlite3_result_text(ctxt, strdup(p), strlen(p), free); - return SQLITE_OK; -} - -static int -my_rowid(cursor *c, sqlite3_int64 *pRowid) { - *pRowid = c->index; - return SQLITE_OK; -} - -static int -my_bestindex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) { - return SQLITE_OK; -} - -static const sqlite3_module module = { - 0, - my_create, - my_connect, - my_bestindex, - my_disconnect, - my_destroy, - my_open, - (int (*)(sqlite3_vtab_cursor *)) my_close, - (int (*)(sqlite3_vtab_cursor *, int, char const *, int, sqlite3_value **)) my_filter, - (int (*)(sqlite3_vtab_cursor *)) my_next, - (int (*)(sqlite3_vtab_cursor *)) my_eof, - (int (*)(sqlite3_vtab_cursor *, sqlite3_context *, int)) my_column, - (int (*)(sqlite3_vtab_cursor *, sqlite3_int64 *)) my_rowid, - NULL, // my_update - NULL, // my_begin - NULL, // my_sync - NULL, // my_commit - NULL, // my_rollback - NULL, // my_findfunction - NULL, // my_rename -}; - -static void -destructor(void *arg) { - return; -} - - -extern "C" { - -EXPORT int -sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) { - SQLITE_EXTENSION_INIT2(api); - sqlite3_create_module_v2(db, "github", &module, NULL, destructor); - return 0; -} - -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go b/vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go deleted file mode 100644 index 261ed4d..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/simple/simple.go +++ /dev/null @@ -1,106 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - _ "github.com/mattn/go-sqlite3" - "log" - "os" -) - -func main() { - os.Remove("./foo.db") - - db, err := sql.Open("sqlite3", "./foo.db") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - sqlStmt := ` - create table foo (id integer not null primary key, name text); - delete from foo; - ` - _, err = db.Exec(sqlStmt) - if err != nil { - log.Printf("%q: %s\n", err, sqlStmt) - return - } - - tx, err := db.Begin() - if err != nil { - log.Fatal(err) - } - stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)") - if err != nil { - log.Fatal(err) - } - defer stmt.Close() - for i := 0; i < 100; i++ { - _, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i)) - if err != nil { - log.Fatal(err) - } - } - tx.Commit() - - rows, err := db.Query("select id, name from foo") - if err != nil { - log.Fatal(err) - } - defer rows.Close() - for rows.Next() { - var id int - var name string - err = rows.Scan(&id, &name) - if err != nil { - log.Fatal(err) - } - fmt.Println(id, name) - } - err = rows.Err() - if err != nil { - log.Fatal(err) - } - - stmt, err = db.Prepare("select name from foo where id = ?") - if err != nil { - log.Fatal(err) - } - defer stmt.Close() - var name string - err = stmt.QueryRow("3").Scan(&name) - if err != nil { - log.Fatal(err) - } - fmt.Println(name) - - _, err = db.Exec("delete from foo") - if err != nil { - log.Fatal(err) - } - - _, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')") - if err != nil { - log.Fatal(err) - } - - rows, err = db.Query("select id, name from foo") - if err != nil { - log.Fatal(err) - } - defer rows.Close() - for rows.Next() { - var id int - var name string - err = rows.Scan(&id, &name) - if err != nil { - log.Fatal(err) - } - fmt.Println(id, name) - } - err = rows.Err() - if err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/trace/main.go b/vendor/github.com/mattn/go-sqlite3/_example/trace/main.go deleted file mode 100644 index 9f83ee1..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/trace/main.go +++ /dev/null @@ -1,264 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - "os" - - sqlite3 "github.com/mattn/go-sqlite3" -) - -func traceCallback(info sqlite3.TraceInfo) int { - // Not very readable but may be useful; uncomment next line in case of doubt: - //fmt.Printf("Trace: %#v\n", info) - - var dbErrText string - if info.DBError.Code != 0 || info.DBError.ExtendedCode != 0 { - dbErrText = fmt.Sprintf("; DB error: %#v", info.DBError) - } else { - dbErrText = "." - } - - // Show the Statement-or-Trigger text in curly braces ('{', '}') - // since from the *paired* ASCII characters they are - // the least used in SQL syntax, therefore better visual delimiters. - // Maybe show 'ExpandedSQL' the same way as 'StmtOrTrigger'. - // - // A known use of curly braces (outside strings) is - // for ODBC escape sequences. Not likely to appear here. - // - // Template languages, etc. don't matter, we should see their *result* - // at *this* level. - // Strange curly braces in SQL code that reached the database driver - // suggest that there is a bug in the application. - // The braces are likely to be either template syntax or - // a programming language's string interpolation syntax. - - var expandedText string - if info.ExpandedSQL != "" { - if info.ExpandedSQL == info.StmtOrTrigger { - expandedText = " = exp" - } else { - expandedText = fmt.Sprintf(" expanded {%q}", info.ExpandedSQL) - } - } else { - expandedText = "" - } - - // SQLite docs as of September 6, 2016: Tracing and Profiling Functions - // https://www.sqlite.org/c3ref/profile.html - // - // The profile callback time is in units of nanoseconds, however - // the current implementation is only capable of millisecond resolution - // so the six least significant digits in the time are meaningless. - // Future versions of SQLite might provide greater resolution on the profiler callback. - - var runTimeText string - if info.RunTimeNanosec == 0 { - if info.EventCode == sqlite3.TraceProfile { - //runTimeText = "; no time" // seems confusing - runTimeText = "; time 0" // no measurement unit - } else { - //runTimeText = "; no time" // seems useless and confusing - } - } else { - const nanosPerMillisec = 1000000 - if info.RunTimeNanosec%nanosPerMillisec == 0 { - runTimeText = fmt.Sprintf("; time %d ms", info.RunTimeNanosec/nanosPerMillisec) - } else { - // unexpected: better than millisecond resolution - runTimeText = fmt.Sprintf("; time %d ns!!!", info.RunTimeNanosec) - } - } - - var modeText string - if info.AutoCommit { - modeText = "-AC-" - } else { - modeText = "+Tx+" - } - - fmt.Printf("Trace: ev %d %s conn 0x%x, stmt 0x%x {%q}%s%s%s\n", - info.EventCode, modeText, info.ConnHandle, info.StmtHandle, - info.StmtOrTrigger, expandedText, - runTimeText, - dbErrText) - return 0 -} - -func main() { - eventMask := sqlite3.TraceStmt | sqlite3.TraceProfile | sqlite3.TraceRow | sqlite3.TraceClose - - sql.Register("sqlite3_tracing", - &sqlite3.SQLiteDriver{ - ConnectHook: func(conn *sqlite3.SQLiteConn) error { - err := conn.SetTrace(&sqlite3.TraceConfig{ - Callback: traceCallback, - EventMask: uint(eventMask), - WantExpandedSQL: true, - }) - return err - }, - }) - - os.Exit(dbMain()) -} - -// Harder to do DB work in main(). -// It's better with a separate function because -// 'defer' and 'os.Exit' don't go well together. -// -// DO NOT use 'log.Fatal...' below: remember that it's equivalent to -// Print() followed by a call to os.Exit(1) --- and -// we want to avoid Exit() so 'defer' can do cleanup. -// Use 'log.Panic...' instead. - -func dbMain() int { - db, err := sql.Open("sqlite3_tracing", ":memory:") - if err != nil { - fmt.Printf("Failed to open database: %#+v\n", err) - return 1 - } - defer db.Close() - - err = db.Ping() - if err != nil { - log.Panic(err) - } - - dbSetup(db) - - dbDoInsert(db) - dbDoInsertPrepared(db) - dbDoSelect(db) - dbDoSelectPrepared(db) - - return 0 -} - -// 'DDL' stands for "Data Definition Language": - -// Note: "INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT" causes the error -// 'near "AUTOINCREMENT": syntax error'; without "NOT NULL" it works. -const tableDDL = `CREATE TABLE t1 ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - note VARCHAR NOT NULL -)` - -// 'DML' stands for "Data Manipulation Language": - -const insertDML = "INSERT INTO t1 (note) VALUES (?)" -const selectDML = "SELECT id, note FROM t1 WHERE note LIKE ?" - -const textPrefix = "bla-1234567890-" -const noteTextPattern = "%Prep%" - -const nGenRows = 4 // Number of Rows to Generate (for *each* approach tested) - -func dbSetup(db *sql.DB) { - var err error - - _, err = db.Exec("DROP TABLE IF EXISTS t1") - if err != nil { - log.Panic(err) - } - _, err = db.Exec(tableDDL) - if err != nil { - log.Panic(err) - } -} - -func dbDoInsert(db *sql.DB) { - const Descr = "DB-Exec" - for i := 0; i < nGenRows; i++ { - result, err := db.Exec(insertDML, textPrefix+Descr) - if err != nil { - log.Panic(err) - } - - resultDoCheck(result, Descr, i) - } -} - -func dbDoInsertPrepared(db *sql.DB) { - const Descr = "DB-Prepare" - - stmt, err := db.Prepare(insertDML) - if err != nil { - log.Panic(err) - } - defer stmt.Close() - - for i := 0; i < nGenRows; i++ { - result, err := stmt.Exec(textPrefix + Descr) - if err != nil { - log.Panic(err) - } - - resultDoCheck(result, Descr, i) - } -} - -func resultDoCheck(result sql.Result, callerDescr string, callIndex int) { - lastID, err := result.LastInsertId() - if err != nil { - log.Panic(err) - } - nAffected, err := result.RowsAffected() - if err != nil { - log.Panic(err) - } - - log.Printf("Exec result for %s (%d): ID = %d, affected = %d\n", callerDescr, callIndex, lastID, nAffected) -} - -func dbDoSelect(db *sql.DB) { - const Descr = "DB-Query" - - rows, err := db.Query(selectDML, noteTextPattern) - if err != nil { - log.Panic(err) - } - defer rows.Close() - - rowsDoFetch(rows, Descr) -} - -func dbDoSelectPrepared(db *sql.DB) { - const Descr = "DB-Prepare" - - stmt, err := db.Prepare(selectDML) - if err != nil { - log.Panic(err) - } - defer stmt.Close() - - rows, err := stmt.Query(noteTextPattern) - if err != nil { - log.Panic(err) - } - defer rows.Close() - - rowsDoFetch(rows, Descr) -} - -func rowsDoFetch(rows *sql.Rows, callerDescr string) { - var nRows int - var id int64 - var note string - - for rows.Next() { - err := rows.Scan(&id, ¬e) - if err != nil { - log.Panic(err) - } - log.Printf("Row for %s (%d): id=%d, note=%q\n", - callerDescr, nRows, id, note) - nRows++ - } - if err := rows.Err(); err != nil { - log.Panic(err) - } - log.Printf("Total %d rows for %s.\n", nRows, callerDescr) -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go b/vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go deleted file mode 100644 index aad8dda..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/vtable/main.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - "log" - - "github.com/mattn/go-sqlite3" -) - -func main() { - sql.Register("sqlite3_with_extensions", &sqlite3.SQLiteDriver{ - ConnectHook: func(conn *sqlite3.SQLiteConn) error { - return conn.CreateModule("github", &githubModule{}) - }, - }) - db, err := sql.Open("sqlite3_with_extensions", ":memory:") - if err != nil { - log.Fatal(err) - } - defer db.Close() - - _, err = db.Exec("create virtual table repo using github(id, full_name, description, html_url)") - if err != nil { - log.Fatal(err) - } - - rows, err := db.Query("select id, full_name, description, html_url from repo") - if err != nil { - log.Fatal(err) - } - defer rows.Close() - for rows.Next() { - var id, fullName, description, htmlURL string - rows.Scan(&id, &fullName, &description, &htmlURL) - fmt.Printf("%s: %s\n\t%s\n\t%s\n\n", id, fullName, description, htmlURL) - } -} diff --git a/vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go b/vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go deleted file mode 100644 index 1d6d824..0000000 --- a/vendor/github.com/mattn/go-sqlite3/_example/vtable/vtable.go +++ /dev/null @@ -1,111 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/mattn/go-sqlite3" -) - -type githubRepo struct { - ID int `json:"id"` - FullName string `json:"full_name"` - Description string `json:"description"` - HTMLURL string `json:"html_url"` -} - -type githubModule struct { -} - -func (m *githubModule) Create(c *sqlite3.SQLiteConn, args []string) (sqlite3.VTab, error) { - err := c.DeclareVTab(fmt.Sprintf(` - CREATE TABLE %s ( - id INT, - full_name TEXT, - description TEXT, - html_url TEXT - )`, args[0])) - if err != nil { - return nil, err - } - return &ghRepoTable{}, nil -} - -func (m *githubModule) Connect(c *sqlite3.SQLiteConn, args []string) (sqlite3.VTab, error) { - return m.Create(c, args) -} - -func (m *githubModule) DestroyModule() {} - -type ghRepoTable struct { - repos []githubRepo -} - -func (v *ghRepoTable) Open() (sqlite3.VTabCursor, error) { - resp, err := http.Get("https://api.github.com/repositories") - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var repos []githubRepo - if err := json.Unmarshal(body, &repos); err != nil { - return nil, err - } - return &ghRepoCursor{0, repos}, nil -} - -func (v *ghRepoTable) BestIndex(cst []sqlite3.InfoConstraint, ob []sqlite3.InfoOrderBy) (*sqlite3.IndexResult, error) { - return &sqlite3.IndexResult{}, nil -} - -func (v *ghRepoTable) Disconnect() error { return nil } -func (v *ghRepoTable) Destroy() error { return nil } - -type ghRepoCursor struct { - index int - repos []githubRepo -} - -func (vc *ghRepoCursor) Column(c *sqlite3.SQLiteContext, col int) error { - switch col { - case 0: - c.ResultInt(vc.repos[vc.index].ID) - case 1: - c.ResultText(vc.repos[vc.index].FullName) - case 2: - c.ResultText(vc.repos[vc.index].Description) - case 3: - c.ResultText(vc.repos[vc.index].HTMLURL) - } - return nil -} - -func (vc *ghRepoCursor) Filter(idxNum int, idxStr string, vals []interface{}) error { - vc.index = 0 - return nil -} - -func (vc *ghRepoCursor) Next() error { - vc.index++ - return nil -} - -func (vc *ghRepoCursor) EOF() bool { - return vc.index >= len(vc.repos) -} - -func (vc *ghRepoCursor) Rowid() (int64, error) { - return int64(vc.index), nil -} - -func (vc *ghRepoCursor) Close() error { - return nil -} diff --git a/vendor/github.com/mattn/go-sqlite3/tool/upgrade.go b/vendor/github.com/mattn/go-sqlite3/tool/upgrade.go deleted file mode 100644 index 94ed39d..0000000 --- a/vendor/github.com/mattn/go-sqlite3/tool/upgrade.go +++ /dev/null @@ -1,111 +0,0 @@ -// +build ignore - -package main - -import ( - "archive/zip" - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "os" - "path" - "path/filepath" - "strings" - - "github.com/PuerkitoBio/goquery" -) - -func main() { - site := "https://www.sqlite.org/download.html" - fmt.Printf("scraping %v\n", site) - doc, err := goquery.NewDocument(site) - if err != nil { - log.Fatal(err) - } - var url string - doc.Find("a").Each(func(_ int, s *goquery.Selection) { - if url == "" && strings.HasPrefix(s.Text(), "sqlite-amalgamation-") { - url = "https://www.sqlite.org/2017/" + s.Text() - } - }) - if url == "" { - return - } - fmt.Printf("downloading %v\n", url) - resp, err := http.Get(url) - if err != nil { - log.Fatal(err) - } - - b, err := ioutil.ReadAll(resp.Body) - if err != nil { - resp.Body.Close() - log.Fatal(err) - } - - fmt.Printf("extracting %v\n", path.Base(url)) - r, err := zip.NewReader(bytes.NewReader(b), resp.ContentLength) - if err != nil { - resp.Body.Close() - log.Fatal(err) - } - resp.Body.Close() - - for _, zf := range r.File { - var f *os.File - switch path.Base(zf.Name) { - case "sqlite3.c": - f, err = os.Create("sqlite3-binding.c") - case "sqlite3.h": - f, err = os.Create("sqlite3-binding.h") - case "sqlite3ext.h": - f, err = os.Create("sqlite3ext.h") - default: - continue - } - if err != nil { - log.Fatal(err) - } - zr, err := zf.Open() - if err != nil { - log.Fatal(err) - } - - _, err = io.WriteString(f, "#ifndef USE_LIBSQLITE3\n") - if err != nil { - zr.Close() - f.Close() - log.Fatal(err) - } - scanner := bufio.NewScanner(zr) - for scanner.Scan() { - text := scanner.Text() - if text == `#include "sqlite3.h"` { - text = `#include "sqlite3-binding.h"` - } - _, err = fmt.Fprintln(f, text) - if err != nil { - break - } - } - err = scanner.Err() - if err != nil { - zr.Close() - f.Close() - log.Fatal(err) - } - _, err = io.WriteString(f, "#else // USE_LIBSQLITE3\n // If users really want to link against the system sqlite3 we\n// need to make this file a noop.\n #endif") - if err != nil { - zr.Close() - f.Close() - log.Fatal(err) - } - zr.Close() - f.Close() - fmt.Printf("extracted %v\n", filepath.Base(f.Name())) - } -} diff --git a/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md b/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md new file mode 100644 index 0000000..2298515 --- /dev/null +++ b/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/go-wordwrap/README.md b/vendor/github.com/mitchellh/go-wordwrap/README.md new file mode 100644 index 0000000..60ae311 --- /dev/null +++ b/vendor/github.com/mitchellh/go-wordwrap/README.md @@ -0,0 +1,39 @@ +# go-wordwrap + +`go-wordwrap` (Golang package: `wordwrap`) is a package for Go that +automatically wraps words into multiple lines. The primary use case for this +is in formatting CLI output, but of course word wrapping is a generally useful +thing to do. + +## Installation and Usage + +Install using `go get github.com/mitchellh/go-wordwrap`. + +Full documentation is available at +http://godoc.org/github.com/mitchellh/go-wordwrap + +Below is an example of its usage ignoring errors: + +```go +wrapped := wordwrap.WrapString("foo bar baz", 3) +fmt.Println(wrapped) +``` + +Would output: + +``` +foo +bar +baz +``` + +## Word Wrap Algorithm + +This library doesn't use any clever algorithm for word wrapping. The wrapping +is actually very naive: whenever there is whitespace or an explicit linebreak. +The goal of this library is for word wrapping CLI output, so the input is +typically pretty well controlled human language. Because of this, the naive +approach typically works just fine. + +In the future, we'd like to make the algorithm more advanced. We would do +so without breaking the API. diff --git a/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go b/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go new file mode 100644 index 0000000..ac67205 --- /dev/null +++ b/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go @@ -0,0 +1,73 @@ +package wordwrap + +import ( + "bytes" + "unicode" +) + +// WrapString wraps the given string within lim width in characters. +// +// Wrapping is currently naive and only happens at white-space. A future +// version of the library will implement smarter wrapping. This means that +// pathological cases can dramatically reach past the limit, such as a very +// long word. +func WrapString(s string, lim uint) string { + // Initialize a buffer with a slightly larger size to account for breaks + init := make([]byte, 0, len(s)) + buf := bytes.NewBuffer(init) + + var current uint + var wordBuf, spaceBuf bytes.Buffer + + for _, char := range s { + if char == '\n' { + if wordBuf.Len() == 0 { + if current+uint(spaceBuf.Len()) > lim { + current = 0 + } else { + current += uint(spaceBuf.Len()) + spaceBuf.WriteTo(buf) + } + spaceBuf.Reset() + } else { + current += uint(spaceBuf.Len() + wordBuf.Len()) + spaceBuf.WriteTo(buf) + spaceBuf.Reset() + wordBuf.WriteTo(buf) + wordBuf.Reset() + } + buf.WriteRune(char) + current = 0 + } else if unicode.IsSpace(char) { + if spaceBuf.Len() == 0 || wordBuf.Len() > 0 { + current += uint(spaceBuf.Len() + wordBuf.Len()) + spaceBuf.WriteTo(buf) + spaceBuf.Reset() + wordBuf.WriteTo(buf) + wordBuf.Reset() + } + + spaceBuf.WriteRune(char) + } else { + + wordBuf.WriteRune(char) + + if current+uint(spaceBuf.Len()+wordBuf.Len()) > lim && uint(wordBuf.Len()) < lim { + buf.WriteRune('\n') + current = 0 + spaceBuf.Reset() + } + } + } + + if wordBuf.Len() == 0 { + if current+uint(spaceBuf.Len()) <= lim { + spaceBuf.WriteTo(buf) + } + } else { + spaceBuf.WriteTo(buf) + wordBuf.WriteTo(buf) + } + + return buf.String() +} diff --git a/vendor/github.com/mitchellh/go-wordwrap/wordwrap_test.go b/vendor/github.com/mitchellh/go-wordwrap/wordwrap_test.go new file mode 100644 index 0000000..bf6ae13 --- /dev/null +++ b/vendor/github.com/mitchellh/go-wordwrap/wordwrap_test.go @@ -0,0 +1,85 @@ +package wordwrap + +import ( + "testing" +) + +func TestWrapString(t *testing.T) { + cases := []struct { + Input, Output string + Lim uint + }{ + // A simple word passes through. + { + "foo", + "foo", + 4, + }, + // A single word that is too long passes through. + // We do not break words. + { + "foobarbaz", + "foobarbaz", + 4, + }, + // Lines are broken at whitespace. + { + "foo bar baz", + "foo\nbar\nbaz", + 4, + }, + // Lines are broken at whitespace, even if words + // are too long. We do not break words. + { + "foo bars bazzes", + "foo\nbars\nbazzes", + 4, + }, + // A word that would run beyond the width is wrapped. + { + "fo sop", + "fo\nsop", + 4, + }, + // Whitespace that trails a line and fits the width + // passes through, as does whitespace prefixing an + // explicit line break. A tab counts as one character. + { + "foo\nb\t r\n baz", + "foo\nb\t r\n baz", + 4, + }, + // Trailing whitespace is removed if it doesn't fit the width. + // Runs of whitespace on which a line is broken are removed. + { + "foo \nb ar ", + "foo\nb\nar", + 4, + }, + // An explicit line break at the end of the input is preserved. + { + "foo bar baz\n", + "foo\nbar\nbaz\n", + 4, + }, + // Explicit break are always preserved. + { + "\nfoo bar\n\n\nbaz\n", + "\nfoo\nbar\n\n\nbaz\n", + 4, + }, + // Complete example: + { + " This is a list: \n\n\t* foo\n\t* bar\n\n\n\t* baz \nBAM ", + " This\nis a\nlist: \n\n\t* foo\n\t* bar\n\n\n\t* baz\nBAM", + 6, + }, + } + + for i, tc := range cases { + actual := WrapString(tc.Input, tc.Lim) + if actual != tc.Output { + t.Fatalf("Case %d Input:\n\n`%s`\n\nActual Output:\n\n`%s`", i, tc.Input, actual) + } + } +} diff --git a/vendor/github.com/nsf/termbox-go/AUTHORS b/vendor/github.com/nsf/termbox-go/AUTHORS new file mode 100644 index 0000000..fe26fb0 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/AUTHORS @@ -0,0 +1,4 @@ +# Please keep this file sorted. + +Georg Reinke +nsf diff --git a/vendor/github.com/nsf/termbox-go/LICENSE b/vendor/github.com/nsf/termbox-go/LICENSE new file mode 100644 index 0000000..d9bc068 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012 termbox-go authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/nsf/termbox-go/README.md b/vendor/github.com/nsf/termbox-go/README.md new file mode 100644 index 0000000..35dcf1b --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/README.md @@ -0,0 +1,39 @@ +## Termbox +Termbox is a library that provides a minimalistic API which allows the programmer to write text-based user interfaces. The library is crossplatform and has both terminal-based implementations on *nix operating systems and a winapi console based implementation for windows operating systems. The basic idea is an abstraction of the greatest common subset of features available on all major terminals and other terminal-like APIs in a minimalistic fashion. Small API means it is easy to implement, test, maintain and learn it, that's what makes the termbox a distinct library in its area. + +### Installation +Install and update this go package with `go get -u github.com/nsf/termbox-go` + +### Examples +For examples of what can be done take a look at demos in the _demos directory. You can try them with go run: `go run _demos/keyboard.go` + +There are also some interesting projects using termbox-go: + - [godit](https://github.com/nsf/godit) is an emacsish lightweight text editor written using termbox. + - [gomatrix](https://github.com/GeertJohan/gomatrix) connects to The Matrix and displays its data streams in your terminal. + - [gotetris](https://github.com/jjinux/gotetris) is an implementation of Tetris. + - [sokoban-go](https://github.com/rn2dy/sokoban-go) is an implementation of sokoban game. + - [hecate](https://github.com/evanmiller/hecate) is a hex editor designed by Satan. + - [httopd](https://github.com/verdverm/httopd) is top for httpd logs. + - [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers. + - [termui](https://github.com/gizak/termui) is a terminal dashboard. + - [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine. + - [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart. + - [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces. + - [dry](https://github.com/moncho/dry) is an interactive cli to manage Docker containers. + - [pxl](https://github.com/ichinaski/pxl) displays images in the terminal. + - [snake-game](https://github.com/DyegoCosta/snake-game) is an implementation of the Snake game. + - [gone](https://github.com/guillaumebreton/gone) is a CLI pomodoro® timer. + - [Spoof.go](https://github.com/sabey/spoofgo) controllable movement spoofing from the cli + - [lf](https://github.com/gokcehan/lf) is a terminal file manager + - [rat](https://github.com/ericfreese/rat) lets you compose shell commands to build terminal applications. + - [httplab](https://github.com/gchaincl/httplab) An interactive web server. + - [tetris](https://github.com/MichaelS11/tetris) Go Tetris with AI option + - [wot](https://github.com/kyu-suke/wot) Wait time during command is completed. + - [2048-go](https://github.com/1984weed/2048-go) is 2048 in Go + - [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line. + - [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST. + - [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements + - [zterm](https://github.com/varunrau/zterm) is a typing game inspired by http://zty.pe/ + +### API reference +[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go) diff --git a/vendor/github.com/nsf/termbox-go/api.go b/vendor/github.com/nsf/termbox-go/api.go new file mode 100644 index 0000000..d530ab5 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/api.go @@ -0,0 +1,489 @@ +// +build !windows + +package termbox + +import "github.com/mattn/go-runewidth" +import "fmt" +import "os" +import "os/signal" +import "syscall" +import "runtime" +import "time" + +// public API + +// Initializes termbox library. This function should be called before any other functions. +// After successful initialization, the library must be finalized using 'Close' function. +// +// Example usage: +// err := termbox.Init() +// if err != nil { +// panic(err) +// } +// defer termbox.Close() +func Init() error { + var err error + + out, err = os.OpenFile("/dev/tty", syscall.O_WRONLY, 0) + if err != nil { + return err + } + in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0) + if err != nil { + return err + } + + err = setup_term() + if err != nil { + return fmt.Errorf("termbox: error while reading terminfo data: %v", err) + } + + signal.Notify(sigwinch, syscall.SIGWINCH) + signal.Notify(sigio, syscall.SIGIO) + + _, err = fcntl(in, syscall.F_SETFL, syscall.O_ASYNC|syscall.O_NONBLOCK) + if err != nil { + return err + } + _, err = fcntl(in, syscall.F_SETOWN, syscall.Getpid()) + if runtime.GOOS != "darwin" && err != nil { + return err + } + err = tcgetattr(out.Fd(), &orig_tios) + if err != nil { + return err + } + + tios := orig_tios + tios.Iflag &^= syscall_IGNBRK | syscall_BRKINT | syscall_PARMRK | + syscall_ISTRIP | syscall_INLCR | syscall_IGNCR | + syscall_ICRNL | syscall_IXON + tios.Lflag &^= syscall_ECHO | syscall_ECHONL | syscall_ICANON | + syscall_ISIG | syscall_IEXTEN + tios.Cflag &^= syscall_CSIZE | syscall_PARENB + tios.Cflag |= syscall_CS8 + tios.Cc[syscall_VMIN] = 1 + tios.Cc[syscall_VTIME] = 0 + + err = tcsetattr(out.Fd(), &tios) + if err != nil { + return err + } + + out.WriteString(funcs[t_enter_ca]) + out.WriteString(funcs[t_enter_keypad]) + out.WriteString(funcs[t_hide_cursor]) + out.WriteString(funcs[t_clear_screen]) + + termw, termh = get_term_size(out.Fd()) + back_buffer.init(termw, termh) + front_buffer.init(termw, termh) + back_buffer.clear() + front_buffer.clear() + + go func() { + buf := make([]byte, 128) + for { + select { + case <-sigio: + for { + n, err := syscall.Read(in, buf) + if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK { + break + } + select { + case input_comm <- input_event{buf[:n], err}: + ie := <-input_comm + buf = ie.data[:128] + case <-quit: + return + } + } + case <-quit: + return + } + } + }() + + IsInit = true + return nil +} + +// Interrupt an in-progress call to PollEvent by causing it to return +// EventInterrupt. Note that this function will block until the PollEvent +// function has successfully been interrupted. +func Interrupt() { + interrupt_comm <- struct{}{} +} + +// Finalizes termbox library, should be called after successful initialization +// when termbox's functionality isn't required anymore. +func Close() { + quit <- 1 + out.WriteString(funcs[t_show_cursor]) + out.WriteString(funcs[t_sgr0]) + out.WriteString(funcs[t_clear_screen]) + out.WriteString(funcs[t_exit_ca]) + out.WriteString(funcs[t_exit_keypad]) + out.WriteString(funcs[t_exit_mouse]) + tcsetattr(out.Fd(), &orig_tios) + + out.Close() + syscall.Close(in) + + // reset the state, so that on next Init() it will work again + termw = 0 + termh = 0 + input_mode = InputEsc + out = nil + in = 0 + lastfg = attr_invalid + lastbg = attr_invalid + lastx = coord_invalid + lasty = coord_invalid + cursor_x = cursor_hidden + cursor_y = cursor_hidden + foreground = ColorDefault + background = ColorDefault + IsInit = false +} + +// Synchronizes the internal back buffer with the terminal. +func Flush() error { + // invalidate cursor position + lastx = coord_invalid + lasty = coord_invalid + + update_size_maybe() + + for y := 0; y < front_buffer.height; y++ { + line_offset := y * front_buffer.width + for x := 0; x < front_buffer.width; { + cell_offset := line_offset + x + back := &back_buffer.cells[cell_offset] + front := &front_buffer.cells[cell_offset] + if back.Ch < ' ' { + back.Ch = ' ' + } + w := runewidth.RuneWidth(back.Ch) + if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) { + w = 1 + } + if *back == *front { + x += w + continue + } + *front = *back + send_attr(back.Fg, back.Bg) + + if w == 2 && x == front_buffer.width-1 { + // there's not enough space for 2-cells rune, + // let's just put a space in there + send_char(x, y, ' ') + } else { + send_char(x, y, back.Ch) + if w == 2 { + next := cell_offset + 1 + front_buffer.cells[next] = Cell{ + Ch: 0, + Fg: back.Fg, + Bg: back.Bg, + } + } + } + x += w + } + } + if !is_cursor_hidden(cursor_x, cursor_y) { + write_cursor(cursor_x, cursor_y) + } + return flush() +} + +// Sets the position of the cursor. See also HideCursor(). +func SetCursor(x, y int) { + if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) { + outbuf.WriteString(funcs[t_show_cursor]) + } + + if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) { + outbuf.WriteString(funcs[t_hide_cursor]) + } + + cursor_x, cursor_y = x, y + if !is_cursor_hidden(cursor_x, cursor_y) { + write_cursor(cursor_x, cursor_y) + } +} + +// The shortcut for SetCursor(-1, -1). +func HideCursor() { + SetCursor(cursor_hidden, cursor_hidden) +} + +// Changes cell's parameters in the internal back buffer at the specified +// position. +func SetCell(x, y int, ch rune, fg, bg Attribute) { + if x < 0 || x >= back_buffer.width { + return + } + if y < 0 || y >= back_buffer.height { + return + } + + back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg} +} + +// Returns a slice into the termbox's back buffer. You can get its dimensions +// using 'Size' function. The slice remains valid as long as no 'Clear' or +// 'Flush' function calls were made after call to this function. +func CellBuffer() []Cell { + return back_buffer.cells +} + +// After getting a raw event from PollRawEvent function call, you can parse it +// again into an ordinary one using termbox logic. That is parse an event as +// termbox would do it. Returned event in addition to usual Event struct fields +// sets N field to the amount of bytes used within 'data' slice. If the length +// of 'data' slice is zero or event cannot be parsed for some other reason, the +// function will return a special event type: EventNone. +// +// IMPORTANT: EventNone may contain a non-zero N, which means you should skip +// these bytes, because termbox cannot recognize them. +// +// NOTE: This API is experimental and may change in future. +func ParseEvent(data []byte) Event { + event := Event{Type: EventKey} + status := extract_event(data, &event, false) + if status != event_extracted { + return Event{Type: EventNone, N: event.N} + } + return event +} + +// Wait for an event and return it. This is a blocking function call. Instead +// of EventKey and EventMouse it returns EventRaw events. Raw event is written +// into `data` slice and Event's N field is set to the amount of bytes written. +// The minimum required length of the 'data' slice is 1. This requirement may +// vary on different platforms. +// +// NOTE: This API is experimental and may change in future. +func PollRawEvent(data []byte) Event { + if len(data) == 0 { + panic("len(data) >= 1 is a requirement") + } + + var event Event + if extract_raw_event(data, &event) { + return event + } + + for { + select { + case ev := <-input_comm: + if ev.err != nil { + return Event{Type: EventError, Err: ev.err} + } + + inbuf = append(inbuf, ev.data...) + input_comm <- ev + if extract_raw_event(data, &event) { + return event + } + case <-interrupt_comm: + event.Type = EventInterrupt + return event + + case <-sigwinch: + event.Type = EventResize + event.Width, event.Height = get_term_size(out.Fd()) + return event + } + } +} + +// Wait for an event and return it. This is a blocking function call. +func PollEvent() Event { + // Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132 + // This is an arbitrary delay which hopefully will be enough time for any lagging + // partial escape sequences to come through. + const esc_wait_delay = 100 * time.Millisecond + + var event Event + var esc_wait_timer *time.Timer + var esc_timeout <-chan time.Time + + // try to extract event from input buffer, return on success + event.Type = EventKey + status := extract_event(inbuf, &event, true) + if event.N != 0 { + copy(inbuf, inbuf[event.N:]) + inbuf = inbuf[:len(inbuf)-event.N] + } + if status == event_extracted { + return event + } else if status == esc_wait { + esc_wait_timer = time.NewTimer(esc_wait_delay) + esc_timeout = esc_wait_timer.C + } + + for { + select { + case ev := <-input_comm: + if esc_wait_timer != nil { + if !esc_wait_timer.Stop() { + <-esc_wait_timer.C + } + esc_wait_timer = nil + } + + if ev.err != nil { + return Event{Type: EventError, Err: ev.err} + } + + inbuf = append(inbuf, ev.data...) + input_comm <- ev + status := extract_event(inbuf, &event, true) + if event.N != 0 { + copy(inbuf, inbuf[event.N:]) + inbuf = inbuf[:len(inbuf)-event.N] + } + if status == event_extracted { + return event + } else if status == esc_wait { + esc_wait_timer = time.NewTimer(esc_wait_delay) + esc_timeout = esc_wait_timer.C + } + case <-esc_timeout: + esc_wait_timer = nil + + status := extract_event(inbuf, &event, false) + if event.N != 0 { + copy(inbuf, inbuf[event.N:]) + inbuf = inbuf[:len(inbuf)-event.N] + } + if status == event_extracted { + return event + } + case <-interrupt_comm: + event.Type = EventInterrupt + return event + + case <-sigwinch: + event.Type = EventResize + event.Width, event.Height = get_term_size(out.Fd()) + return event + } + } +} + +// Returns the size of the internal back buffer (which is mostly the same as +// terminal's window size in characters). But it doesn't always match the size +// of the terminal window, after the terminal size has changed, the internal +// back buffer will get in sync only after Clear or Flush function calls. +func Size() (width int, height int) { + return termw, termh +} + +// Clears the internal back buffer. +func Clear(fg, bg Attribute) error { + foreground, background = fg, bg + err := update_size_maybe() + back_buffer.clear() + return err +} + +// Sets termbox input mode. Termbox has two input modes: +// +// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match +// any known sequence. ESC means KeyEsc. This is the default input mode. +// +// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match +// any known sequence. ESC enables ModAlt modifier for the next keyboard event. +// +// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will +// enable mouse button press/release and drag events. +// +// If 'mode' is InputCurrent, returns the current input mode. See also Input* +// constants. +func SetInputMode(mode InputMode) InputMode { + if mode == InputCurrent { + return input_mode + } + if mode&(InputEsc|InputAlt) == 0 { + mode |= InputEsc + } + if mode&(InputEsc|InputAlt) == InputEsc|InputAlt { + mode &^= InputAlt + } + if mode&InputMouse != 0 { + out.WriteString(funcs[t_enter_mouse]) + } else { + out.WriteString(funcs[t_exit_mouse]) + } + + input_mode = mode + return input_mode +} + +// Sets the termbox output mode. Termbox has four output options: +// +// 1. OutputNormal => [1..8] +// This mode provides 8 different colors: +// black, red, green, yellow, blue, magenta, cyan, white +// Shortcut: ColorBlack, ColorRed, ... +// Attributes: AttrBold, AttrUnderline, AttrReverse +// +// Example usage: +// SetCell(x, y, '@', ColorBlack | AttrBold, ColorRed); +// +// 2. Output256 => [1..256] +// In this mode you can leverage the 256 terminal mode: +// 0x01 - 0x08: the 8 colors as in OutputNormal +// 0x09 - 0x10: Color* | AttrBold +// 0x11 - 0xe8: 216 different colors +// 0xe9 - 0x1ff: 24 different shades of grey +// +// Example usage: +// SetCell(x, y, '@', 184, 240); +// SetCell(x, y, '@', 0xb8, 0xf0); +// +// 3. Output216 => [1..216] +// This mode supports the 3rd range of the 256 mode only. +// But you don't need to provide an offset. +// +// 4. OutputGrayscale => [1..26] +// This mode supports the 4th range of the 256 mode +// and black and white colors from 3th range of the 256 mode +// But you don't need to provide an offset. +// +// In all modes, 0x00 represents the default color. +// +// `go run _demos/output.go` to see its impact on your terminal. +// +// If 'mode' is OutputCurrent, it returns the current output mode. +// +// Note that this may return a different OutputMode than the one requested, +// as the requested mode may not be available on the target platform. +func SetOutputMode(mode OutputMode) OutputMode { + if mode == OutputCurrent { + return output_mode + } + + output_mode = mode + return output_mode +} + +// Sync comes handy when something causes desync between termbox's understanding +// of a terminal buffer and the reality. Such as a third party process. Sync +// forces a complete resync between the termbox and a terminal, it may not be +// visually pretty though. +func Sync() error { + front_buffer.clear() + err := send_clear() + if err != nil { + return err + } + + return Flush() +} diff --git a/vendor/github.com/nsf/termbox-go/api_common.go b/vendor/github.com/nsf/termbox-go/api_common.go new file mode 100644 index 0000000..5ca1371 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/api_common.go @@ -0,0 +1,187 @@ +// termbox is a library for creating cross-platform text-based interfaces +package termbox + +// public API, common OS agnostic part + +type ( + InputMode int + OutputMode int + EventType uint8 + Modifier uint8 + Key uint16 + Attribute uint16 +) + +// This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are +// valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if +// 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError. +type Event struct { + Type EventType // one of Event* constants + Mod Modifier // one of Mod* constants or 0 + Key Key // one of Key* constants, invalid if 'Ch' is not 0 + Ch rune // a unicode character + Width int // width of the screen + Height int // height of the screen + Err error // error in case if input failed + MouseX int // x coord of mouse + MouseY int // y coord of mouse + N int // number of bytes written when getting a raw event +} + +// A cell, single conceptual entity on the screen. The screen is basically a 2d +// array of cells. 'Ch' is a unicode character, 'Fg' and 'Bg' are foreground +// and background attributes respectively. +type Cell struct { + Ch rune + Fg Attribute + Bg Attribute +} + +// To know if termbox has been initialized or not +var ( + IsInit bool = false +) + +// Key constants, see Event.Key field. +const ( + KeyF1 Key = 0xFFFF - iota + KeyF2 + KeyF3 + KeyF4 + KeyF5 + KeyF6 + KeyF7 + KeyF8 + KeyF9 + KeyF10 + KeyF11 + KeyF12 + KeyInsert + KeyDelete + KeyHome + KeyEnd + KeyPgup + KeyPgdn + KeyArrowUp + KeyArrowDown + KeyArrowLeft + KeyArrowRight + key_min // see terminfo + MouseLeft + MouseMiddle + MouseRight + MouseRelease + MouseWheelUp + MouseWheelDown +) + +const ( + KeyCtrlTilde Key = 0x00 + KeyCtrl2 Key = 0x00 + KeyCtrlSpace Key = 0x00 + KeyCtrlA Key = 0x01 + KeyCtrlB Key = 0x02 + KeyCtrlC Key = 0x03 + KeyCtrlD Key = 0x04 + KeyCtrlE Key = 0x05 + KeyCtrlF Key = 0x06 + KeyCtrlG Key = 0x07 + KeyBackspace Key = 0x08 + KeyCtrlH Key = 0x08 + KeyTab Key = 0x09 + KeyCtrlI Key = 0x09 + KeyCtrlJ Key = 0x0A + KeyCtrlK Key = 0x0B + KeyCtrlL Key = 0x0C + KeyEnter Key = 0x0D + KeyCtrlM Key = 0x0D + KeyCtrlN Key = 0x0E + KeyCtrlO Key = 0x0F + KeyCtrlP Key = 0x10 + KeyCtrlQ Key = 0x11 + KeyCtrlR Key = 0x12 + KeyCtrlS Key = 0x13 + KeyCtrlT Key = 0x14 + KeyCtrlU Key = 0x15 + KeyCtrlV Key = 0x16 + KeyCtrlW Key = 0x17 + KeyCtrlX Key = 0x18 + KeyCtrlY Key = 0x19 + KeyCtrlZ Key = 0x1A + KeyEsc Key = 0x1B + KeyCtrlLsqBracket Key = 0x1B + KeyCtrl3 Key = 0x1B + KeyCtrl4 Key = 0x1C + KeyCtrlBackslash Key = 0x1C + KeyCtrl5 Key = 0x1D + KeyCtrlRsqBracket Key = 0x1D + KeyCtrl6 Key = 0x1E + KeyCtrl7 Key = 0x1F + KeyCtrlSlash Key = 0x1F + KeyCtrlUnderscore Key = 0x1F + KeySpace Key = 0x20 + KeyBackspace2 Key = 0x7F + KeyCtrl8 Key = 0x7F +) + +// Alt modifier constant, see Event.Mod field and SetInputMode function. +const ( + ModAlt Modifier = 1 << iota + ModMotion +) + +// Cell colors, you can combine a color with multiple attributes using bitwise +// OR ('|'). +const ( + ColorDefault Attribute = iota + ColorBlack + ColorRed + ColorGreen + ColorYellow + ColorBlue + ColorMagenta + ColorCyan + ColorWhite +) + +// Cell attributes, it is possible to use multiple attributes by combining them +// using bitwise OR ('|'). Although, colors cannot be combined. But you can +// combine attributes and a single color. +// +// It's worth mentioning that some platforms don't support certain attributes. +// For example windows console doesn't support AttrUnderline. And on some +// terminals applying AttrBold to background may result in blinking text. Use +// them with caution and test your code on various terminals. +const ( + AttrBold Attribute = 1 << (iota + 9) + AttrUnderline + AttrReverse +) + +// Input mode. See SetInputMode function. +const ( + InputEsc InputMode = 1 << iota + InputAlt + InputMouse + InputCurrent InputMode = 0 +) + +// Output mode. See SetOutputMode function. +const ( + OutputCurrent OutputMode = iota + OutputNormal + Output256 + Output216 + OutputGrayscale +) + +// Event type. See Event.Type field. +const ( + EventKey EventType = iota + EventResize + EventMouse + EventError + EventInterrupt + EventRaw + EventNone +) diff --git a/vendor/github.com/nsf/termbox-go/api_windows.go b/vendor/github.com/nsf/termbox-go/api_windows.go new file mode 100644 index 0000000..7def30a --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/api_windows.go @@ -0,0 +1,239 @@ +package termbox + +import ( + "syscall" +) + +// public API + +// Initializes termbox library. This function should be called before any other functions. +// After successful initialization, the library must be finalized using 'Close' function. +// +// Example usage: +// err := termbox.Init() +// if err != nil { +// panic(err) +// } +// defer termbox.Close() +func Init() error { + var err error + + interrupt, err = create_event() + if err != nil { + return err + } + + in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0) + if err != nil { + return err + } + out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0) + if err != nil { + return err + } + + err = get_console_mode(in, &orig_mode) + if err != nil { + return err + } + + err = set_console_mode(in, enable_window_input) + if err != nil { + return err + } + + orig_size = get_term_size(out) + win_size := get_win_size(out) + + err = set_console_screen_buffer_size(out, win_size) + if err != nil { + return err + } + + err = get_console_cursor_info(out, &orig_cursor_info) + if err != nil { + return err + } + + show_cursor(false) + term_size = get_term_size(out) + back_buffer.init(int(term_size.x), int(term_size.y)) + front_buffer.init(int(term_size.x), int(term_size.y)) + back_buffer.clear() + front_buffer.clear() + clear() + + diffbuf = make([]diff_msg, 0, 32) + + go input_event_producer() + IsInit = true + return nil +} + +// Finalizes termbox library, should be called after successful initialization +// when termbox's functionality isn't required anymore. +func Close() { + // we ignore errors here, because we can't really do anything about them + Clear(0, 0) + Flush() + + // stop event producer + cancel_comm <- true + set_event(interrupt) + select { + case <-input_comm: + default: + } + <-cancel_done_comm + + set_console_cursor_info(out, &orig_cursor_info) + set_console_cursor_position(out, coord{}) + set_console_screen_buffer_size(out, orig_size) + set_console_mode(in, orig_mode) + syscall.Close(in) + syscall.Close(out) + syscall.Close(interrupt) + IsInit = false +} + +// Interrupt an in-progress call to PollEvent by causing it to return +// EventInterrupt. Note that this function will block until the PollEvent +// function has successfully been interrupted. +func Interrupt() { + interrupt_comm <- struct{}{} +} + +// Synchronizes the internal back buffer with the terminal. +func Flush() error { + update_size_maybe() + prepare_diff_messages() + for _, diff := range diffbuf { + r := small_rect{ + left: 0, + top: diff.pos, + right: term_size.x - 1, + bottom: diff.pos + diff.lines - 1, + } + write_console_output(out, diff.chars, r) + } + if !is_cursor_hidden(cursor_x, cursor_y) { + move_cursor(cursor_x, cursor_y) + } + return nil +} + +// Sets the position of the cursor. See also HideCursor(). +func SetCursor(x, y int) { + if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) { + show_cursor(true) + } + + if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) { + show_cursor(false) + } + + cursor_x, cursor_y = x, y + if !is_cursor_hidden(cursor_x, cursor_y) { + move_cursor(cursor_x, cursor_y) + } +} + +// The shortcut for SetCursor(-1, -1). +func HideCursor() { + SetCursor(cursor_hidden, cursor_hidden) +} + +// Changes cell's parameters in the internal back buffer at the specified +// position. +func SetCell(x, y int, ch rune, fg, bg Attribute) { + if x < 0 || x >= back_buffer.width { + return + } + if y < 0 || y >= back_buffer.height { + return + } + + back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg} +} + +// Returns a slice into the termbox's back buffer. You can get its dimensions +// using 'Size' function. The slice remains valid as long as no 'Clear' or +// 'Flush' function calls were made after call to this function. +func CellBuffer() []Cell { + return back_buffer.cells +} + +// Wait for an event and return it. This is a blocking function call. +func PollEvent() Event { + select { + case ev := <-input_comm: + return ev + case <-interrupt_comm: + return Event{Type: EventInterrupt} + } +} + +// Returns the size of the internal back buffer (which is mostly the same as +// console's window size in characters). But it doesn't always match the size +// of the console window, after the console size has changed, the internal back +// buffer will get in sync only after Clear or Flush function calls. +func Size() (int, int) { + return int(term_size.x), int(term_size.y) +} + +// Clears the internal back buffer. +func Clear(fg, bg Attribute) error { + foreground, background = fg, bg + update_size_maybe() + back_buffer.clear() + return nil +} + +// Sets termbox input mode. Termbox has two input modes: +// +// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match +// any known sequence. ESC means KeyEsc. This is the default input mode. +// +// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match +// any known sequence. ESC enables ModAlt modifier for the next keyboard event. +// +// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will +// enable mouse button press/release and drag events. +// +// If 'mode' is InputCurrent, returns the current input mode. See also Input* +// constants. +func SetInputMode(mode InputMode) InputMode { + if mode == InputCurrent { + return input_mode + } + if mode&InputMouse != 0 { + err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags) + if err != nil { + panic(err) + } + } else { + err := set_console_mode(in, enable_window_input) + if err != nil { + panic(err) + } + } + + input_mode = mode + return input_mode +} + +// Sets the termbox output mode. +// +// Windows console does not support extra colour modes, +// so this will always set and return OutputNormal. +func SetOutputMode(mode OutputMode) OutputMode { + return OutputNormal +} + +// Sync comes handy when something causes desync between termbox's understanding +// of a terminal buffer and the reality. Such as a third party process. Sync +// forces a complete resync between the termbox and a terminal, it may not be +// visually pretty though. At the moment on Windows it does nothing. +func Sync() error { + return nil +} diff --git a/vendor/github.com/nsf/termbox-go/collect_terminfo.py b/vendor/github.com/nsf/termbox-go/collect_terminfo.py new file mode 100755 index 0000000..5e50975 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/collect_terminfo.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python + +import sys, os, subprocess + +def escaped(s): + return repr(s)[1:-1] + +def tput(term, name): + try: + return subprocess.check_output(['tput', '-T%s' % term, name]).decode() + except subprocess.CalledProcessError as e: + return e.output.decode() + + +def w(s): + if s == None: + return + sys.stdout.write(s) + +terminals = { + 'xterm' : 'xterm', + 'rxvt-256color' : 'rxvt_256color', + 'rxvt-unicode' : 'rxvt_unicode', + 'linux' : 'linux', + 'Eterm' : 'eterm', + 'screen' : 'screen' +} + +keys = [ + "F1", "kf1", + "F2", "kf2", + "F3", "kf3", + "F4", "kf4", + "F5", "kf5", + "F6", "kf6", + "F7", "kf7", + "F8", "kf8", + "F9", "kf9", + "F10", "kf10", + "F11", "kf11", + "F12", "kf12", + "INSERT", "kich1", + "DELETE", "kdch1", + "HOME", "khome", + "END", "kend", + "PGUP", "kpp", + "PGDN", "knp", + "KEY_UP", "kcuu1", + "KEY_DOWN", "kcud1", + "KEY_LEFT", "kcub1", + "KEY_RIGHT", "kcuf1" +] + +funcs = [ + "T_ENTER_CA", "smcup", + "T_EXIT_CA", "rmcup", + "T_SHOW_CURSOR", "cnorm", + "T_HIDE_CURSOR", "civis", + "T_CLEAR_SCREEN", "clear", + "T_SGR0", "sgr0", + "T_UNDERLINE", "smul", + "T_BOLD", "bold", + "T_BLINK", "blink", + "T_REVERSE", "rev", + "T_ENTER_KEYPAD", "smkx", + "T_EXIT_KEYPAD", "rmkx" +] + +def iter_pairs(iterable): + iterable = iter(iterable) + while True: + yield (next(iterable), next(iterable)) + +def do_term(term, nick): + w("// %s\n" % term) + w("var %s_keys = []string{\n\t" % nick) + for k, v in iter_pairs(keys): + w('"') + w(escaped(tput(term, v))) + w('",') + w("\n}\n") + w("var %s_funcs = []string{\n\t" % nick) + for k,v in iter_pairs(funcs): + w('"') + if v == "sgr": + w("\\033[3%d;4%dm") + elif v == "cup": + w("\\033[%d;%dH") + else: + w(escaped(tput(term, v))) + w('", ') + w("\n}\n\n") + +def do_terms(d): + w("var terms = []struct {\n") + w("\tname string\n") + w("\tkeys []string\n") + w("\tfuncs []string\n") + w("}{\n") + for k, v in d.items(): + w('\t{"%s", %s_keys, %s_funcs},\n' % (k, v, v)) + w("}\n\n") + +w("// +build !windows\n\npackage termbox\n\n") + +for k,v in terminals.items(): + do_term(k, v) + +do_terms(terminals) + diff --git a/vendor/github.com/nsf/termbox-go/escwait.go b/vendor/github.com/nsf/termbox-go/escwait.go new file mode 100644 index 0000000..b7bbb89 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/escwait.go @@ -0,0 +1,11 @@ +// +build !darwin + +package termbox + +// On all systems other than macOS, disable behavior which will wait before +// deciding that the escape key was pressed, to account for partially send +// escape sequences, especially with regard to lengthy mouse sequences. +// See https://github.com/nsf/termbox-go/issues/132 +func enable_wait_for_escape_sequence() bool { + return false +} diff --git a/vendor/github.com/nsf/termbox-go/escwait_darwin.go b/vendor/github.com/nsf/termbox-go/escwait_darwin.go new file mode 100644 index 0000000..dde69b6 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/escwait_darwin.go @@ -0,0 +1,9 @@ +package termbox + +// On macOS, enable behavior which will wait before deciding that the escape +// key was pressed, to account for partially send escape sequences, especially +// with regard to lengthy mouse sequences. +// See https://github.com/nsf/termbox-go/issues/132 +func enable_wait_for_escape_sequence() bool { + return true +} diff --git a/vendor/github.com/nsf/termbox-go/syscalls.go b/vendor/github.com/nsf/termbox-go/syscalls.go new file mode 100644 index 0000000..4f52bb9 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls.go @@ -0,0 +1,39 @@ +// +build ignore + +package termbox + +/* +#include +#include +*/ +import "C" + +type syscall_Termios C.struct_termios + +const ( + syscall_IGNBRK = C.IGNBRK + syscall_BRKINT = C.BRKINT + syscall_PARMRK = C.PARMRK + syscall_ISTRIP = C.ISTRIP + syscall_INLCR = C.INLCR + syscall_IGNCR = C.IGNCR + syscall_ICRNL = C.ICRNL + syscall_IXON = C.IXON + syscall_OPOST = C.OPOST + syscall_ECHO = C.ECHO + syscall_ECHONL = C.ECHONL + syscall_ICANON = C.ICANON + syscall_ISIG = C.ISIG + syscall_IEXTEN = C.IEXTEN + syscall_CSIZE = C.CSIZE + syscall_PARENB = C.PARENB + syscall_CS8 = C.CS8 + syscall_VMIN = C.VMIN + syscall_VTIME = C.VTIME + + // on darwin change these to (on *bsd too?): + // C.TIOCGETA + // C.TIOCSETA + syscall_TCGETS = C.TCGETS + syscall_TCSETS = C.TCSETS +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_darwin.go b/vendor/github.com/nsf/termbox-go/syscalls_darwin.go new file mode 100644 index 0000000..25b78f7 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_darwin.go @@ -0,0 +1,41 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +// +build !amd64 + +package termbox + +type syscall_Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed uint32 + Ospeed uint32 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x402c7413 + syscall_TCSETS = 0x802c7414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go b/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go new file mode 100644 index 0000000..11f25be --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go @@ -0,0 +1,40 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +type syscall_Termios struct { + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]uint8 + Pad_cgo_0 [4]byte + Ispeed uint64 + Ospeed uint64 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x40487413 + syscall_TCSETS = 0x80487414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go b/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go new file mode 100644 index 0000000..e03624e --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go @@ -0,0 +1,39 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +type syscall_Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed uint32 + Ospeed uint32 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x402c7413 + syscall_TCSETS = 0x802c7414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go b/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go new file mode 100644 index 0000000..e03624e --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go @@ -0,0 +1,39 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +type syscall_Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed uint32 + Ospeed uint32 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x402c7413 + syscall_TCSETS = 0x802c7414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_linux.go b/vendor/github.com/nsf/termbox-go/syscalls_linux.go new file mode 100644 index 0000000..b88960d --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_linux.go @@ -0,0 +1,33 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +import "syscall" + +type syscall_Termios syscall.Termios + +const ( + syscall_IGNBRK = syscall.IGNBRK + syscall_BRKINT = syscall.BRKINT + syscall_PARMRK = syscall.PARMRK + syscall_ISTRIP = syscall.ISTRIP + syscall_INLCR = syscall.INLCR + syscall_IGNCR = syscall.IGNCR + syscall_ICRNL = syscall.ICRNL + syscall_IXON = syscall.IXON + syscall_OPOST = syscall.OPOST + syscall_ECHO = syscall.ECHO + syscall_ECHONL = syscall.ECHONL + syscall_ICANON = syscall.ICANON + syscall_ISIG = syscall.ISIG + syscall_IEXTEN = syscall.IEXTEN + syscall_CSIZE = syscall.CSIZE + syscall_PARENB = syscall.PARENB + syscall_CS8 = syscall.CS8 + syscall_VMIN = syscall.VMIN + syscall_VTIME = syscall.VTIME + + syscall_TCGETS = syscall.TCGETS + syscall_TCSETS = syscall.TCSETS +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go b/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go new file mode 100644 index 0000000..49a3355 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go @@ -0,0 +1,39 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +type syscall_Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x402c7413 + syscall_TCSETS = 0x802c7414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go b/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go new file mode 100644 index 0000000..49a3355 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go @@ -0,0 +1,39 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs syscalls.go + +package termbox + +type syscall_Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed int32 + Ospeed int32 +} + +const ( + syscall_IGNBRK = 0x1 + syscall_BRKINT = 0x2 + syscall_PARMRK = 0x8 + syscall_ISTRIP = 0x20 + syscall_INLCR = 0x40 + syscall_IGNCR = 0x80 + syscall_ICRNL = 0x100 + syscall_IXON = 0x200 + syscall_OPOST = 0x1 + syscall_ECHO = 0x8 + syscall_ECHONL = 0x10 + syscall_ICANON = 0x100 + syscall_ISIG = 0x80 + syscall_IEXTEN = 0x400 + syscall_CSIZE = 0x300 + syscall_PARENB = 0x1000 + syscall_CS8 = 0x300 + syscall_VMIN = 0x10 + syscall_VTIME = 0x11 + + syscall_TCGETS = 0x402c7413 + syscall_TCSETS = 0x802c7414 +) diff --git a/vendor/github.com/nsf/termbox-go/syscalls_windows.go b/vendor/github.com/nsf/termbox-go/syscalls_windows.go new file mode 100644 index 0000000..472d002 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/syscalls_windows.go @@ -0,0 +1,61 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs -- -DUNICODE syscalls.go + +package termbox + +const ( + foreground_blue = 0x1 + foreground_green = 0x2 + foreground_red = 0x4 + foreground_intensity = 0x8 + background_blue = 0x10 + background_green = 0x20 + background_red = 0x40 + background_intensity = 0x80 + std_input_handle = -0xa + std_output_handle = -0xb + key_event = 0x1 + mouse_event = 0x2 + window_buffer_size_event = 0x4 + enable_window_input = 0x8 + enable_mouse_input = 0x10 + enable_extended_flags = 0x80 + + vk_f1 = 0x70 + vk_f2 = 0x71 + vk_f3 = 0x72 + vk_f4 = 0x73 + vk_f5 = 0x74 + vk_f6 = 0x75 + vk_f7 = 0x76 + vk_f8 = 0x77 + vk_f9 = 0x78 + vk_f10 = 0x79 + vk_f11 = 0x7a + vk_f12 = 0x7b + vk_insert = 0x2d + vk_delete = 0x2e + vk_home = 0x24 + vk_end = 0x23 + vk_pgup = 0x21 + vk_pgdn = 0x22 + vk_arrow_up = 0x26 + vk_arrow_down = 0x28 + vk_arrow_left = 0x25 + vk_arrow_right = 0x27 + vk_backspace = 0x8 + vk_tab = 0x9 + vk_enter = 0xd + vk_esc = 0x1b + vk_space = 0x20 + + left_alt_pressed = 0x2 + left_ctrl_pressed = 0x8 + right_alt_pressed = 0x1 + right_ctrl_pressed = 0x4 + shift_pressed = 0x10 + + generic_read = 0x80000000 + generic_write = 0x40000000 + console_textmode_buffer = 0x1 +) diff --git a/vendor/github.com/nsf/termbox-go/termbox.go b/vendor/github.com/nsf/termbox-go/termbox.go new file mode 100644 index 0000000..fbe4c3d --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/termbox.go @@ -0,0 +1,529 @@ +// +build !windows + +package termbox + +import "unicode/utf8" +import "bytes" +import "syscall" +import "unsafe" +import "strings" +import "strconv" +import "os" +import "io" + +// private API + +const ( + t_enter_ca = iota + t_exit_ca + t_show_cursor + t_hide_cursor + t_clear_screen + t_sgr0 + t_underline + t_bold + t_blink + t_reverse + t_enter_keypad + t_exit_keypad + t_enter_mouse + t_exit_mouse + t_max_funcs +) + +const ( + coord_invalid = -2 + attr_invalid = Attribute(0xFFFF) +) + +type input_event struct { + data []byte + err error +} + +type extract_event_res int + +const ( + event_not_extracted extract_event_res = iota + event_extracted + esc_wait +) + +var ( + // term specific sequences + keys []string + funcs []string + + // termbox inner state + orig_tios syscall_Termios + back_buffer cellbuf + front_buffer cellbuf + termw int + termh int + input_mode = InputEsc + output_mode = OutputNormal + out *os.File + in int + lastfg = attr_invalid + lastbg = attr_invalid + lastx = coord_invalid + lasty = coord_invalid + cursor_x = cursor_hidden + cursor_y = cursor_hidden + foreground = ColorDefault + background = ColorDefault + inbuf = make([]byte, 0, 64) + outbuf bytes.Buffer + sigwinch = make(chan os.Signal, 1) + sigio = make(chan os.Signal, 1) + quit = make(chan int) + input_comm = make(chan input_event) + interrupt_comm = make(chan struct{}) + intbuf = make([]byte, 0, 16) + + // grayscale indexes + grayscale = []Attribute{ + 0, 17, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 232, + } +) + +func write_cursor(x, y int) { + outbuf.WriteString("\033[") + outbuf.Write(strconv.AppendUint(intbuf, uint64(y+1), 10)) + outbuf.WriteString(";") + outbuf.Write(strconv.AppendUint(intbuf, uint64(x+1), 10)) + outbuf.WriteString("H") +} + +func write_sgr_fg(a Attribute) { + switch output_mode { + case Output256, Output216, OutputGrayscale: + outbuf.WriteString("\033[38;5;") + outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) + outbuf.WriteString("m") + default: + outbuf.WriteString("\033[3") + outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) + outbuf.WriteString("m") + } +} + +func write_sgr_bg(a Attribute) { + switch output_mode { + case Output256, Output216, OutputGrayscale: + outbuf.WriteString("\033[48;5;") + outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) + outbuf.WriteString("m") + default: + outbuf.WriteString("\033[4") + outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) + outbuf.WriteString("m") + } +} + +func write_sgr(fg, bg Attribute) { + switch output_mode { + case Output256, Output216, OutputGrayscale: + outbuf.WriteString("\033[38;5;") + outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10)) + outbuf.WriteString("m") + outbuf.WriteString("\033[48;5;") + outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10)) + outbuf.WriteString("m") + default: + outbuf.WriteString("\033[3") + outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10)) + outbuf.WriteString(";4") + outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10)) + outbuf.WriteString("m") + } +} + +type winsize struct { + rows uint16 + cols uint16 + xpixels uint16 + ypixels uint16 +} + +func get_term_size(fd uintptr) (int, int) { + var sz winsize + _, _, _ = syscall.Syscall(syscall.SYS_IOCTL, + fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz))) + return int(sz.cols), int(sz.rows) +} + +func send_attr(fg, bg Attribute) { + if fg == lastfg && bg == lastbg { + return + } + + outbuf.WriteString(funcs[t_sgr0]) + + var fgcol, bgcol Attribute + + switch output_mode { + case Output256: + fgcol = fg & 0x1FF + bgcol = bg & 0x1FF + case Output216: + fgcol = fg & 0xFF + bgcol = bg & 0xFF + if fgcol > 216 { + fgcol = ColorDefault + } + if bgcol > 216 { + bgcol = ColorDefault + } + if fgcol != ColorDefault { + fgcol += 0x10 + } + if bgcol != ColorDefault { + bgcol += 0x10 + } + case OutputGrayscale: + fgcol = fg & 0x1F + bgcol = bg & 0x1F + if fgcol > 26 { + fgcol = ColorDefault + } + if bgcol > 26 { + bgcol = ColorDefault + } + if fgcol != ColorDefault { + fgcol = grayscale[fgcol] + } + if bgcol != ColorDefault { + bgcol = grayscale[bgcol] + } + default: + fgcol = fg & 0x0F + bgcol = bg & 0x0F + } + + if fgcol != ColorDefault { + if bgcol != ColorDefault { + write_sgr(fgcol, bgcol) + } else { + write_sgr_fg(fgcol) + } + } else if bgcol != ColorDefault { + write_sgr_bg(bgcol) + } + + if fg&AttrBold != 0 { + outbuf.WriteString(funcs[t_bold]) + } + if bg&AttrBold != 0 { + outbuf.WriteString(funcs[t_blink]) + } + if fg&AttrUnderline != 0 { + outbuf.WriteString(funcs[t_underline]) + } + if fg&AttrReverse|bg&AttrReverse != 0 { + outbuf.WriteString(funcs[t_reverse]) + } + + lastfg, lastbg = fg, bg +} + +func send_char(x, y int, ch rune) { + var buf [8]byte + n := utf8.EncodeRune(buf[:], ch) + if x-1 != lastx || y != lasty { + write_cursor(x, y) + } + lastx, lasty = x, y + outbuf.Write(buf[:n]) +} + +func flush() error { + _, err := io.Copy(out, &outbuf) + outbuf.Reset() + return err +} + +func send_clear() error { + send_attr(foreground, background) + outbuf.WriteString(funcs[t_clear_screen]) + if !is_cursor_hidden(cursor_x, cursor_y) { + write_cursor(cursor_x, cursor_y) + } + + // we need to invalidate cursor position too and these two vars are + // used only for simple cursor positioning optimization, cursor + // actually may be in the correct place, but we simply discard + // optimization once and it gives us simple solution for the case when + // cursor moved + lastx = coord_invalid + lasty = coord_invalid + + return flush() +} + +func update_size_maybe() error { + w, h := get_term_size(out.Fd()) + if w != termw || h != termh { + termw, termh = w, h + back_buffer.resize(termw, termh) + front_buffer.resize(termw, termh) + front_buffer.clear() + return send_clear() + } + return nil +} + +func tcsetattr(fd uintptr, termios *syscall_Termios) error { + r, _, e := syscall.Syscall(syscall.SYS_IOCTL, + fd, uintptr(syscall_TCSETS), uintptr(unsafe.Pointer(termios))) + if r != 0 { + return os.NewSyscallError("SYS_IOCTL", e) + } + return nil +} + +func tcgetattr(fd uintptr, termios *syscall_Termios) error { + r, _, e := syscall.Syscall(syscall.SYS_IOCTL, + fd, uintptr(syscall_TCGETS), uintptr(unsafe.Pointer(termios))) + if r != 0 { + return os.NewSyscallError("SYS_IOCTL", e) + } + return nil +} + +func parse_mouse_event(event *Event, buf string) (int, bool) { + if strings.HasPrefix(buf, "\033[M") && len(buf) >= 6 { + // X10 mouse encoding, the simplest one + // \033 [ M Cb Cx Cy + b := buf[3] - 32 + switch b & 3 { + case 0: + if b&64 != 0 { + event.Key = MouseWheelUp + } else { + event.Key = MouseLeft + } + case 1: + if b&64 != 0 { + event.Key = MouseWheelDown + } else { + event.Key = MouseMiddle + } + case 2: + event.Key = MouseRight + case 3: + event.Key = MouseRelease + default: + return 6, false + } + event.Type = EventMouse // KeyEvent by default + if b&32 != 0 { + event.Mod |= ModMotion + } + + // the coord is 1,1 for upper left + event.MouseX = int(buf[4]) - 1 - 32 + event.MouseY = int(buf[5]) - 1 - 32 + return 6, true + } else if strings.HasPrefix(buf, "\033[<") || strings.HasPrefix(buf, "\033[") { + // xterm 1006 extended mode or urxvt 1015 extended mode + // xterm: \033 [ < Cb ; Cx ; Cy (M or m) + // urxvt: \033 [ Cb ; Cx ; Cy M + + // find the first M or m, that's where we stop + mi := strings.IndexAny(buf, "Mm") + if mi == -1 { + return 0, false + } + + // whether it's a capital M or not + isM := buf[mi] == 'M' + + // whether it's urxvt or not + isU := false + + // buf[2] is safe here, because having M or m found means we have at + // least 3 bytes in a string + if buf[2] == '<' { + buf = buf[3:mi] + } else { + isU = true + buf = buf[2:mi] + } + + s1 := strings.Index(buf, ";") + s2 := strings.LastIndex(buf, ";") + // not found or only one ';' + if s1 == -1 || s2 == -1 || s1 == s2 { + return 0, false + } + + n1, err := strconv.ParseInt(buf[0:s1], 10, 64) + if err != nil { + return 0, false + } + n2, err := strconv.ParseInt(buf[s1+1:s2], 10, 64) + if err != nil { + return 0, false + } + n3, err := strconv.ParseInt(buf[s2+1:], 10, 64) + if err != nil { + return 0, false + } + + // on urxvt, first number is encoded exactly as in X10, but we need to + // make it zero-based, on xterm it is zero-based already + if isU { + n1 -= 32 + } + switch n1 & 3 { + case 0: + if n1&64 != 0 { + event.Key = MouseWheelUp + } else { + event.Key = MouseLeft + } + case 1: + if n1&64 != 0 { + event.Key = MouseWheelDown + } else { + event.Key = MouseMiddle + } + case 2: + event.Key = MouseRight + case 3: + event.Key = MouseRelease + default: + return mi + 1, false + } + if !isM { + // on xterm mouse release is signaled by lowercase m + event.Key = MouseRelease + } + + event.Type = EventMouse // KeyEvent by default + if n1&32 != 0 { + event.Mod |= ModMotion + } + + event.MouseX = int(n2) - 1 + event.MouseY = int(n3) - 1 + return mi + 1, true + } + + return 0, false +} + +func parse_escape_sequence(event *Event, buf []byte) (int, bool) { + bufstr := string(buf) + for i, key := range keys { + if strings.HasPrefix(bufstr, key) { + event.Ch = 0 + event.Key = Key(0xFFFF - i) + return len(key), true + } + } + + // if none of the keys match, let's try mouse sequences + return parse_mouse_event(event, bufstr) +} + +func extract_raw_event(data []byte, event *Event) bool { + if len(inbuf) == 0 { + return false + } + + n := len(data) + if n == 0 { + return false + } + + n = copy(data, inbuf) + copy(inbuf, inbuf[n:]) + inbuf = inbuf[:len(inbuf)-n] + + event.N = n + event.Type = EventRaw + return true +} + +func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res { + if len(inbuf) == 0 { + event.N = 0 + return event_not_extracted + } + + if inbuf[0] == '\033' { + // possible escape sequence + if n, ok := parse_escape_sequence(event, inbuf); n != 0 { + event.N = n + if ok { + return event_extracted + } else { + return event_not_extracted + } + } + + // possible partially read escape sequence; trigger a wait if appropriate + if enable_wait_for_escape_sequence() && allow_esc_wait { + event.N = 0 + return esc_wait + } + + // it's not escape sequence, then it's Alt or Esc, check input_mode + switch { + case input_mode&InputEsc != 0: + // if we're in escape mode, fill Esc event, pop buffer, return success + event.Ch = 0 + event.Key = KeyEsc + event.Mod = 0 + event.N = 1 + return event_extracted + case input_mode&InputAlt != 0: + // if we're in alt mode, set Alt modifier to event and redo parsing + event.Mod = ModAlt + status := extract_event(inbuf[1:], event, false) + if status == event_extracted { + event.N++ + } else { + event.N = 0 + } + return status + default: + panic("unreachable") + } + } + + // if we're here, this is not an escape sequence and not an alt sequence + // so, it's a FUNCTIONAL KEY or a UNICODE character + + // first of all check if it's a functional key + if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 { + // fill event, pop buffer, return success + event.Ch = 0 + event.Key = Key(inbuf[0]) + event.N = 1 + return event_extracted + } + + // the only possible option is utf8 rune + if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError { + event.Ch = r + event.Key = 0 + event.N = n + return event_extracted + } + + return event_not_extracted +} + +func fcntl(fd int, cmd int, arg int) (val int, err error) { + r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), + uintptr(arg)) + val = int(r) + if e != 0 { + err = e + } + return +} diff --git a/vendor/github.com/nsf/termbox-go/termbox_common.go b/vendor/github.com/nsf/termbox-go/termbox_common.go new file mode 100644 index 0000000..c3355cc --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/termbox_common.go @@ -0,0 +1,59 @@ +package termbox + +// private API, common OS agnostic part + +type cellbuf struct { + width int + height int + cells []Cell +} + +func (this *cellbuf) init(width, height int) { + this.width = width + this.height = height + this.cells = make([]Cell, width*height) +} + +func (this *cellbuf) resize(width, height int) { + if this.width == width && this.height == height { + return + } + + oldw := this.width + oldh := this.height + oldcells := this.cells + + this.init(width, height) + this.clear() + + minw, minh := oldw, oldh + + if width < minw { + minw = width + } + if height < minh { + minh = height + } + + for i := 0; i < minh; i++ { + srco, dsto := i*oldw, i*width + src := oldcells[srco : srco+minw] + dst := this.cells[dsto : dsto+minw] + copy(dst, src) + } +} + +func (this *cellbuf) clear() { + for i := range this.cells { + c := &this.cells[i] + c.Ch = ' ' + c.Fg = foreground + c.Bg = background + } +} + +const cursor_hidden = -1 + +func is_cursor_hidden(x, y int) bool { + return x == cursor_hidden || y == cursor_hidden +} diff --git a/vendor/github.com/nsf/termbox-go/termbox_windows.go b/vendor/github.com/nsf/termbox-go/termbox_windows.go new file mode 100644 index 0000000..738847c --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/termbox_windows.go @@ -0,0 +1,889 @@ +package termbox + +import "syscall" +import "unsafe" +import "unicode/utf16" +import "github.com/mattn/go-runewidth" + +type ( + wchar uint16 + short int16 + dword uint32 + word uint16 + char_info struct { + char wchar + attr word + } + coord struct { + x short + y short + } + small_rect struct { + left short + top short + right short + bottom short + } + console_screen_buffer_info struct { + size coord + cursor_position coord + attributes word + window small_rect + maximum_window_size coord + } + console_cursor_info struct { + size dword + visible int32 + } + input_record struct { + event_type word + _ [2]byte + event [16]byte + } + key_event_record struct { + key_down int32 + repeat_count word + virtual_key_code word + virtual_scan_code word + unicode_char wchar + control_key_state dword + } + window_buffer_size_record struct { + size coord + } + mouse_event_record struct { + mouse_pos coord + button_state dword + control_key_state dword + event_flags dword + } +) + +const ( + mouse_lmb = 0x1 + mouse_rmb = 0x2 + mouse_mmb = 0x4 | 0x8 | 0x10 + SM_CXMIN = 28 + SM_CYMIN = 29 +) + +func (this coord) uintptr() uintptr { + return uintptr(*(*int32)(unsafe.Pointer(&this))) +} + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") +var moduser32 = syscall.NewLazyDLL("user32.dll") +var is_cjk = runewidth.IsEastAsian() + +var ( + proc_set_console_active_screen_buffer = kernel32.NewProc("SetConsoleActiveScreenBuffer") + proc_set_console_screen_buffer_size = kernel32.NewProc("SetConsoleScreenBufferSize") + proc_create_console_screen_buffer = kernel32.NewProc("CreateConsoleScreenBuffer") + proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo") + proc_write_console_output = kernel32.NewProc("WriteConsoleOutputW") + proc_write_console_output_character = kernel32.NewProc("WriteConsoleOutputCharacterW") + proc_write_console_output_attribute = kernel32.NewProc("WriteConsoleOutputAttribute") + proc_set_console_cursor_info = kernel32.NewProc("SetConsoleCursorInfo") + proc_set_console_cursor_position = kernel32.NewProc("SetConsoleCursorPosition") + proc_get_console_cursor_info = kernel32.NewProc("GetConsoleCursorInfo") + proc_read_console_input = kernel32.NewProc("ReadConsoleInputW") + proc_get_console_mode = kernel32.NewProc("GetConsoleMode") + proc_set_console_mode = kernel32.NewProc("SetConsoleMode") + proc_fill_console_output_character = kernel32.NewProc("FillConsoleOutputCharacterW") + proc_fill_console_output_attribute = kernel32.NewProc("FillConsoleOutputAttribute") + proc_create_event = kernel32.NewProc("CreateEventW") + proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects") + proc_set_event = kernel32.NewProc("SetEvent") + get_system_metrics = moduser32.NewProc("GetSystemMetrics") +) + +func set_console_active_screen_buffer(h syscall.Handle) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_console_active_screen_buffer.Addr(), + 1, uintptr(h), 0, 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func set_console_screen_buffer_size(h syscall.Handle, size coord) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_console_screen_buffer_size.Addr(), + 2, uintptr(h), size.uintptr(), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func create_console_screen_buffer() (h syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(proc_create_console_screen_buffer.Addr(), + 5, uintptr(generic_read|generic_write), 0, 0, console_textmode_buffer, 0, 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return syscall.Handle(r0), err +} + +func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) { + r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(), + 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func write_console_output(h syscall.Handle, chars []char_info, dst small_rect) (err error) { + tmp_coord = coord{dst.right - dst.left + 1, dst.bottom - dst.top + 1} + tmp_rect = dst + r0, _, e1 := syscall.Syscall6(proc_write_console_output.Addr(), + 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), tmp_coord.uintptr(), + tmp_coord0.uintptr(), uintptr(unsafe.Pointer(&tmp_rect)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func write_console_output_character(h syscall.Handle, chars []wchar, pos coord) (err error) { + r0, _, e1 := syscall.Syscall6(proc_write_console_output_character.Addr(), + 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), uintptr(len(chars)), + pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func write_console_output_attribute(h syscall.Handle, attrs []word, pos coord) (err error) { + r0, _, e1 := syscall.Syscall6(proc_write_console_output_attribute.Addr(), + 5, uintptr(h), uintptr(unsafe.Pointer(&attrs[0])), uintptr(len(attrs)), + pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func set_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_console_cursor_info.Addr(), + 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func get_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) { + r0, _, e1 := syscall.Syscall(proc_get_console_cursor_info.Addr(), + 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func set_console_cursor_position(h syscall.Handle, pos coord) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_console_cursor_position.Addr(), + 2, uintptr(h), pos.uintptr(), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func read_console_input(h syscall.Handle, record *input_record) (err error) { + r0, _, e1 := syscall.Syscall6(proc_read_console_input.Addr(), + 4, uintptr(h), uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&tmp_arg)), 0, 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func get_console_mode(h syscall.Handle, mode *dword) (err error) { + r0, _, e1 := syscall.Syscall(proc_get_console_mode.Addr(), + 2, uintptr(h), uintptr(unsafe.Pointer(mode)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func set_console_mode(h syscall.Handle, mode dword) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_console_mode.Addr(), + 2, uintptr(h), uintptr(mode), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func fill_console_output_character(h syscall.Handle, char wchar, n int) (err error) { + r0, _, e1 := syscall.Syscall6(proc_fill_console_output_character.Addr(), + 5, uintptr(h), uintptr(char), uintptr(n), tmp_coord.uintptr(), + uintptr(unsafe.Pointer(&tmp_arg)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func fill_console_output_attribute(h syscall.Handle, attr word, n int) (err error) { + r0, _, e1 := syscall.Syscall6(proc_fill_console_output_attribute.Addr(), + 5, uintptr(h), uintptr(attr), uintptr(n), tmp_coord.uintptr(), + uintptr(unsafe.Pointer(&tmp_arg)), 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func create_event() (out syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(proc_create_event.Addr(), + 4, 0, 0, 0, 0, 0, 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return syscall.Handle(r0), err +} + +func wait_for_multiple_objects(objects []syscall.Handle) (err error) { + r0, _, e1 := syscall.Syscall6(proc_wait_for_multiple_objects.Addr(), + 4, uintptr(len(objects)), uintptr(unsafe.Pointer(&objects[0])), + 0, 0xFFFFFFFF, 0, 0) + if uint32(r0) == 0xFFFFFFFF { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func set_event(ev syscall.Handle) (err error) { + r0, _, e1 := syscall.Syscall(proc_set_event.Addr(), + 1, uintptr(ev), 0, 0) + if int(r0) == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +type diff_msg struct { + pos short + lines short + chars []char_info +} + +type input_event struct { + event Event + err error +} + +var ( + orig_cursor_info console_cursor_info + orig_size coord + orig_mode dword + orig_screen syscall.Handle + back_buffer cellbuf + front_buffer cellbuf + term_size coord + input_mode = InputEsc + cursor_x = cursor_hidden + cursor_y = cursor_hidden + foreground = ColorDefault + background = ColorDefault + in syscall.Handle + out syscall.Handle + interrupt syscall.Handle + charbuf []char_info + diffbuf []diff_msg + beg_x = -1 + beg_y = -1 + beg_i = -1 + input_comm = make(chan Event) + interrupt_comm = make(chan struct{}) + cancel_comm = make(chan bool, 1) + cancel_done_comm = make(chan bool) + alt_mode_esc = false + + // these ones just to prevent heap allocs at all costs + tmp_info console_screen_buffer_info + tmp_arg dword + tmp_coord0 = coord{0, 0} + tmp_coord = coord{0, 0} + tmp_rect = small_rect{0, 0, 0, 0} +) + +func get_cursor_position(out syscall.Handle) coord { + err := get_console_screen_buffer_info(out, &tmp_info) + if err != nil { + panic(err) + } + return tmp_info.cursor_position +} + +func get_term_size(out syscall.Handle) coord { + err := get_console_screen_buffer_info(out, &tmp_info) + if err != nil { + panic(err) + } + return tmp_info.size +} + +func get_win_min_size(out syscall.Handle) coord { + x, _, err := get_system_metrics.Call(SM_CXMIN) + y, _, err := get_system_metrics.Call(SM_CYMIN) + + if x == 0 || y == 0 { + if err != nil { + panic(err) + } + } + + return coord{ + x: short(x), + y: short(y), + } +} + +func get_win_size(out syscall.Handle) coord { + err := get_console_screen_buffer_info(out, &tmp_info) + if err != nil { + panic(err) + } + + min_size := get_win_min_size(out) + + size := coord{ + x: tmp_info.window.right - tmp_info.window.left + 1, + y: tmp_info.window.bottom - tmp_info.window.top + 1, + } + + if size.x < min_size.x { + size.x = min_size.x + } + + if size.y < min_size.y { + size.y = min_size.y + } + + return size +} + +func update_size_maybe() { + size := get_term_size(out) + if size.x != term_size.x || size.y != term_size.y { + term_size = size + back_buffer.resize(int(size.x), int(size.y)) + front_buffer.resize(int(size.x), int(size.y)) + front_buffer.clear() + clear() + + area := int(size.x) * int(size.y) + if cap(charbuf) < area { + charbuf = make([]char_info, 0, area) + } + } +} + +var color_table_bg = []word{ + 0, // default (black) + 0, // black + background_red, + background_green, + background_red | background_green, // yellow + background_blue, + background_red | background_blue, // magenta + background_green | background_blue, // cyan + background_red | background_blue | background_green, // white +} + +var color_table_fg = []word{ + foreground_red | foreground_blue | foreground_green, // default (white) + 0, + foreground_red, + foreground_green, + foreground_red | foreground_green, // yellow + foreground_blue, + foreground_red | foreground_blue, // magenta + foreground_green | foreground_blue, // cyan + foreground_red | foreground_blue | foreground_green, // white +} + +const ( + replacement_char = '\uFFFD' + max_rune = '\U0010FFFF' + surr1 = 0xd800 + surr2 = 0xdc00 + surr3 = 0xe000 + surr_self = 0x10000 +) + +func append_diff_line(y int) int { + n := 0 + for x := 0; x < front_buffer.width; { + cell_offset := y*front_buffer.width + x + back := &back_buffer.cells[cell_offset] + front := &front_buffer.cells[cell_offset] + attr, char := cell_to_char_info(*back) + charbuf = append(charbuf, char_info{attr: attr, char: char[0]}) + *front = *back + n++ + w := runewidth.RuneWidth(back.Ch) + if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) { + w = 1 + } + x += w + // If not CJK, fill trailing space with whitespace + if !is_cjk && w == 2 { + charbuf = append(charbuf, char_info{attr: attr, char: ' '}) + } + } + return n +} + +// compares 'back_buffer' with 'front_buffer' and prepares all changes in the form of +// 'diff_msg's in the 'diff_buf' +func prepare_diff_messages() { + // clear buffers + diffbuf = diffbuf[:0] + charbuf = charbuf[:0] + + var diff diff_msg + gbeg := 0 + for y := 0; y < front_buffer.height; y++ { + same := true + line_offset := y * front_buffer.width + for x := 0; x < front_buffer.width; x++ { + cell_offset := line_offset + x + back := &back_buffer.cells[cell_offset] + front := &front_buffer.cells[cell_offset] + if *back != *front { + same = false + break + } + } + if same && diff.lines > 0 { + diffbuf = append(diffbuf, diff) + diff = diff_msg{} + } + if !same { + beg := len(charbuf) + end := beg + append_diff_line(y) + if diff.lines == 0 { + diff.pos = short(y) + gbeg = beg + } + diff.lines++ + diff.chars = charbuf[gbeg:end] + } + } + if diff.lines > 0 { + diffbuf = append(diffbuf, diff) + diff = diff_msg{} + } +} + +func get_ct(table []word, idx int) word { + idx = idx & 0x0F + if idx >= len(table) { + idx = len(table) - 1 + } + return table[idx] +} + +func cell_to_char_info(c Cell) (attr word, wc [2]wchar) { + attr = get_ct(color_table_fg, int(c.Fg)) | get_ct(color_table_bg, int(c.Bg)) + if c.Fg&AttrReverse|c.Bg&AttrReverse != 0 { + attr = (attr&0xF0)>>4 | (attr&0x0F)<<4 + } + if c.Fg&AttrBold != 0 { + attr |= foreground_intensity + } + if c.Bg&AttrBold != 0 { + attr |= background_intensity + } + + r0, r1 := utf16.EncodeRune(c.Ch) + if r0 == 0xFFFD { + wc[0] = wchar(c.Ch) + wc[1] = ' ' + } else { + wc[0] = wchar(r0) + wc[1] = wchar(r1) + } + return +} + +func move_cursor(x, y int) { + err := set_console_cursor_position(out, coord{short(x), short(y)}) + if err != nil { + panic(err) + } +} + +func show_cursor(visible bool) { + var v int32 + if visible { + v = 1 + } + + var info console_cursor_info + info.size = 100 + info.visible = v + err := set_console_cursor_info(out, &info) + if err != nil { + panic(err) + } +} + +func clear() { + var err error + attr, char := cell_to_char_info(Cell{ + ' ', + foreground, + background, + }) + + area := int(term_size.x) * int(term_size.y) + err = fill_console_output_attribute(out, attr, area) + if err != nil { + panic(err) + } + err = fill_console_output_character(out, char[0], area) + if err != nil { + panic(err) + } + if !is_cursor_hidden(cursor_x, cursor_y) { + move_cursor(cursor_x, cursor_y) + } +} + +func key_event_record_to_event(r *key_event_record) (Event, bool) { + if r.key_down == 0 { + return Event{}, false + } + + e := Event{Type: EventKey} + if input_mode&InputAlt != 0 { + if alt_mode_esc { + e.Mod = ModAlt + alt_mode_esc = false + } + if r.control_key_state&(left_alt_pressed|right_alt_pressed) != 0 { + e.Mod = ModAlt + } + } + + ctrlpressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0 + + if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 { + switch r.virtual_key_code { + case vk_f1: + e.Key = KeyF1 + case vk_f2: + e.Key = KeyF2 + case vk_f3: + e.Key = KeyF3 + case vk_f4: + e.Key = KeyF4 + case vk_f5: + e.Key = KeyF5 + case vk_f6: + e.Key = KeyF6 + case vk_f7: + e.Key = KeyF7 + case vk_f8: + e.Key = KeyF8 + case vk_f9: + e.Key = KeyF9 + case vk_f10: + e.Key = KeyF10 + case vk_f11: + e.Key = KeyF11 + case vk_f12: + e.Key = KeyF12 + default: + panic("unreachable") + } + + return e, true + } + + if r.virtual_key_code <= vk_delete { + switch r.virtual_key_code { + case vk_insert: + e.Key = KeyInsert + case vk_delete: + e.Key = KeyDelete + case vk_home: + e.Key = KeyHome + case vk_end: + e.Key = KeyEnd + case vk_pgup: + e.Key = KeyPgup + case vk_pgdn: + e.Key = KeyPgdn + case vk_arrow_up: + e.Key = KeyArrowUp + case vk_arrow_down: + e.Key = KeyArrowDown + case vk_arrow_left: + e.Key = KeyArrowLeft + case vk_arrow_right: + e.Key = KeyArrowRight + case vk_backspace: + if ctrlpressed { + e.Key = KeyBackspace2 + } else { + e.Key = KeyBackspace + } + case vk_tab: + e.Key = KeyTab + case vk_enter: + e.Key = KeyEnter + case vk_esc: + switch { + case input_mode&InputEsc != 0: + e.Key = KeyEsc + case input_mode&InputAlt != 0: + alt_mode_esc = true + return Event{}, false + } + case vk_space: + if ctrlpressed { + // manual return here, because KeyCtrlSpace is zero + e.Key = KeyCtrlSpace + return e, true + } else { + e.Key = KeySpace + } + } + + if e.Key != 0 { + return e, true + } + } + + if ctrlpressed { + if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket { + e.Key = Key(r.unicode_char) + if input_mode&InputAlt != 0 && e.Key == KeyEsc { + alt_mode_esc = true + return Event{}, false + } + return e, true + } + switch r.virtual_key_code { + case 192, 50: + // manual return here, because KeyCtrl2 is zero + e.Key = KeyCtrl2 + return e, true + case 51: + if input_mode&InputAlt != 0 { + alt_mode_esc = true + return Event{}, false + } + e.Key = KeyCtrl3 + case 52: + e.Key = KeyCtrl4 + case 53: + e.Key = KeyCtrl5 + case 54: + e.Key = KeyCtrl6 + case 189, 191, 55: + e.Key = KeyCtrl7 + case 8, 56: + e.Key = KeyCtrl8 + } + + if e.Key != 0 { + return e, true + } + } + + if r.unicode_char != 0 { + e.Ch = rune(r.unicode_char) + return e, true + } + + return Event{}, false +} + +func input_event_producer() { + var r input_record + var err error + var last_button Key + var last_button_pressed Key + var last_state = dword(0) + var last_x, last_y = -1, -1 + handles := []syscall.Handle{in, interrupt} + for { + err = wait_for_multiple_objects(handles) + if err != nil { + input_comm <- Event{Type: EventError, Err: err} + } + + select { + case <-cancel_comm: + cancel_done_comm <- true + return + default: + } + + err = read_console_input(in, &r) + if err != nil { + input_comm <- Event{Type: EventError, Err: err} + } + + switch r.event_type { + case key_event: + kr := (*key_event_record)(unsafe.Pointer(&r.event)) + ev, ok := key_event_record_to_event(kr) + if ok { + for i := 0; i < int(kr.repeat_count); i++ { + input_comm <- ev + } + } + case window_buffer_size_event: + sr := *(*window_buffer_size_record)(unsafe.Pointer(&r.event)) + input_comm <- Event{ + Type: EventResize, + Width: int(sr.size.x), + Height: int(sr.size.y), + } + case mouse_event: + mr := *(*mouse_event_record)(unsafe.Pointer(&r.event)) + ev := Event{Type: EventMouse} + switch mr.event_flags { + case 0, 2: + // single or double click + cur_state := mr.button_state + switch { + case last_state&mouse_lmb == 0 && cur_state&mouse_lmb != 0: + last_button = MouseLeft + last_button_pressed = last_button + case last_state&mouse_rmb == 0 && cur_state&mouse_rmb != 0: + last_button = MouseRight + last_button_pressed = last_button + case last_state&mouse_mmb == 0 && cur_state&mouse_mmb != 0: + last_button = MouseMiddle + last_button_pressed = last_button + case last_state&mouse_lmb != 0 && cur_state&mouse_lmb == 0: + last_button = MouseRelease + case last_state&mouse_rmb != 0 && cur_state&mouse_rmb == 0: + last_button = MouseRelease + case last_state&mouse_mmb != 0 && cur_state&mouse_mmb == 0: + last_button = MouseRelease + default: + last_state = cur_state + continue + } + last_state = cur_state + ev.Key = last_button + last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y) + ev.MouseX = last_x + ev.MouseY = last_y + case 1: + // mouse motion + x, y := int(mr.mouse_pos.x), int(mr.mouse_pos.y) + if last_state != 0 && (last_x != x || last_y != y) { + ev.Key = last_button_pressed + ev.Mod = ModMotion + ev.MouseX = x + ev.MouseY = y + last_x, last_y = x, y + } else { + ev.Type = EventNone + } + case 4: + // mouse wheel + n := int16(mr.button_state >> 16) + if n > 0 { + ev.Key = MouseWheelUp + } else { + ev.Key = MouseWheelDown + } + last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y) + ev.MouseX = last_x + ev.MouseY = last_y + default: + ev.Type = EventNone + } + if ev.Type != EventNone { + input_comm <- ev + } + } + } +} diff --git a/vendor/github.com/nsf/termbox-go/terminfo.go b/vendor/github.com/nsf/termbox-go/terminfo.go new file mode 100644 index 0000000..35dbd70 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/terminfo.go @@ -0,0 +1,221 @@ +// +build !windows +// This file contains a simple and incomplete implementation of the terminfo +// database. Information was taken from the ncurses manpages term(5) and +// terminfo(5). Currently, only the string capabilities for special keys and for +// functions without parameters are actually used. Colors are still done with +// ANSI escape sequences. Other special features that are not (yet?) supported +// are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database +// format and extended capabilities. + +package termbox + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "io/ioutil" + "os" + "strings" +) + +const ( + ti_magic = 0432 + ti_header_length = 12 + ti_mouse_enter = "\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h" + ti_mouse_leave = "\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l" +) + +func load_terminfo() ([]byte, error) { + var data []byte + var err error + + term := os.Getenv("TERM") + if term == "" { + return nil, fmt.Errorf("termbox: TERM not set") + } + + // The following behaviour follows the one described in terminfo(5) as + // distributed by ncurses. + + terminfo := os.Getenv("TERMINFO") + if terminfo != "" { + // if TERMINFO is set, no other directory should be searched + return ti_try_path(terminfo) + } + + // next, consider ~/.terminfo + home := os.Getenv("HOME") + if home != "" { + data, err = ti_try_path(home + "/.terminfo") + if err == nil { + return data, nil + } + } + + // next, TERMINFO_DIRS + dirs := os.Getenv("TERMINFO_DIRS") + if dirs != "" { + for _, dir := range strings.Split(dirs, ":") { + if dir == "" { + // "" -> "/usr/share/terminfo" + dir = "/usr/share/terminfo" + } + data, err = ti_try_path(dir) + if err == nil { + return data, nil + } + } + } + + // fall back to /usr/share/terminfo + return ti_try_path("/usr/share/terminfo") +} + +func ti_try_path(path string) (data []byte, err error) { + // load_terminfo already made sure it is set + term := os.Getenv("TERM") + + // first try, the typical *nix path + terminfo := path + "/" + term[0:1] + "/" + term + data, err = ioutil.ReadFile(terminfo) + if err == nil { + return + } + + // fallback to darwin specific dirs structure + terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term + data, err = ioutil.ReadFile(terminfo) + return +} + +func setup_term_builtin() error { + name := os.Getenv("TERM") + if name == "" { + return errors.New("termbox: TERM environment variable not set") + } + + for _, t := range terms { + if t.name == name { + keys = t.keys + funcs = t.funcs + return nil + } + } + + compat_table := []struct { + partial string + keys []string + funcs []string + }{ + {"xterm", xterm_keys, xterm_funcs}, + {"rxvt", rxvt_unicode_keys, rxvt_unicode_funcs}, + {"linux", linux_keys, linux_funcs}, + {"Eterm", eterm_keys, eterm_funcs}, + {"screen", screen_keys, screen_funcs}, + // let's assume that 'cygwin' is xterm compatible + {"cygwin", xterm_keys, xterm_funcs}, + {"st", xterm_keys, xterm_funcs}, + } + + // try compatibility variants + for _, it := range compat_table { + if strings.Contains(name, it.partial) { + keys = it.keys + funcs = it.funcs + return nil + } + } + + return errors.New("termbox: unsupported terminal") +} + +func setup_term() (err error) { + var data []byte + var header [6]int16 + var str_offset, table_offset int16 + + data, err = load_terminfo() + if err != nil { + return setup_term_builtin() + } + + rd := bytes.NewReader(data) + // 0: magic number, 1: size of names section, 2: size of boolean section, 3: + // size of numbers section (in integers), 4: size of the strings section (in + // integers), 5: size of the string table + + err = binary.Read(rd, binary.LittleEndian, header[:]) + if err != nil { + return + } + + if (header[1]+header[2])%2 != 0 { + // old quirk to align everything on word boundaries + header[2] += 1 + } + str_offset = ti_header_length + header[1] + header[2] + 2*header[3] + table_offset = str_offset + 2*header[4] + + keys = make([]string, 0xFFFF-key_min) + for i, _ := range keys { + keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset) + if err != nil { + return + } + } + funcs = make([]string, t_max_funcs) + // the last two entries are reserved for mouse. because the table offset is + // not there, the two entries have to fill in manually + for i, _ := range funcs[:len(funcs)-2] { + funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset) + if err != nil { + return + } + } + funcs[t_max_funcs-2] = ti_mouse_enter + funcs[t_max_funcs-1] = ti_mouse_leave + return nil +} + +func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) { + var off int16 + + _, err := rd.Seek(int64(str_off), 0) + if err != nil { + return "", err + } + err = binary.Read(rd, binary.LittleEndian, &off) + if err != nil { + return "", err + } + _, err = rd.Seek(int64(table+off), 0) + if err != nil { + return "", err + } + var bs []byte + for { + b, err := rd.ReadByte() + if err != nil { + return "", err + } + if b == byte(0x00) { + break + } + bs = append(bs, b) + } + return string(bs), nil +} + +// "Maps" the function constants from termbox.go to the number of the respective +// string capability in the terminfo file. Taken from (ncurses) term.h. +var ti_funcs = []int16{ + 28, 40, 16, 13, 5, 39, 36, 27, 26, 34, 89, 88, +} + +// Same as above for the special keys. +var ti_keys = []int16{ + 66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70, + 71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83, +} diff --git a/vendor/github.com/nsf/termbox-go/terminfo_builtin.go b/vendor/github.com/nsf/termbox-go/terminfo_builtin.go new file mode 100644 index 0000000..a948660 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/terminfo_builtin.go @@ -0,0 +1,64 @@ +// +build !windows + +package termbox + +// Eterm +var eterm_keys = []string{ + "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", +} +var eterm_funcs = []string{ + "\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "", +} + +// screen +var screen_keys = []string{ + "\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC", +} +var screen_funcs = []string{ + "\x1b[?1049h", "\x1b[?1049l", "\x1b[34h\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave, +} + +// xterm +var xterm_keys = []string{ + "\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1bOH", "\x1bOF", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC", +} +var xterm_funcs = []string{ + "\x1b[?1049h", "\x1b[?1049l", "\x1b[?12l\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b(B\x1b[m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave, +} + +// rxvt-unicode +var rxvt_unicode_keys = []string{ + "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", +} +var rxvt_unicode_funcs = []string{ + "\x1b[?1049h", "\x1b[r\x1b[?1049l", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x1b(B", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave, +} + +// linux +var linux_keys = []string{ + "\x1b[[A", "\x1b[[B", "\x1b[[C", "\x1b[[D", "\x1b[[E", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", +} +var linux_funcs = []string{ + "", "", "\x1b[?25h\x1b[?0c", "\x1b[?25l\x1b[?1c", "\x1b[H\x1b[J", "\x1b[0;10m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "", +} + +// rxvt-256color +var rxvt_256color_keys = []string{ + "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", +} +var rxvt_256color_funcs = []string{ + "\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave, +} + +var terms = []struct { + name string + keys []string + funcs []string +}{ + {"Eterm", eterm_keys, eterm_funcs}, + {"screen", screen_keys, screen_funcs}, + {"xterm", xterm_keys, xterm_funcs}, + {"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs}, + {"linux", linux_keys, linux_funcs}, + {"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs}, +} diff --git a/vendor/golang.org/x/sys/plan9/asm.s b/vendor/golang.org/x/sys/plan9/asm.s deleted file mode 100644 index 06449eb..0000000 --- a/vendor/golang.org/x/sys/plan9/asm.s +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2014 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 "textflag.h" - -TEXT ·use(SB),NOSPLIT,$0 - RET diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_386.s b/vendor/golang.org/x/sys/plan9/asm_plan9_386.s deleted file mode 100644 index bc5cab1..0000000 --- a/vendor/golang.org/x/sys/plan9/asm_plan9_386.s +++ /dev/null @@ -1,30 +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. - -#include "textflag.h" - -// -// System call support for 386, Plan 9 -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-32 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-44 - JMP syscall·Syscall6(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - JMP syscall·RawSyscall6(SB) - -TEXT ·seek(SB),NOSPLIT,$0-36 - JMP syscall·seek(SB) - -TEXT ·exit(SB),NOSPLIT,$4-4 - JMP syscall·exit(SB) diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s b/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s deleted file mode 100644 index d3448e6..0000000 --- a/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s +++ /dev/null @@ -1,30 +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. - -#include "textflag.h" - -// -// System call support for amd64, Plan 9 -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-64 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-88 - JMP syscall·Syscall6(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) - -TEXT ·seek(SB),NOSPLIT,$0-56 - JMP syscall·seek(SB) - -TEXT ·exit(SB),NOSPLIT,$8-8 - JMP syscall·exit(SB) diff --git a/vendor/golang.org/x/sys/plan9/const_plan9.go b/vendor/golang.org/x/sys/plan9/const_plan9.go deleted file mode 100644 index b4e85a3..0000000 --- a/vendor/golang.org/x/sys/plan9/const_plan9.go +++ /dev/null @@ -1,70 +0,0 @@ -package plan9 - -// Plan 9 Constants - -// Open modes -const ( - O_RDONLY = 0 - O_WRONLY = 1 - O_RDWR = 2 - O_TRUNC = 16 - O_CLOEXEC = 32 - O_EXCL = 0x1000 -) - -// Rfork flags -const ( - RFNAMEG = 1 << 0 - RFENVG = 1 << 1 - RFFDG = 1 << 2 - RFNOTEG = 1 << 3 - RFPROC = 1 << 4 - RFMEM = 1 << 5 - RFNOWAIT = 1 << 6 - RFCNAMEG = 1 << 10 - RFCENVG = 1 << 11 - RFCFDG = 1 << 12 - RFREND = 1 << 13 - RFNOMNT = 1 << 14 -) - -// Qid.Type bits -const ( - QTDIR = 0x80 - QTAPPEND = 0x40 - QTEXCL = 0x20 - QTMOUNT = 0x10 - QTAUTH = 0x08 - QTTMP = 0x04 - QTFILE = 0x00 -) - -// Dir.Mode bits -const ( - DMDIR = 0x80000000 - DMAPPEND = 0x40000000 - DMEXCL = 0x20000000 - DMMOUNT = 0x10000000 - DMAUTH = 0x08000000 - DMTMP = 0x04000000 - DMREAD = 0x4 - DMWRITE = 0x2 - DMEXEC = 0x1 -) - -const ( - STATMAX = 65535 - ERRMAX = 128 - STATFIXLEN = 49 -) - -// Mount and bind flags -const ( - MREPL = 0x0000 - MBEFORE = 0x0001 - MAFTER = 0x0002 - MORDER = 0x0003 - MCREATE = 0x0004 - MCACHE = 0x0010 - MMASK = 0x0017 -) diff --git a/vendor/golang.org/x/sys/plan9/dir_plan9.go b/vendor/golang.org/x/sys/plan9/dir_plan9.go deleted file mode 100644 index 0955e0c..0000000 --- a/vendor/golang.org/x/sys/plan9/dir_plan9.go +++ /dev/null @@ -1,212 +0,0 @@ -// 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. - -// Plan 9 directory marshalling. See intro(5). - -package plan9 - -import "errors" - -var ( - ErrShortStat = errors.New("stat buffer too short") - ErrBadStat = errors.New("malformed stat buffer") - ErrBadName = errors.New("bad character in file name") -) - -// A Qid represents a 9P server's unique identification for a file. -type Qid struct { - Path uint64 // the file server's unique identification for the file - Vers uint32 // version number for given Path - Type uint8 // the type of the file (plan9.QTDIR for example) -} - -// A Dir contains the metadata for a file. -type Dir struct { - // system-modified data - Type uint16 // server type - Dev uint32 // server subtype - - // file data - Qid Qid // unique id from server - Mode uint32 // permissions - Atime uint32 // last read time - Mtime uint32 // last write time - Length int64 // file length - Name string // last element of path - Uid string // owner name - Gid string // group name - Muid string // last modifier name -} - -var nullDir = Dir{ - Type: ^uint16(0), - Dev: ^uint32(0), - Qid: Qid{ - Path: ^uint64(0), - Vers: ^uint32(0), - Type: ^uint8(0), - }, - Mode: ^uint32(0), - Atime: ^uint32(0), - Mtime: ^uint32(0), - Length: ^int64(0), -} - -// Null assigns special "don't touch" values to members of d to -// avoid modifying them during plan9.Wstat. -func (d *Dir) Null() { *d = nullDir } - -// Marshal encodes a 9P stat message corresponding to d into b -// -// If there isn't enough space in b for a stat message, ErrShortStat is returned. -func (d *Dir) Marshal(b []byte) (n int, err error) { - n = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid) - if n > len(b) { - return n, ErrShortStat - } - - for _, c := range d.Name { - if c == '/' { - return n, ErrBadName - } - } - - b = pbit16(b, uint16(n)-2) - b = pbit16(b, d.Type) - b = pbit32(b, d.Dev) - b = pbit8(b, d.Qid.Type) - b = pbit32(b, d.Qid.Vers) - b = pbit64(b, d.Qid.Path) - b = pbit32(b, d.Mode) - b = pbit32(b, d.Atime) - b = pbit32(b, d.Mtime) - b = pbit64(b, uint64(d.Length)) - b = pstring(b, d.Name) - b = pstring(b, d.Uid) - b = pstring(b, d.Gid) - b = pstring(b, d.Muid) - - return n, nil -} - -// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir. -// -// If b is too small to hold a valid stat message, ErrShortStat is returned. -// -// If the stat message itself is invalid, ErrBadStat is returned. -func UnmarshalDir(b []byte) (*Dir, error) { - if len(b) < STATFIXLEN { - return nil, ErrShortStat - } - size, buf := gbit16(b) - if len(b) != int(size)+2 { - return nil, ErrBadStat - } - b = buf - - var d Dir - d.Type, b = gbit16(b) - d.Dev, b = gbit32(b) - d.Qid.Type, b = gbit8(b) - d.Qid.Vers, b = gbit32(b) - d.Qid.Path, b = gbit64(b) - d.Mode, b = gbit32(b) - d.Atime, b = gbit32(b) - d.Mtime, b = gbit32(b) - - n, b := gbit64(b) - d.Length = int64(n) - - var ok bool - if d.Name, b, ok = gstring(b); !ok { - return nil, ErrBadStat - } - if d.Uid, b, ok = gstring(b); !ok { - return nil, ErrBadStat - } - if d.Gid, b, ok = gstring(b); !ok { - return nil, ErrBadStat - } - if d.Muid, b, ok = gstring(b); !ok { - return nil, ErrBadStat - } - - return &d, nil -} - -// pbit8 copies the 8-bit number v to b and returns the remaining slice of b. -func pbit8(b []byte, v uint8) []byte { - b[0] = byte(v) - return b[1:] -} - -// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b. -func pbit16(b []byte, v uint16) []byte { - b[0] = byte(v) - b[1] = byte(v >> 8) - return b[2:] -} - -// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b. -func pbit32(b []byte, v uint32) []byte { - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) - return b[4:] -} - -// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b. -func pbit64(b []byte, v uint64) []byte { - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) - b[4] = byte(v >> 32) - b[5] = byte(v >> 40) - b[6] = byte(v >> 48) - b[7] = byte(v >> 56) - return b[8:] -} - -// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and -// returning the remaining slice of b.. -func pstring(b []byte, s string) []byte { - b = pbit16(b, uint16(len(s))) - n := copy(b, s) - return b[n:] -} - -// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b. -func gbit8(b []byte) (uint8, []byte) { - return uint8(b[0]), b[1:] -} - -// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b. -func gbit16(b []byte) (uint16, []byte) { - return uint16(b[0]) | uint16(b[1])<<8, b[2:] -} - -// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b. -func gbit32(b []byte) (uint32, []byte) { - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:] -} - -// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b. -func gbit64(b []byte) (uint64, []byte) { - lo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - hi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24 - return uint64(lo) | uint64(hi)<<32, b[8:] -} - -// gstring reads a string from b, prefixed with a 16-bit length in little-endian order. -// It returns the string with the remaining slice of b and a boolean. If the length is -// greater than the number of bytes in b, the boolean will be false. -func gstring(b []byte) (string, []byte, bool) { - n, b := gbit16(b) - if int(n) > len(b) { - return "", b, false - } - return string(b[:n]), b[n:], true -} diff --git a/vendor/golang.org/x/sys/plan9/env_plan9.go b/vendor/golang.org/x/sys/plan9/env_plan9.go deleted file mode 100644 index 8f19180..0000000 --- a/vendor/golang.org/x/sys/plan9/env_plan9.go +++ /dev/null @@ -1,31 +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. - -// Plan 9 environment variables. - -package plan9 - -import ( - "syscall" -) - -func Getenv(key string) (value string, found bool) { - return syscall.Getenv(key) -} - -func Setenv(key, value string) error { - return syscall.Setenv(key, value) -} - -func Clearenv() { - syscall.Clearenv() -} - -func Environ() []string { - return syscall.Environ() -} - -func Unsetenv(key string) error { - return syscall.Unsetenv(key) -} diff --git a/vendor/golang.org/x/sys/plan9/errors_plan9.go b/vendor/golang.org/x/sys/plan9/errors_plan9.go deleted file mode 100644 index 65fe74d..0000000 --- a/vendor/golang.org/x/sys/plan9/errors_plan9.go +++ /dev/null @@ -1,50 +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 plan9 - -import "syscall" - -// Constants -const ( - // Invented values to support what package os expects. - O_CREAT = 0x02000 - O_APPEND = 0x00400 - O_NOCTTY = 0x00000 - O_NONBLOCK = 0x00000 - O_SYNC = 0x00000 - O_ASYNC = 0x00000 - - S_IFMT = 0x1f000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 -) - -// Errors -var ( - EINVAL = syscall.NewError("bad arg in system call") - ENOTDIR = syscall.NewError("not a directory") - EISDIR = syscall.NewError("file is a directory") - ENOENT = syscall.NewError("file does not exist") - EEXIST = syscall.NewError("file already exists") - EMFILE = syscall.NewError("no free file descriptors") - EIO = syscall.NewError("i/o error") - ENAMETOOLONG = syscall.NewError("file name too long") - EINTR = syscall.NewError("interrupted") - EPERM = syscall.NewError("permission denied") - EBUSY = syscall.NewError("no free devices") - ETIMEDOUT = syscall.NewError("connection timed out") - EPLAN9 = syscall.NewError("not supported by plan 9") - - // The following errors do not correspond to any - // Plan 9 system messages. Invented to support - // what package os and others expect. - EACCES = syscall.NewError("access permission denied") - EAFNOSUPPORT = syscall.NewError("address family not supported by protocol") -) diff --git a/vendor/golang.org/x/sys/plan9/mkall.sh b/vendor/golang.org/x/sys/plan9/mkall.sh deleted file mode 100755 index 9f73c60..0000000 --- a/vendor/golang.org/x/sys/plan9/mkall.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash -# 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. - -# The plan9 package provides access to the raw system call -# interface of the underlying operating system. Porting Go to -# a new architecture/operating system combination requires -# some manual effort, though there are tools that automate -# much of the process. The auto-generated files have names -# beginning with z. -# -# This script runs or (given -n) prints suggested commands to generate z files -# for the current system. Running those commands is not automatic. -# This script is documentation more than anything else. -# -# * asm_${GOOS}_${GOARCH}.s -# -# This hand-written assembly file implements system call dispatch. -# There are three entry points: -# -# func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr); -# func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr); -# func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr); -# -# The first and second are the standard ones; they differ only in -# how many arguments can be passed to the kernel. -# The third is for low-level use by the ForkExec wrapper; -# unlike the first two, it does not call into the scheduler to -# let it know that a system call is running. -# -# * syscall_${GOOS}.go -# -# This hand-written Go file implements system calls that need -# special handling and lists "//sys" comments giving prototypes -# for ones that can be auto-generated. Mksyscall reads those -# comments to generate the stubs. -# -# * syscall_${GOOS}_${GOARCH}.go -# -# Same as syscall_${GOOS}.go except that it contains code specific -# to ${GOOS} on one particular architecture. -# -# * types_${GOOS}.c -# -# This hand-written C file includes standard C headers and then -# creates typedef or enum names beginning with a dollar sign -# (use of $ in variable names is a gcc extension). The hardest -# part about preparing this file is figuring out which headers to -# include and which symbols need to be #defined to get the -# actual data structures that pass through to the kernel system calls. -# Some C libraries present alternate versions for binary compatibility -# and translate them on the way in and out of system calls, but -# there is almost always a #define that can get the real ones. -# See types_darwin.c and types_linux.c for examples. -# -# * zerror_${GOOS}_${GOARCH}.go -# -# This machine-generated file defines the system's error numbers, -# error strings, and signal numbers. The generator is "mkerrors.sh". -# Usually no arguments are needed, but mkerrors.sh will pass its -# arguments on to godefs. -# -# * zsyscall_${GOOS}_${GOARCH}.go -# -# Generated by mksyscall.pl; see syscall_${GOOS}.go above. -# -# * zsysnum_${GOOS}_${GOARCH}.go -# -# Generated by mksysnum_${GOOS}. -# -# * ztypes_${GOOS}_${GOARCH}.go -# -# Generated by godefs; see types_${GOOS}.c above. - -GOOSARCH="${GOOS}_${GOARCH}" - -# defaults -mksyscall="./mksyscall.pl" -mkerrors="./mkerrors.sh" -zerrors="zerrors_$GOOSARCH.go" -mksysctl="" -zsysctl="zsysctl_$GOOSARCH.go" -mksysnum= -mktypes= -run="sh" - -case "$1" in --syscalls) - for i in zsyscall*go - do - sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i - rm _$i - done - exit 0 - ;; --n) - run="cat" - shift -esac - -case "$#" in -0) - ;; -*) - echo 'usage: mkall.sh [-n]' 1>&2 - exit 2 -esac - -case "$GOOSARCH" in -_* | *_ | _) - echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2 - exit 1 - ;; -plan9_386) - mkerrors= - mksyscall="./mksyscall.pl -l32 -plan9" - mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h" - mktypes="XXX" - ;; -*) - echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2 - exit 1 - ;; -esac - -( - if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi - case "$GOOS" in - plan9) - syscall_goos="syscall_$GOOS.go" - if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi - ;; - esac - if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi - if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi - if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi -) | $run diff --git a/vendor/golang.org/x/sys/plan9/mkerrors.sh b/vendor/golang.org/x/sys/plan9/mkerrors.sh deleted file mode 100755 index 052c86d..0000000 --- a/vendor/golang.org/x/sys/plan9/mkerrors.sh +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env bash -# 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. - -# Generate Go code listing errors and other #defined constant -# values (ENAMETOOLONG etc.), by asking the preprocessor -# about the definitions. - -unset LANG -export LC_ALL=C -export LC_CTYPE=C - -CC=${CC:-gcc} - -uname=$(uname) - -includes=' -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -' - -ccflags="$@" - -# Write go tool cgo -godefs input. -( - echo package plan9 - echo - echo '/*' - indirect="includes_$(uname)" - echo "${!indirect} $includes" - echo '*/' - echo 'import "C"' - echo - echo 'const (' - - # The gcc command line prints all the #defines - # it encounters while processing the input - echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags | - awk ' - $1 != "#define" || $2 ~ /\(/ || $3 == "" {next} - - $2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers - $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next} - $2 ~ /^(SCM_SRCRT)$/ {next} - $2 ~ /^(MAP_FAILED)$/ {next} - - $2 !~ /^ETH_/ && - $2 !~ /^EPROC_/ && - $2 !~ /^EQUIV_/ && - $2 !~ /^EXPR_/ && - $2 ~ /^E[A-Z0-9_]+$/ || - $2 ~ /^B[0-9_]+$/ || - $2 ~ /^V[A-Z0-9]+$/ || - $2 ~ /^CS[A-Z0-9]/ || - $2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ || - $2 ~ /^IGN/ || - $2 ~ /^IX(ON|ANY|OFF)$/ || - $2 ~ /^IN(LCR|PCK)$/ || - $2 ~ /(^FLU?SH)|(FLU?SH$)/ || - $2 ~ /^C(LOCAL|READ)$/ || - $2 == "BRKINT" || - $2 == "HUPCL" || - $2 == "PENDIN" || - $2 == "TOSTOP" || - $2 ~ /^PAR/ || - $2 ~ /^SIG[^_]/ || - $2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ || - $2 ~ /^IN_/ || - $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || - $2 == "ICMPV6_FILTER" || - $2 == "SOMAXCONN" || - $2 == "NAME_MAX" || - $2 == "IFNAMSIZ" || - $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ || - $2 ~ /^SYSCTL_VERS/ || - $2 ~ /^(MS|MNT)_/ || - $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || - $2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ || - $2 ~ /^LINUX_REBOOT_CMD_/ || - $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || - $2 !~ "NLA_TYPE_MASK" && - $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ || - $2 ~ /^SIOC/ || - $2 ~ /^TIOC/ || - $2 !~ "RTF_BITS" && - $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ || - $2 ~ /^BIOC/ || - $2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ || - $2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ || - $2 ~ /^PRIO_(PROCESS|PGRP|USER)/ || - $2 ~ /^CLONE_[A-Z_]+/ || - $2 !~ /^(BPF_TIMEVAL)$/ && - $2 ~ /^(BPF|DLT)_/ || - $2 !~ "WMESGLEN" && - $2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)} - $2 ~ /^__WCOREFLAG$/ {next} - $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} - - {next} - ' | sort - - echo ')' -) >_const.go - -# Pull out the error names for later. -errors=$( - echo '#include ' | $CC -x c - -E -dM $ccflags | - awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' | - sort -) - -# Pull out the signal names for later. -signals=$( - echo '#include ' | $CC -x c - -E -dM $ccflags | - awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | - egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' | - sort -) - -# Again, writing regexps to a file. -echo '#include ' | $CC -x c - -E -dM $ccflags | - awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' | - sort >_error.grep -echo '#include ' | $CC -x c - -E -dM $ccflags | - awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | - egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' | - sort >_signal.grep - -echo '// mkerrors.sh' "$@" -echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT' -echo -go tool cgo -godefs -- "$@" _const.go >_error.out -cat _error.out | grep -vf _error.grep | grep -vf _signal.grep -echo -echo '// Errors' -echo 'const (' -cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/' -echo ')' - -echo -echo '// Signals' -echo 'const (' -cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/' -echo ')' - -# Run C program to print error and syscall strings. -( - echo -E " -#include -#include -#include -#include -#include -#include - -#define nelem(x) (sizeof(x)/sizeof((x)[0])) - -enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below - -int errors[] = { -" - for i in $errors - do - echo -E ' '$i, - done - - echo -E " -}; - -int signals[] = { -" - for i in $signals - do - echo -E ' '$i, - done - - # Use -E because on some systems bash builtin interprets \n itself. - echo -E ' -}; - -static int -intcmp(const void *a, const void *b) -{ - return *(int*)a - *(int*)b; -} - -int -main(void) -{ - int i, j, e; - char buf[1024], *p; - - printf("\n\n// Error table\n"); - printf("var errors = [...]string {\n"); - qsort(errors, nelem(errors), sizeof errors[0], intcmp); - for(i=0; i 0 && errors[i-1] == e) - continue; - strcpy(buf, strerror(e)); - // lowercase first letter: Bad -> bad, but STREAM -> STREAM. - if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) - buf[0] += a - A; - printf("\t%d: \"%s\",\n", e, buf); - } - printf("}\n\n"); - - printf("\n\n// Signal table\n"); - printf("var signals = [...]string {\n"); - qsort(signals, nelem(signals), sizeof signals[0], intcmp); - for(i=0; i 0 && signals[i-1] == e) - continue; - strcpy(buf, strsignal(e)); - // lowercase first letter: Bad -> bad, but STREAM -> STREAM. - if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) - buf[0] += a - A; - // cut trailing : number. - p = strrchr(buf, ":"[0]); - if(p) - *p = '\0'; - printf("\t%d: \"%s\",\n", e, buf); - } - printf("}\n\n"); - - return 0; -} - -' -) >_errors.c - -$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out diff --git a/vendor/golang.org/x/sys/plan9/mksyscall.pl b/vendor/golang.org/x/sys/plan9/mksyscall.pl deleted file mode 100755 index ce8e1e4..0000000 --- a/vendor/golang.org/x/sys/plan9/mksyscall.pl +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/env perl -# 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. - -# This program reads a file containing function prototypes -# (like syscall_plan9.go) and generates system call bodies. -# The prototypes are marked by lines beginning with "//sys" -# and read like func declarations if //sys is replaced by func, but: -# * The parameter lists must give a name for each argument. -# This includes return parameters. -# * The parameter lists must give a type for each argument: -# the (x, y, z int) shorthand is not allowed. -# * If the return parameter is an error number, it must be named errno. - -# A line beginning with //sysnb is like //sys, except that the -# goroutine will not be suspended during the execution of the system -# call. This must only be used for system calls which can never -# block, as otherwise the system call could cause all goroutines to -# hang. - -use strict; - -my $cmdline = "mksyscall.pl " . join(' ', @ARGV); -my $errors = 0; -my $_32bit = ""; -my $plan9 = 0; -my $openbsd = 0; -my $netbsd = 0; -my $dragonfly = 0; -my $nacl = 0; -my $arm = 0; # 64-bit value should use (even, odd)-pair - -if($ARGV[0] eq "-b32") { - $_32bit = "big-endian"; - shift; -} elsif($ARGV[0] eq "-l32") { - $_32bit = "little-endian"; - shift; -} -if($ARGV[0] eq "-plan9") { - $plan9 = 1; - shift; -} -if($ARGV[0] eq "-openbsd") { - $openbsd = 1; - shift; -} -if($ARGV[0] eq "-netbsd") { - $netbsd = 1; - shift; -} -if($ARGV[0] eq "-dragonfly") { - $dragonfly = 1; - shift; -} -if($ARGV[0] eq "-nacl") { - $nacl = 1; - shift; -} -if($ARGV[0] eq "-arm") { - $arm = 1; - shift; -} - -if($ARGV[0] =~ /^-/) { - print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n"; - exit 1; -} - -sub parseparamlist($) { - my ($list) = @_; - $list =~ s/^\s*//; - $list =~ s/\s*$//; - if($list eq "") { - return (); - } - return split(/\s*,\s*/, $list); -} - -sub parseparam($) { - my ($p) = @_; - if($p !~ /^(\S*) (\S*)$/) { - print STDERR "$ARGV:$.: malformed parameter: $p\n"; - $errors = 1; - return ("xx", "int"); - } - return ($1, $2); -} - -my $text = ""; -while(<>) { - chomp; - s/\s+/ /g; - s/^\s+//; - s/\s+$//; - my $nonblock = /^\/\/sysnb /; - next if !/^\/\/sys / && !$nonblock; - - # Line must be of the form - # func Open(path string, mode int, perm int) (fd int, errno error) - # Split into name, in params, out params. - if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) { - print STDERR "$ARGV:$.: malformed //sys declaration\n"; - $errors = 1; - next; - } - my ($func, $in, $out, $sysname) = ($2, $3, $4, $5); - - # Split argument lists on comma. - my @in = parseparamlist($in); - my @out = parseparamlist($out); - - # Try in vain to keep people from editing this file. - # The theory is that they jump into the middle of the file - # without reading the header. - $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; - - # Go function header. - my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : ""; - $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl; - - # Check if err return available - my $errvar = ""; - foreach my $p (@out) { - my ($name, $type) = parseparam($p); - if($type eq "error") { - $errvar = $name; - last; - } - } - - # Prepare arguments to Syscall. - my @args = (); - my @uses = (); - my $n = 0; - foreach my $p (@in) { - my ($name, $type) = parseparam($p); - if($type =~ /^\*/) { - push @args, "uintptr(unsafe.Pointer($name))"; - } elsif($type eq "string" && $errvar ne "") { - $text .= "\tvar _p$n *byte\n"; - $text .= "\t_p$n, $errvar = BytePtrFromString($name)\n"; - $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; - push @args, "uintptr(unsafe.Pointer(_p$n))"; - push @uses, "use(unsafe.Pointer(_p$n))"; - $n++; - } elsif($type eq "string") { - print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; - $text .= "\tvar _p$n *byte\n"; - $text .= "\t_p$n, _ = BytePtrFromString($name)\n"; - push @args, "uintptr(unsafe.Pointer(_p$n))"; - push @uses, "use(unsafe.Pointer(_p$n))"; - $n++; - } elsif($type =~ /^\[\](.*)/) { - # Convert slice into pointer, length. - # Have to be careful not to take address of &a[0] if len == 0: - # pass dummy pointer in that case. - # Used to pass nil, but some OSes or simulators reject write(fd, nil, 0). - $text .= "\tvar _p$n unsafe.Pointer\n"; - $text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}"; - $text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}"; - $text .= "\n"; - push @args, "uintptr(_p$n)", "uintptr(len($name))"; - $n++; - } elsif($type eq "int64" && ($openbsd || $netbsd)) { - push @args, "0"; - if($_32bit eq "big-endian") { - push @args, "uintptr($name>>32)", "uintptr($name)"; - } elsif($_32bit eq "little-endian") { - push @args, "uintptr($name)", "uintptr($name>>32)"; - } else { - push @args, "uintptr($name)"; - } - } elsif($type eq "int64" && $dragonfly) { - if ($func !~ /^extp(read|write)/i) { - push @args, "0"; - } - if($_32bit eq "big-endian") { - push @args, "uintptr($name>>32)", "uintptr($name)"; - } elsif($_32bit eq "little-endian") { - push @args, "uintptr($name)", "uintptr($name>>32)"; - } else { - push @args, "uintptr($name)"; - } - } elsif($type eq "int64" && $_32bit ne "") { - if(@args % 2 && $arm) { - # arm abi specifies 64-bit argument uses - # (even, odd) pair - push @args, "0" - } - if($_32bit eq "big-endian") { - push @args, "uintptr($name>>32)", "uintptr($name)"; - } else { - push @args, "uintptr($name)", "uintptr($name>>32)"; - } - } else { - push @args, "uintptr($name)"; - } - } - - # Determine which form to use; pad args with zeros. - my $asm = "Syscall"; - if ($nonblock) { - $asm = "RawSyscall"; - } - if(@args <= 3) { - while(@args < 3) { - push @args, "0"; - } - } elsif(@args <= 6) { - $asm .= "6"; - while(@args < 6) { - push @args, "0"; - } - } elsif(@args <= 9) { - $asm .= "9"; - while(@args < 9) { - push @args, "0"; - } - } else { - print STDERR "$ARGV:$.: too many arguments to system call\n"; - } - - # System call number. - if($sysname eq "") { - $sysname = "SYS_$func"; - $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar - $sysname =~ y/a-z/A-Z/; - if($nacl) { - $sysname =~ y/A-Z/a-z/; - } - } - - # Actual call. - my $args = join(', ', @args); - my $call = "$asm($sysname, $args)"; - - # Assign return values. - my $body = ""; - my @ret = ("_", "_", "_"); - my $do_errno = 0; - for(my $i=0; $i<@out; $i++) { - my $p = $out[$i]; - my ($name, $type) = parseparam($p); - my $reg = ""; - if($name eq "err" && !$plan9) { - $reg = "e1"; - $ret[2] = $reg; - $do_errno = 1; - } elsif($name eq "err" && $plan9) { - $ret[0] = "r0"; - $ret[2] = "e1"; - next; - } else { - $reg = sprintf("r%d", $i); - $ret[$i] = $reg; - } - if($type eq "bool") { - $reg = "$reg != 0"; - } - if($type eq "int64" && $_32bit ne "") { - # 64-bit number in r1:r0 or r0:r1. - if($i+2 > @out) { - print STDERR "$ARGV:$.: not enough registers for int64 return\n"; - } - if($_32bit eq "big-endian") { - $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); - } else { - $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); - } - $ret[$i] = sprintf("r%d", $i); - $ret[$i+1] = sprintf("r%d", $i+1); - } - if($reg ne "e1" || $plan9) { - $body .= "\t$name = $type($reg)\n"; - } - } - if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { - $text .= "\t$call\n"; - } else { - $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; - } - foreach my $use (@uses) { - $text .= "\t$use\n"; - } - $text .= $body; - - if ($plan9 && $ret[2] eq "e1") { - $text .= "\tif int32(r0) == -1 {\n"; - $text .= "\t\terr = e1\n"; - $text .= "\t}\n"; - } elsif ($do_errno) { - $text .= "\tif e1 != 0 {\n"; - $text .= "\t\terr = e1\n"; - $text .= "\t}\n"; - } - $text .= "\treturn\n"; - $text .= "}\n\n"; -} - -chomp $text; -chomp $text; - -if($errors) { - exit 1; -} - -print <= 10 { - buf[i] = byte(val%10 + '0') - i-- - val /= 10 - } - buf[i] = byte(val + '0') - return string(buf[i:]) -} diff --git a/vendor/golang.org/x/sys/plan9/syscall.go b/vendor/golang.org/x/sys/plan9/syscall.go deleted file mode 100644 index 5046cfe..0000000 --- a/vendor/golang.org/x/sys/plan9/syscall.go +++ /dev/null @@ -1,74 +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 plan9 - -// Package plan9 contains an interface to the low-level operating system -// primitives. OS details vary depending on the underlying system, and -// by default, godoc will display the OS-specific documentation for the current -// system. If you want godoc to display documentation for another -// system, set $GOOS and $GOARCH to the desired system. For example, if -// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS -// to freebsd and $GOARCH to arm. -// The primary use of this package is inside other packages that provide a more -// portable interface to the system, such as "os", "time" and "net". Use -// those packages rather than this one if you can. -// For details of the functions and data types in this package consult -// the manuals for the appropriate operating system. -// These calls return err == nil to indicate success; otherwise -// err represents an operating system error describing the failure and -// holds a value of type syscall.ErrorString. -package plan9 // import "golang.org/x/sys/plan9" - -import "unsafe" - -// ByteSliceFromString returns a NUL-terminated slice of bytes -// containing the text of s. If s contains a NUL byte at any -// location, it returns (nil, EINVAL). -func ByteSliceFromString(s string) ([]byte, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, EINVAL - } - } - a := make([]byte, len(s)+1) - copy(a, s) - return a, nil -} - -// BytePtrFromString returns a pointer to a NUL-terminated array of -// bytes containing the text of s. If s contains a NUL byte at any -// location, it returns (nil, EINVAL). -func BytePtrFromString(s string) (*byte, error) { - a, err := ByteSliceFromString(s) - if err != nil { - return nil, err - } - return &a[0], nil -} - -// Single-word zero for use when we need a valid pointer to 0 bytes. -// See mksyscall.pl. -var _zero uintptr - -func (ts *Timespec) Unix() (sec int64, nsec int64) { - return int64(ts.Sec), int64(ts.Nsec) -} - -func (tv *Timeval) Unix() (sec int64, nsec int64) { - return int64(tv.Sec), int64(tv.Usec) * 1000 -} - -func (ts *Timespec) Nano() int64 { - return int64(ts.Sec)*1e9 + int64(ts.Nsec) -} - -func (tv *Timeval) Nano() int64 { - return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 -} - -// use is a no-op, but the compiler cannot see that it is. -// Calling use(p) ensures that p is kept live until that point. -//go:noescape -func use(p unsafe.Pointer) diff --git a/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/vendor/golang.org/x/sys/plan9/syscall_plan9.go deleted file mode 100644 index d39d07d..0000000 --- a/vendor/golang.org/x/sys/plan9/syscall_plan9.go +++ /dev/null @@ -1,349 +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. - -// Plan 9 system calls. -// This file is compiled as ordinary Go code, -// but it is also input to mksyscall, -// which parses the //sys lines and generates system call stubs. -// Note that sometimes we use a lowercase //sys name and -// wrap it in our own nicer implementation. - -package plan9 - -import ( - "syscall" - "unsafe" -) - -// A Note is a string describing a process note. -// It implements the os.Signal interface. -type Note string - -func (n Note) Signal() {} - -func (n Note) String() string { - return string(n) -} - -var ( - Stdin = 0 - Stdout = 1 - Stderr = 2 -) - -// For testing: clients can set this flag to force -// creation of IPv6 sockets to return EAFNOSUPPORT. -var SocketDisableIPv6 bool - -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString) -func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString) -func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) -func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) - -func atoi(b []byte) (n uint) { - n = 0 - for i := 0; i < len(b); i++ { - n = n*10 + uint(b[i]-'0') - } - return -} - -func cstring(s []byte) string { - for i := range s { - if s[i] == 0 { - return string(s[0:i]) - } - } - return string(s) -} - -func errstr() string { - var buf [ERRMAX]byte - - RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) - - buf[len(buf)-1] = 0 - return cstring(buf[:]) -} - -// Implemented in assembly to import from runtime. -func exit(code int) - -func Exit(code int) { exit(code) } - -func readnum(path string) (uint, error) { - var b [12]byte - - fd, e := Open(path, O_RDONLY) - if e != nil { - return 0, e - } - defer Close(fd) - - n, e := Pread(fd, b[:], 0) - - if e != nil { - return 0, e - } - - m := 0 - for ; m < n && b[m] == ' '; m++ { - } - - return atoi(b[m : n-1]), nil -} - -func Getpid() (pid int) { - n, _ := readnum("#c/pid") - return int(n) -} - -func Getppid() (ppid int) { - n, _ := readnum("#c/ppid") - return int(n) -} - -func Read(fd int, p []byte) (n int, err error) { - return Pread(fd, p, -1) -} - -func Write(fd int, p []byte) (n int, err error) { - return Pwrite(fd, p, -1) -} - -var ioSync int64 - -//sys fd2path(fd int, buf []byte) (err error) -func Fd2path(fd int) (path string, err error) { - var buf [512]byte - - e := fd2path(fd, buf[:]) - if e != nil { - return "", e - } - return cstring(buf[:]), nil -} - -//sys pipe(p *[2]int32) (err error) -func Pipe(p []int) (err error) { - if len(p) != 2 { - return syscall.ErrorString("bad arg in system call") - } - var pp [2]int32 - err = pipe(&pp) - p[0] = int(pp[0]) - p[1] = int(pp[1]) - return -} - -// Underlying system call writes to newoffset via pointer. -// Implemented in assembly to avoid allocation. -func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string) - -func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { - newoffset, e := seek(0, fd, offset, whence) - - if newoffset == -1 { - err = syscall.ErrorString(e) - } - return -} - -func Mkdir(path string, mode uint32) (err error) { - fd, err := Create(path, O_RDONLY, DMDIR|mode) - - if fd != -1 { - Close(fd) - } - - return -} - -type Waitmsg struct { - Pid int - Time [3]uint32 - Msg string -} - -func (w Waitmsg) Exited() bool { return true } -func (w Waitmsg) Signaled() bool { return false } - -func (w Waitmsg) ExitStatus() int { - if len(w.Msg) == 0 { - // a normal exit returns no message - return 0 - } - return 1 -} - -//sys await(s []byte) (n int, err error) -func Await(w *Waitmsg) (err error) { - var buf [512]byte - var f [5][]byte - - n, err := await(buf[:]) - - if err != nil || w == nil { - return - } - - nf := 0 - p := 0 - for i := 0; i < n && nf < len(f)-1; i++ { - if buf[i] == ' ' { - f[nf] = buf[p:i] - p = i + 1 - nf++ - } - } - f[nf] = buf[p:] - nf++ - - if nf != len(f) { - return syscall.ErrorString("invalid wait message") - } - w.Pid = int(atoi(f[0])) - w.Time[0] = uint32(atoi(f[1])) - w.Time[1] = uint32(atoi(f[2])) - w.Time[2] = uint32(atoi(f[3])) - w.Msg = cstring(f[4]) - if w.Msg == "''" { - // await() returns '' for no error - w.Msg = "" - } - return -} - -func Unmount(name, old string) (err error) { - fixwd() - oldp, err := BytePtrFromString(old) - if err != nil { - return err - } - oldptr := uintptr(unsafe.Pointer(oldp)) - - var r0 uintptr - var e syscall.ErrorString - - // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted. - if name == "" { - r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0) - } else { - namep, err := BytePtrFromString(name) - if err != nil { - return err - } - r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0) - } - - if int32(r0) == -1 { - err = e - } - return -} - -func Fchdir(fd int) (err error) { - path, err := Fd2path(fd) - - if err != nil { - return - } - - return Chdir(path) -} - -type Timespec struct { - Sec int32 - Nsec int32 -} - -type Timeval struct { - Sec int32 - Usec int32 -} - -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int32(nsec / 1e9) - return -} - -func nsec() int64 { - var scratch int64 - - r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0) - // TODO(aram): remove hack after I fix _nsec in the pc64 kernel. - if r0 == 0 { - return scratch - } - return int64(r0) -} - -func Gettimeofday(tv *Timeval) error { - nsec := nsec() - *tv = NsecToTimeval(nsec) - return nil -} - -func Getpagesize() int { return 0x1000 } - -func Getegid() (egid int) { return -1 } -func Geteuid() (euid int) { return -1 } -func Getgid() (gid int) { return -1 } -func Getuid() (uid int) { return -1 } - -func Getgroups() (gids []int, err error) { - return make([]int, 0), nil -} - -//sys open(path string, mode int) (fd int, err error) -func Open(path string, mode int) (fd int, err error) { - fixwd() - return open(path, mode) -} - -//sys create(path string, mode int, perm uint32) (fd int, err error) -func Create(path string, mode int, perm uint32) (fd int, err error) { - fixwd() - return create(path, mode, perm) -} - -//sys remove(path string) (err error) -func Remove(path string) error { - fixwd() - return remove(path) -} - -//sys stat(path string, edir []byte) (n int, err error) -func Stat(path string, edir []byte) (n int, err error) { - fixwd() - return stat(path, edir) -} - -//sys bind(name string, old string, flag int) (err error) -func Bind(name string, old string, flag int) (err error) { - fixwd() - return bind(name, old, flag) -} - -//sys mount(fd int, afd int, old string, flag int, aname string) (err error) -func Mount(fd int, afd int, old string, flag int, aname string) (err error) { - fixwd() - return mount(fd, afd, old, flag, aname) -} - -//sys wstat(path string, edir []byte) (err error) -func Wstat(path string, edir []byte) (err error) { - fixwd() - return wstat(path, edir) -} - -//sys chdir(path string) (err error) -//sys Dup(oldfd int, newfd int) (fd int, err error) -//sys Pread(fd int, p []byte, offset int64) (n int, err error) -//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) -//sys Close(fd int) (err error) -//sys Fstat(fd int, edir []byte) (n int, err error) -//sys Fwstat(fd int, edir []byte) (err error) diff --git a/vendor/golang.org/x/sys/plan9/syscall_test.go b/vendor/golang.org/x/sys/plan9/syscall_test.go deleted file mode 100644 index 8f829ba..0000000 --- a/vendor/golang.org/x/sys/plan9/syscall_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2013 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 plan9_test - -import ( - "testing" - - "golang.org/x/sys/plan9" -) - -func testSetGetenv(t *testing.T, key, value string) { - err := plan9.Setenv(key, value) - if err != nil { - t.Fatalf("Setenv failed to set %q: %v", value, err) - } - newvalue, found := plan9.Getenv(key) - if !found { - t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value) - } - if newvalue != value { - t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value) - } -} - -func TestEnv(t *testing.T) { - testSetGetenv(t, "TESTENV", "AVALUE") - // make sure TESTENV gets set to "", not deleted - testSetGetenv(t, "TESTENV", "") -} diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go deleted file mode 100644 index b35598a..0000000 --- a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go +++ /dev/null @@ -1,292 +0,0 @@ -// mksyscall.pl -l32 -plan9 syscall_plan9.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package plan9 - -import "unsafe" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fd2path(fd int, buf []byte) (err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf))) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func pipe(p *[2]int32) (err error) { - r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func await(s []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(s) > 0 { - _p0 = unsafe.Pointer(&s[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func open(path string, mode int) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func create(path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func remove(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func stat(path string, edir []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(edir) > 0 { - _p1 = unsafe.Pointer(&edir[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) - use(unsafe.Pointer(_p0)) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func bind(name string, old string, flag int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(name) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(old) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) - use(unsafe.Pointer(_p0)) - use(unsafe.Pointer(_p1)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func mount(fd int, afd int, old string, flag int, aname string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(old) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(aname) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0) - use(unsafe.Pointer(_p0)) - use(unsafe.Pointer(_p1)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func wstat(path string, edir []byte) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(edir) > 0 { - _p1 = unsafe.Pointer(&edir[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func chdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup(oldfd int, newfd int) (fd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pread(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pwrite(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Close(fd int) (err error) { - r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, edir []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(edir) > 0 { - _p0 = unsafe.Pointer(&edir[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fwstat(fd int, edir []byte) (err error) { - var _p0 unsafe.Pointer - if len(edir) > 0 { - _p0 = unsafe.Pointer(&edir[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) - if int32(r0) == -1 { - err = e1 - } - return -} diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go deleted file mode 100644 index b35598a..0000000 --- a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go +++ /dev/null @@ -1,292 +0,0 @@ -// mksyscall.pl -l32 -plan9 syscall_plan9.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package plan9 - -import "unsafe" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func fd2path(fd int, buf []byte) (err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf))) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func pipe(p *[2]int32) (err error) { - r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func await(s []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(s) > 0 { - _p0 = unsafe.Pointer(&s[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func open(path string, mode int) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func create(path string, mode int, perm uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func remove(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func stat(path string, edir []byte) (n int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(edir) > 0 { - _p1 = unsafe.Pointer(&edir[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) - use(unsafe.Pointer(_p0)) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func bind(name string, old string, flag int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(name) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(old) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) - use(unsafe.Pointer(_p0)) - use(unsafe.Pointer(_p1)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func mount(fd int, afd int, old string, flag int, aname string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(old) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(aname) - if err != nil { - return - } - r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0) - use(unsafe.Pointer(_p0)) - use(unsafe.Pointer(_p1)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func wstat(path string, edir []byte) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - var _p1 unsafe.Pointer - if len(edir) > 0 { - _p1 = unsafe.Pointer(&edir[0]) - } else { - _p1 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func chdir(path string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) - use(unsafe.Pointer(_p0)) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Dup(oldfd int, newfd int) (fd int, err error) { - r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0) - fd = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pread(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Pwrite(fd int, p []byte, offset int64) (n int, err error) { - var _p0 unsafe.Pointer - if len(p) > 0 { - _p0 = unsafe.Pointer(&p[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Close(fd int) (err error) { - r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fstat(fd int, edir []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(edir) > 0 { - _p0 = unsafe.Pointer(&edir[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) - n = int(r0) - if int32(r0) == -1 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fwstat(fd int, edir []byte) (err error) { - var _p0 unsafe.Pointer - if len(edir) > 0 { - _p0 = unsafe.Pointer(&edir[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) - if int32(r0) == -1 { - err = e1 - } - return -} diff --git a/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go b/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go deleted file mode 100644 index 22e8abd..0000000 --- a/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go +++ /dev/null @@ -1,49 +0,0 @@ -// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT - -package plan9 - -const ( - SYS_SYSR1 = 0 - SYS_BIND = 2 - SYS_CHDIR = 3 - SYS_CLOSE = 4 - SYS_DUP = 5 - SYS_ALARM = 6 - SYS_EXEC = 7 - SYS_EXITS = 8 - SYS_FAUTH = 10 - SYS_SEGBRK = 12 - SYS_OPEN = 14 - SYS_OSEEK = 16 - SYS_SLEEP = 17 - SYS_RFORK = 19 - SYS_PIPE = 21 - SYS_CREATE = 22 - SYS_FD2PATH = 23 - SYS_BRK_ = 24 - SYS_REMOVE = 25 - SYS_NOTIFY = 28 - SYS_NOTED = 29 - SYS_SEGATTACH = 30 - SYS_SEGDETACH = 31 - SYS_SEGFREE = 32 - SYS_SEGFLUSH = 33 - SYS_RENDEZVOUS = 34 - SYS_UNMOUNT = 35 - SYS_SEMACQUIRE = 37 - SYS_SEMRELEASE = 38 - SYS_SEEK = 39 - SYS_FVERSION = 40 - SYS_ERRSTR = 41 - SYS_STAT = 42 - SYS_FSTAT = 43 - SYS_WSTAT = 44 - SYS_FWSTAT = 45 - SYS_MOUNT = 46 - SYS_AWAIT = 47 - SYS_PREAD = 50 - SYS_PWRITE = 51 - SYS_TSEMACQUIRE = 52 - SYS_NSEC = 53 -) diff --git a/vendor/golang.org/x/sys/unix/linux/Dockerfile b/vendor/golang.org/x/sys/unix/linux/Dockerfile deleted file mode 100644 index 7fe5fc3..0000000 --- a/vendor/golang.org/x/sys/unix/linux/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -FROM ubuntu:16.04 - -# Use the most recent ubuntu sources -RUN echo 'deb http://en.archive.ubuntu.com/ubuntu/ artful main universe' >> /etc/apt/sources.list - -# Dependencies to get the git sources and go binaries -RUN apt-get update && apt-get install -y \ - curl \ - git \ - && rm -rf /var/lib/apt/lists/* - -# Get the git sources. If not cached, this takes O(5 minutes). -WORKDIR /git -RUN git config --global advice.detachedHead false -# Linux Kernel: Released 03 Sep 2017 -RUN git clone --branch v4.13 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux -# GNU C library: Released 02 Aug 2017 (we should try to get a secure way to clone this) -RUN git clone --branch glibc-2.26 --depth 1 git://sourceware.org/git/glibc.git - -# Get Go 1.9.2 -ENV GOLANG_VERSION 1.9.2 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 de874549d9a8d8d8062be05808509c09a88a248e77ec14eb77453530829ac02b - -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ - && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz - -ENV PATH /usr/local/go/bin:$PATH - -# Linux and Glibc build dependencies -RUN apt-get update && apt-get install -y \ - gawk make python \ - gcc gcc-multilib \ - gettext texinfo \ - && rm -rf /var/lib/apt/lists/* -# Emulator and cross compilers -RUN apt-get update && apt-get install -y \ - qemu \ - gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi \ - gcc-mips-linux-gnu gcc-mips64-linux-gnuabi64 \ - gcc-mips64el-linux-gnuabi64 gcc-mipsel-linux-gnu \ - gcc-powerpc64-linux-gnu gcc-powerpc64le-linux-gnu \ - gcc-s390x-linux-gnu gcc-sparc64-linux-gnu \ - && rm -rf /var/lib/apt/lists/* - -# Let the scripts know they are in the docker environment -ENV GOLANG_SYS_BUILD docker -WORKDIR /build -ENTRYPOINT ["go", "run", "linux/mkall.go", "/git/linux", "/git/glibc"] diff --git a/vendor/golang.org/x/sys/unix/linux/mkall.go b/vendor/golang.org/x/sys/unix/linux/mkall.go deleted file mode 100644 index 89b2fe8..0000000 --- a/vendor/golang.org/x/sys/unix/linux/mkall.go +++ /dev/null @@ -1,482 +0,0 @@ -// Copyright 2017 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. - -// linux/mkall.go - Generates all Linux zsysnum, zsyscall, zerror, and ztype -// files for all 11 linux architectures supported by the go compiler. See -// README.md for more information about the build system. - -// To run it you must have a git checkout of the Linux kernel and glibc. Once -// the appropriate sources are ready, the program is run as: -// go run linux/mkall.go - -// +build ignore - -package main - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "unicode" -) - -// These will be paths to the appropriate source directories. -var LinuxDir string -var GlibcDir string - -const TempDir = "/tmp" -const IncludeDir = TempDir + "/include" // To hold our C headers -const BuildDir = TempDir + "/build" // To hold intermediate build files - -const GOOS = "linux" // Only for Linux targets -const BuildArch = "amd64" // Must be built on this architecture -const MinKernel = "2.6.23" // https://golang.org/doc/install#requirements - -type target struct { - GoArch string // Architecture name according to Go - LinuxArch string // Architecture name according to the Linux Kernel - GNUArch string // Architecture name according to GNU tools (https://wiki.debian.org/Multiarch/Tuples) - BigEndian bool // Default Little Endian - SignedChar bool // Is -fsigned-char needed (default no) - Bits int -} - -// List of the 11 Linux targets supported by the go compiler. sparc64 is not -// currently supported, though a port is in progress. -var targets = []target{ - { - GoArch: "386", - LinuxArch: "x86", - GNUArch: "i686-linux-gnu", // Note "i686" not "i386" - Bits: 32, - }, - { - GoArch: "amd64", - LinuxArch: "x86", - GNUArch: "x86_64-linux-gnu", - Bits: 64, - }, - { - GoArch: "arm64", - LinuxArch: "arm64", - GNUArch: "aarch64-linux-gnu", - SignedChar: true, - Bits: 64, - }, - { - GoArch: "arm", - LinuxArch: "arm", - GNUArch: "arm-linux-gnueabi", - Bits: 32, - }, - { - GoArch: "mips", - LinuxArch: "mips", - GNUArch: "mips-linux-gnu", - BigEndian: true, - Bits: 32, - }, - { - GoArch: "mipsle", - LinuxArch: "mips", - GNUArch: "mipsel-linux-gnu", - Bits: 32, - }, - { - GoArch: "mips64", - LinuxArch: "mips", - GNUArch: "mips64-linux-gnuabi64", - BigEndian: true, - Bits: 64, - }, - { - GoArch: "mips64le", - LinuxArch: "mips", - GNUArch: "mips64el-linux-gnuabi64", - Bits: 64, - }, - { - GoArch: "ppc64", - LinuxArch: "powerpc", - GNUArch: "powerpc64-linux-gnu", - BigEndian: true, - Bits: 64, - }, - { - GoArch: "ppc64le", - LinuxArch: "powerpc", - GNUArch: "powerpc64le-linux-gnu", - Bits: 64, - }, - { - GoArch: "s390x", - LinuxArch: "s390", - GNUArch: "s390x-linux-gnu", - BigEndian: true, - SignedChar: true, - Bits: 64, - }, - // { - // GoArch: "sparc64", - // LinuxArch: "sparc", - // GNUArch: "sparc64-linux-gnu", - // BigEndian: true, - // Bits: 64, - // }, -} - -// ptracePairs is a list of pairs of targets that can, in some cases, -// run each other's binaries. -var ptracePairs = []struct{ a1, a2 string }{ - {"386", "amd64"}, - {"arm", "arm64"}, - {"mips", "mips64"}, - {"mipsle", "mips64le"}, -} - -func main() { - if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch { - fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n", - runtime.GOOS, runtime.GOARCH, GOOS, BuildArch) - return - } - - // Check that we are using the new build system if we should - if os.Getenv("GOLANG_SYS_BUILD") != "docker" { - fmt.Println("In the new build system, mkall.go should not be called directly.") - fmt.Println("See README.md") - return - } - - // Parse the command line options - if len(os.Args) != 3 { - fmt.Println("USAGE: go run linux/mkall.go ") - return - } - LinuxDir = os.Args[1] - GlibcDir = os.Args[2] - - for _, t := range targets { - fmt.Printf("----- GENERATING: %s -----\n", t.GoArch) - if err := t.generateFiles(); err != nil { - fmt.Printf("%v\n***** FAILURE: %s *****\n\n", err, t.GoArch) - } else { - fmt.Printf("----- SUCCESS: %s -----\n\n", t.GoArch) - } - } - - fmt.Printf("----- GENERATING ptrace pairs -----\n") - ok := true - for _, p := range ptracePairs { - if err := generatePtracePair(p.a1, p.a2); err != nil { - fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2) - ok = false - } - } - if ok { - fmt.Printf("----- SUCCESS ptrace pairs -----\n\n") - } -} - -// Makes an exec.Cmd with Stderr attached to os.Stderr -func makeCommand(name string, args ...string) *exec.Cmd { - cmd := exec.Command(name, args...) - cmd.Stderr = os.Stderr - return cmd -} - -// Runs the command, pipes output to a formatter, pipes that to an output file. -func (t *target) commandFormatOutput(formatter string, outputFile string, - name string, args ...string) (err error) { - mainCmd := makeCommand(name, args...) - - fmtCmd := makeCommand(formatter) - if formatter == "mkpost" { - fmtCmd = makeCommand("go", "run", "mkpost.go") - // Set GOARCH_TARGET so mkpost knows what GOARCH is.. - fmtCmd.Env = append(os.Environ(), "GOARCH_TARGET="+t.GoArch) - // Set GOARCH to host arch for mkpost, so it can run natively. - for i, s := range fmtCmd.Env { - if strings.HasPrefix(s, "GOARCH=") { - fmtCmd.Env[i] = "GOARCH=" + BuildArch - } - } - } - - // mainCmd | fmtCmd > outputFile - if fmtCmd.Stdin, err = mainCmd.StdoutPipe(); err != nil { - return - } - if fmtCmd.Stdout, err = os.Create(outputFile); err != nil { - return - } - - // Make sure the formatter eventually closes - if err = fmtCmd.Start(); err != nil { - return - } - defer func() { - fmtErr := fmtCmd.Wait() - if err == nil { - err = fmtErr - } - }() - - return mainCmd.Run() -} - -// Generates all the files for a Linux target -func (t *target) generateFiles() error { - // Setup environment variables - os.Setenv("GOOS", GOOS) - os.Setenv("GOARCH", t.GoArch) - - // Get appropriate compiler and emulator (unless on x86) - if t.LinuxArch != "x86" { - // Check/Setup cross compiler - compiler := t.GNUArch + "-gcc" - if _, err := exec.LookPath(compiler); err != nil { - return err - } - os.Setenv("CC", compiler) - - // Check/Setup emulator (usually first component of GNUArch) - qemuArchName := t.GNUArch[:strings.Index(t.GNUArch, "-")] - if t.LinuxArch == "powerpc" { - qemuArchName = t.GoArch - } - os.Setenv("GORUN", "qemu-"+qemuArchName) - } else { - os.Setenv("CC", "gcc") - } - - // Make the include directory and fill it with headers - if err := os.MkdirAll(IncludeDir, os.ModePerm); err != nil { - return err - } - defer os.RemoveAll(IncludeDir) - if err := t.makeHeaders(); err != nil { - return fmt.Errorf("could not make header files: %v", err) - } - fmt.Println("header files generated") - - // Make each of the four files - if err := t.makeZSysnumFile(); err != nil { - return fmt.Errorf("could not make zsysnum file: %v", err) - } - fmt.Println("zsysnum file generated") - - if err := t.makeZSyscallFile(); err != nil { - return fmt.Errorf("could not make zsyscall file: %v", err) - } - fmt.Println("zsyscall file generated") - - if err := t.makeZTypesFile(); err != nil { - return fmt.Errorf("could not make ztypes file: %v", err) - } - fmt.Println("ztypes file generated") - - if err := t.makeZErrorsFile(); err != nil { - return fmt.Errorf("could not make zerrors file: %v", err) - } - fmt.Println("zerrors file generated") - - return nil -} - -// Create the Linux and glibc headers in the include directory. -func (t *target) makeHeaders() error { - // Make the Linux headers we need for this architecture - linuxMake := makeCommand("make", "headers_install", "ARCH="+t.LinuxArch, "INSTALL_HDR_PATH="+TempDir) - linuxMake.Dir = LinuxDir - if err := linuxMake.Run(); err != nil { - return err - } - - // A Temporary build directory for glibc - if err := os.MkdirAll(BuildDir, os.ModePerm); err != nil { - return err - } - defer os.RemoveAll(BuildDir) - - // Make the glibc headers we need for this architecture - confScript := filepath.Join(GlibcDir, "configure") - glibcConf := makeCommand(confScript, "--prefix="+TempDir, "--host="+t.GNUArch, "--enable-kernel="+MinKernel) - glibcConf.Dir = BuildDir - if err := glibcConf.Run(); err != nil { - return err - } - glibcMake := makeCommand("make", "install-headers") - glibcMake.Dir = BuildDir - if err := glibcMake.Run(); err != nil { - return err - } - // We only need an empty stubs file - stubsFile := filepath.Join(IncludeDir, "gnu/stubs.h") - if file, err := os.Create(stubsFile); err != nil { - return err - } else { - file.Close() - } - - return nil -} - -// makes the zsysnum_linux_$GOARCH.go file -func (t *target) makeZSysnumFile() error { - zsysnumFile := fmt.Sprintf("zsysnum_linux_%s.go", t.GoArch) - unistdFile := filepath.Join(IncludeDir, "asm/unistd.h") - - args := append(t.cFlags(), unistdFile) - return t.commandFormatOutput("gofmt", zsysnumFile, "linux/mksysnum.pl", args...) -} - -// makes the zsyscall_linux_$GOARCH.go file -func (t *target) makeZSyscallFile() error { - zsyscallFile := fmt.Sprintf("zsyscall_linux_%s.go", t.GoArch) - // Find the correct architecture syscall file (might end with x.go) - archSyscallFile := fmt.Sprintf("syscall_linux_%s.go", t.GoArch) - if _, err := os.Stat(archSyscallFile); os.IsNotExist(err) { - shortArch := strings.TrimSuffix(t.GoArch, "le") - archSyscallFile = fmt.Sprintf("syscall_linux_%sx.go", shortArch) - } - - args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch, - "syscall_linux.go", archSyscallFile) - return t.commandFormatOutput("gofmt", zsyscallFile, "./mksyscall.pl", args...) -} - -// makes the zerrors_linux_$GOARCH.go file -func (t *target) makeZErrorsFile() error { - zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch) - - return t.commandFormatOutput("gofmt", zerrorsFile, "./mkerrors.sh", t.cFlags()...) -} - -// makes the ztypes_linux_$GOARCH.go file -func (t *target) makeZTypesFile() error { - ztypesFile := fmt.Sprintf("ztypes_linux_%s.go", t.GoArch) - - args := []string{"tool", "cgo", "-godefs", "--"} - args = append(args, t.cFlags()...) - args = append(args, "linux/types.go") - return t.commandFormatOutput("mkpost", ztypesFile, "go", args...) -} - -// Flags that should be given to gcc and cgo for this target -func (t *target) cFlags() []string { - // Compile statically to avoid cross-architecture dynamic linking. - flags := []string{"-Wall", "-Werror", "-static", "-I" + IncludeDir} - - // Architecture-specific flags - if t.SignedChar { - flags = append(flags, "-fsigned-char") - } - if t.LinuxArch == "x86" { - flags = append(flags, fmt.Sprintf("-m%d", t.Bits)) - } - - return flags -} - -// Flags that should be given to mksyscall for this target -func (t *target) mksyscallFlags() (flags []string) { - if t.Bits == 32 { - if t.BigEndian { - flags = append(flags, "-b32") - } else { - flags = append(flags, "-l32") - } - } - - // This flag menas a 64-bit value should use (even, odd)-pair. - if t.GoArch == "arm" || (t.LinuxArch == "mips" && t.Bits == 32) { - flags = append(flags, "-arm") - } - return -} - -// generatePtracePair takes a pair of GOARCH values that can run each -// other's binaries, such as 386 and amd64. It extracts the PtraceRegs -// type for each one. It writes a new file defining the types -// PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions -// Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other -// binary on a native system. -func generatePtracePair(arch1, arch2 string) error { - def1, err := ptraceDef(arch1) - if err != nil { - return err - } - def2, err := ptraceDef(arch2) - if err != nil { - return err - } - f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1)) - if err != nil { - return err - } - buf := bufio.NewWriter(f) - fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2) - fmt.Fprintf(buf, "\n") - fmt.Fprintf(buf, "// +build linux\n") - fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2) - fmt.Fprintf(buf, "\n") - fmt.Fprintf(buf, "package unix\n") - fmt.Fprintf(buf, "\n") - fmt.Fprintf(buf, "%s\n", `import "unsafe"`) - fmt.Fprintf(buf, "\n") - writeOnePtrace(buf, arch1, def1) - fmt.Fprintf(buf, "\n") - writeOnePtrace(buf, arch2, def2) - if err := buf.Flush(); err != nil { - return err - } - if err := f.Close(); err != nil { - return err - } - return nil -} - -// ptraceDef returns the definition of PtraceRegs for arch. -func ptraceDef(arch string) (string, error) { - filename := fmt.Sprintf("ztypes_linux_%s.go", arch) - data, err := ioutil.ReadFile(filename) - if err != nil { - return "", fmt.Errorf("reading %s: %v", filename, err) - } - start := bytes.Index(data, []byte("type PtraceRegs struct")) - if start < 0 { - return "", fmt.Errorf("%s: no definition of PtraceRegs", filename) - } - data = data[start:] - end := bytes.Index(data, []byte("\n}\n")) - if end < 0 { - return "", fmt.Errorf("%s: can't find end of PtraceRegs definition", filename) - } - return string(data[:end+2]), nil -} - -// writeOnePtrace writes out the ptrace definitions for arch. -func writeOnePtrace(w io.Writer, arch, def string) { - uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:] - fmt.Fprintf(w, "// PtraceRegs%s is the registers used by %s binaries.\n", uarch, arch) - fmt.Fprintf(w, "%s\n", strings.Replace(def, "PtraceRegs", "PtraceRegs"+uarch, 1)) - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "// PtraceGetRegs%s fetches the registers used by %s binaries.\n", uarch, arch) - fmt.Fprintf(w, "func PtraceGetRegs%s(pid int, regsout *PtraceRegs%s) error {\n", uarch, uarch) - fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))\n") - fmt.Fprintf(w, "}\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "// PtraceSetRegs%s sets the registers used by %s binaries.\n", uarch, arch) - fmt.Fprintf(w, "func PtraceSetRegs%s(pid int, regs *PtraceRegs%s) error {\n", uarch, uarch) - fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))\n") - fmt.Fprintf(w, "}\n") -} diff --git a/vendor/golang.org/x/sys/unix/linux/mksysnum.pl b/vendor/golang.org/x/sys/unix/linux/mksysnum.pl deleted file mode 100755 index 63fd800..0000000 --- a/vendor/golang.org/x/sys/unix/linux/mksysnum.pl +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env perl -# 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. - -use strict; - -if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { - print STDERR "GOARCH or GOOS not defined in environment\n"; - exit 1; -} - -# Check that we are using the new build system if we should -if($ENV{'GOLANG_SYS_BUILD'} ne "docker") { - print STDERR "In the new build system, mksysnum should not be called directly.\n"; - print STDERR "See README.md\n"; - exit 1; -} - -my $command = "$0 ". join(' ', @ARGV); - -print < 999){ - # ignore deprecated syscalls that are no longer implemented - # https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716 - return; - } - $name =~ y/a-z/A-Z/; - $num = $num + $offset; - print " SYS_$name = $num;\n"; -} - -my $prev; -open(CC, "$ENV{'CC'} -E -dD @ARGV |") || die "can't run $ENV{'CC'}"; -while(){ - if(/^#define __NR_Linux\s+([0-9]+)/){ - # mips/mips64: extract offset - $offset = $1; - } - elsif(/^#define __NR(\w*)_SYSCALL_BASE\s+([0-9]+)/){ - # arm: extract offset - $offset = $1; - } - elsif(/^#define __NR_syscalls\s+/) { - # ignore redefinitions of __NR_syscalls - } - elsif(/^#define __NR_(\w*)Linux_syscalls\s+/) { - # mips/mips64: ignore definitions about the number of syscalls - } - elsif(/^#define __NR_(\w+)\s+([0-9]+)/){ - $prev = $2; - fmt($1, $2); - } - elsif(/^#define __NR3264_(\w+)\s+([0-9]+)/){ - $prev = $2; - fmt($1, $2); - } - elsif(/^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)/){ - fmt($1, $prev+$2) - } - elsif(/^#define __NR_(\w+)\s+\(__NR_Linux \+ ([0-9]+)/){ - fmt($1, $2); - } - elsif(/^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE \+ ([0-9]+)/){ - fmt($1, $2); - } -} - -print < -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// On mips64, the glibc stat and kernel stat do not agree -#if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) - -// Use the stat defined by the kernel with a few modifications. These are: -// * The time fields (like st_atime and st_atimensec) use the timespec -// struct (like st_atim) for consitancy with the glibc fields. -// * The padding fields get different names to not break compatibility. -// * st_blocks is signed, again for compatibility. -struct stat { - unsigned int st_dev; - unsigned int st_pad1[3]; // Reserved for st_dev expansion - - unsigned long st_ino; - - mode_t st_mode; - __u32 st_nlink; - - uid_t st_uid; - gid_t st_gid; - - unsigned int st_rdev; - unsigned int st_pad2[3]; // Reserved for st_rdev expansion - - off_t st_size; - - // These are declared as speperate fields in the kernel. Here we use - // the timespec struct for consistancy with the other stat structs. - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned int st_blksize; - unsigned int st_pad4; - - long st_blocks; -}; - -// These are needed because we do not include fcntl.h or sys/types.h -#include -#include - -#else - -// Use the stat defined by glibc -#include -#include - -#endif - -// These are defined in linux/fcntl.h, but including it globally causes -// conflicts with fcntl.h -#ifndef AT_STATX_SYNC_TYPE -# define AT_STATX_SYNC_TYPE 0x6000 // Type of synchronisation required from statx() -#endif -#ifndef AT_STATX_SYNC_AS_STAT -# define AT_STATX_SYNC_AS_STAT 0x0000 // - Do whatever stat() does -#endif -#ifndef AT_STATX_FORCE_SYNC -# define AT_STATX_FORCE_SYNC 0x2000 // - Force the attributes to be sync'd with the server -#endif -#ifndef AT_STATX_DONT_SYNC -# define AT_STATX_DONT_SYNC 0x4000 // - Don't sync attributes with the server -#endif - -#ifdef TCSETS2 -// On systems that have "struct termios2" use this as type Termios. -typedef struct termios2 termios_t; -#else -typedef struct termios termios_t; -#endif - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_ll s5; - struct sockaddr_nl s6; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -// copied from /usr/include/bluetooth/hci.h -struct sockaddr_hci { - sa_family_t hci_family; - unsigned short hci_dev; - unsigned short hci_channel; -};; - -// copied from /usr/include/linux/un.h -struct my_sockaddr_un { - sa_family_t sun_family; -#if defined(__ARM_EABI__) || defined(__powerpc64__) - // on ARM char is by default unsigned - signed char sun_path[108]; -#else - char sun_path[108]; -#endif -}; - -#ifdef __ARM_EABI__ -typedef struct user_regs PtraceRegs; -#elif defined(__aarch64__) -typedef struct user_pt_regs PtraceRegs; -#elif defined(__mips__) || defined(__powerpc64__) -typedef struct pt_regs PtraceRegs; -#elif defined(__s390x__) -typedef struct _user_regs_struct PtraceRegs; -#elif defined(__sparc__) -#include -typedef struct pt_regs PtraceRegs; -#else -typedef struct user_regs_struct PtraceRegs; -#endif - -#if defined(__s390x__) -typedef struct _user_psw_struct ptracePsw; -typedef struct _user_fpregs_struct ptraceFpregs; -typedef struct _user_per_struct ptracePer; -#else -typedef struct {} ptracePsw; -typedef struct {} ptraceFpregs; -typedef struct {} ptracePer; -#endif - -// The real epoll_event is a union, and godefs doesn't handle it well. -struct my_epoll_event { - uint32_t events; -#if defined(__ARM_EABI__) || defined(__aarch64__) || (defined(__mips__) && _MIPS_SIM == _ABIO32) - // padding is not specified in linux/eventpoll.h but added to conform to the - // alignment requirements of EABI - int32_t padFd; -#elif defined(__powerpc64__) || defined(__s390x__) || defined(__sparc__) - int32_t _padFd; -#endif - int32_t fd; - int32_t pad; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - PathMax = C.PATH_MAX -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -type Timex C.struct_timex - -type Time_t C.time_t - -type Tms C.struct_tms - -type Utimbuf C.struct_utimbuf - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -type Stat_t C.struct_stat - -type Statfs_t C.struct_statfs - -type StatxTimestamp C.struct_statx_timestamp - -type Statx_t C.struct_statx - -type Dirent C.struct_dirent - -type Fsid C.fsid_t - -type Flock_t C.struct_flock - -// Filesystem Encryption - -type FscryptPolicy C.struct_fscrypt_policy - -type FscryptKey C.struct_fscrypt_key - -// Structure for Keyctl - -type KeyctlDHParams C.struct_keyctl_dh_params - -// Advice to Fadvise - -const ( - FADV_NORMAL = C.POSIX_FADV_NORMAL - FADV_RANDOM = C.POSIX_FADV_RANDOM - FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL - FADV_WILLNEED = C.POSIX_FADV_WILLNEED - FADV_DONTNEED = C.POSIX_FADV_DONTNEED - FADV_NOREUSE = C.POSIX_FADV_NOREUSE -) - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_my_sockaddr_un - -type RawSockaddrLinklayer C.struct_sockaddr_ll - -type RawSockaddrNetlink C.struct_sockaddr_nl - -type RawSockaddrHCI C.struct_sockaddr_hci - -type RawSockaddrCAN C.struct_sockaddr_can - -type RawSockaddrALG C.struct_sockaddr_alg - -type RawSockaddrVM C.struct_sockaddr_vm - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPMreqn C.struct_ip_mreqn - -type IPv6Mreq C.struct_ipv6_mreq - -type PacketMreq C.struct_packet_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet4Pktinfo C.struct_in_pktinfo - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -type Ucred C.struct_ucred - -type TCPInfo C.struct_tcp_info - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll - SizeofSockaddrNetlink = C.sizeof_struct_sockaddr_nl - SizeofSockaddrHCI = C.sizeof_struct_sockaddr_hci - SizeofSockaddrCAN = C.sizeof_struct_sockaddr_can - SizeofSockaddrALG = C.sizeof_struct_sockaddr_alg - SizeofSockaddrVM = C.sizeof_struct_sockaddr_vm - SizeofLinger = C.sizeof_struct_linger - SizeofIovec = C.sizeof_struct_iovec - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPMreqn = C.sizeof_struct_ip_mreqn - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofPacketMreq = C.sizeof_struct_packet_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter - SizeofUcred = C.sizeof_struct_ucred - SizeofTCPInfo = C.sizeof_struct_tcp_info -) - -// Netlink routing and interface messages - -const ( - IFA_UNSPEC = C.IFA_UNSPEC - IFA_ADDRESS = C.IFA_ADDRESS - IFA_LOCAL = C.IFA_LOCAL - IFA_LABEL = C.IFA_LABEL - IFA_BROADCAST = C.IFA_BROADCAST - IFA_ANYCAST = C.IFA_ANYCAST - IFA_CACHEINFO = C.IFA_CACHEINFO - IFA_MULTICAST = C.IFA_MULTICAST - IFLA_UNSPEC = C.IFLA_UNSPEC - IFLA_ADDRESS = C.IFLA_ADDRESS - IFLA_BROADCAST = C.IFLA_BROADCAST - IFLA_IFNAME = C.IFLA_IFNAME - IFLA_MTU = C.IFLA_MTU - IFLA_LINK = C.IFLA_LINK - IFLA_QDISC = C.IFLA_QDISC - IFLA_STATS = C.IFLA_STATS - IFLA_COST = C.IFLA_COST - IFLA_PRIORITY = C.IFLA_PRIORITY - IFLA_MASTER = C.IFLA_MASTER - IFLA_WIRELESS = C.IFLA_WIRELESS - IFLA_PROTINFO = C.IFLA_PROTINFO - IFLA_TXQLEN = C.IFLA_TXQLEN - IFLA_MAP = C.IFLA_MAP - IFLA_WEIGHT = C.IFLA_WEIGHT - IFLA_OPERSTATE = C.IFLA_OPERSTATE - IFLA_LINKMODE = C.IFLA_LINKMODE - IFLA_LINKINFO = C.IFLA_LINKINFO - IFLA_NET_NS_PID = C.IFLA_NET_NS_PID - IFLA_IFALIAS = C.IFLA_IFALIAS - IFLA_MAX = C.IFLA_MAX - RT_SCOPE_UNIVERSE = C.RT_SCOPE_UNIVERSE - RT_SCOPE_SITE = C.RT_SCOPE_SITE - RT_SCOPE_LINK = C.RT_SCOPE_LINK - RT_SCOPE_HOST = C.RT_SCOPE_HOST - RT_SCOPE_NOWHERE = C.RT_SCOPE_NOWHERE - RT_TABLE_UNSPEC = C.RT_TABLE_UNSPEC - RT_TABLE_COMPAT = C.RT_TABLE_COMPAT - RT_TABLE_DEFAULT = C.RT_TABLE_DEFAULT - RT_TABLE_MAIN = C.RT_TABLE_MAIN - RT_TABLE_LOCAL = C.RT_TABLE_LOCAL - RT_TABLE_MAX = C.RT_TABLE_MAX - RTA_UNSPEC = C.RTA_UNSPEC - RTA_DST = C.RTA_DST - RTA_SRC = C.RTA_SRC - RTA_IIF = C.RTA_IIF - RTA_OIF = C.RTA_OIF - RTA_GATEWAY = C.RTA_GATEWAY - RTA_PRIORITY = C.RTA_PRIORITY - RTA_PREFSRC = C.RTA_PREFSRC - RTA_METRICS = C.RTA_METRICS - RTA_MULTIPATH = C.RTA_MULTIPATH - RTA_FLOW = C.RTA_FLOW - RTA_CACHEINFO = C.RTA_CACHEINFO - RTA_TABLE = C.RTA_TABLE - RTN_UNSPEC = C.RTN_UNSPEC - RTN_UNICAST = C.RTN_UNICAST - RTN_LOCAL = C.RTN_LOCAL - RTN_BROADCAST = C.RTN_BROADCAST - RTN_ANYCAST = C.RTN_ANYCAST - RTN_MULTICAST = C.RTN_MULTICAST - RTN_BLACKHOLE = C.RTN_BLACKHOLE - RTN_UNREACHABLE = C.RTN_UNREACHABLE - RTN_PROHIBIT = C.RTN_PROHIBIT - RTN_THROW = C.RTN_THROW - RTN_NAT = C.RTN_NAT - RTN_XRESOLVE = C.RTN_XRESOLVE - RTNLGRP_NONE = C.RTNLGRP_NONE - RTNLGRP_LINK = C.RTNLGRP_LINK - RTNLGRP_NOTIFY = C.RTNLGRP_NOTIFY - RTNLGRP_NEIGH = C.RTNLGRP_NEIGH - RTNLGRP_TC = C.RTNLGRP_TC - RTNLGRP_IPV4_IFADDR = C.RTNLGRP_IPV4_IFADDR - RTNLGRP_IPV4_MROUTE = C.RTNLGRP_IPV4_MROUTE - RTNLGRP_IPV4_ROUTE = C.RTNLGRP_IPV4_ROUTE - RTNLGRP_IPV4_RULE = C.RTNLGRP_IPV4_RULE - RTNLGRP_IPV6_IFADDR = C.RTNLGRP_IPV6_IFADDR - RTNLGRP_IPV6_MROUTE = C.RTNLGRP_IPV6_MROUTE - RTNLGRP_IPV6_ROUTE = C.RTNLGRP_IPV6_ROUTE - RTNLGRP_IPV6_IFINFO = C.RTNLGRP_IPV6_IFINFO - RTNLGRP_IPV6_PREFIX = C.RTNLGRP_IPV6_PREFIX - RTNLGRP_IPV6_RULE = C.RTNLGRP_IPV6_RULE - RTNLGRP_ND_USEROPT = C.RTNLGRP_ND_USEROPT - SizeofNlMsghdr = C.sizeof_struct_nlmsghdr - SizeofNlMsgerr = C.sizeof_struct_nlmsgerr - SizeofRtGenmsg = C.sizeof_struct_rtgenmsg - SizeofNlAttr = C.sizeof_struct_nlattr - SizeofRtAttr = C.sizeof_struct_rtattr - SizeofIfInfomsg = C.sizeof_struct_ifinfomsg - SizeofIfAddrmsg = C.sizeof_struct_ifaddrmsg - SizeofRtMsg = C.sizeof_struct_rtmsg - SizeofRtNexthop = C.sizeof_struct_rtnexthop -) - -type NlMsghdr C.struct_nlmsghdr - -type NlMsgerr C.struct_nlmsgerr - -type RtGenmsg C.struct_rtgenmsg - -type NlAttr C.struct_nlattr - -type RtAttr C.struct_rtattr - -type IfInfomsg C.struct_ifinfomsg - -type IfAddrmsg C.struct_ifaddrmsg - -type RtMsg C.struct_rtmsg - -type RtNexthop C.struct_rtnexthop - -// Linux socket filter - -const ( - SizeofSockFilter = C.sizeof_struct_sock_filter - SizeofSockFprog = C.sizeof_struct_sock_fprog -) - -type SockFilter C.struct_sock_filter - -type SockFprog C.struct_sock_fprog - -// Inotify - -type InotifyEvent C.struct_inotify_event - -const SizeofInotifyEvent = C.sizeof_struct_inotify_event - -// Ptrace - -// Register structures -type PtraceRegs C.PtraceRegs - -// Structures contained in PtraceRegs on s390x (exported by mkpost.go) -type PtracePsw C.ptracePsw - -type PtraceFpregs C.ptraceFpregs - -type PtracePer C.ptracePer - -// Misc - -type FdSet C.fd_set - -type Sysinfo_t C.struct_sysinfo - -type Utsname C.struct_utsname - -type Ustat_t C.struct_ustat - -type EpollEvent C.struct_my_epoll_event - -const ( - AT_EMPTY_PATH = C.AT_EMPTY_PATH - AT_FDCWD = C.AT_FDCWD - AT_NO_AUTOMOUNT = C.AT_NO_AUTOMOUNT - AT_REMOVEDIR = C.AT_REMOVEDIR - - AT_STATX_SYNC_AS_STAT = C.AT_STATX_SYNC_AS_STAT - AT_STATX_FORCE_SYNC = C.AT_STATX_FORCE_SYNC - AT_STATX_DONT_SYNC = C.AT_STATX_DONT_SYNC - - AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW -) - -type PollFd C.struct_pollfd - -const ( - POLLIN = C.POLLIN - POLLPRI = C.POLLPRI - POLLOUT = C.POLLOUT - POLLRDHUP = C.POLLRDHUP - POLLERR = C.POLLERR - POLLHUP = C.POLLHUP - POLLNVAL = C.POLLNVAL -) - -type Sigset_t C.sigset_t - -const RNDGETENTCNT = C.RNDGETENTCNT - -const PERF_IOC_FLAG_GROUP = C.PERF_IOC_FLAG_GROUP - -// Terminal handling - -type Termios C.termios_t - -type Winsize C.struct_winsize - -// Taskstats and cgroup stats. - -type Taskstats C.struct_taskstats - -const ( - TASKSTATS_CMD_UNSPEC = C.TASKSTATS_CMD_UNSPEC - TASKSTATS_CMD_GET = C.TASKSTATS_CMD_GET - TASKSTATS_CMD_NEW = C.TASKSTATS_CMD_NEW - TASKSTATS_TYPE_UNSPEC = C.TASKSTATS_TYPE_UNSPEC - TASKSTATS_TYPE_PID = C.TASKSTATS_TYPE_PID - TASKSTATS_TYPE_TGID = C.TASKSTATS_TYPE_TGID - TASKSTATS_TYPE_STATS = C.TASKSTATS_TYPE_STATS - TASKSTATS_TYPE_AGGR_PID = C.TASKSTATS_TYPE_AGGR_PID - TASKSTATS_TYPE_AGGR_TGID = C.TASKSTATS_TYPE_AGGR_TGID - TASKSTATS_TYPE_NULL = C.TASKSTATS_TYPE_NULL - TASKSTATS_CMD_ATTR_UNSPEC = C.TASKSTATS_CMD_ATTR_UNSPEC - TASKSTATS_CMD_ATTR_PID = C.TASKSTATS_CMD_ATTR_PID - TASKSTATS_CMD_ATTR_TGID = C.TASKSTATS_CMD_ATTR_TGID - TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = C.TASKSTATS_CMD_ATTR_REGISTER_CPUMASK - TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = C.TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK -) - -type CGroupStats C.struct_cgroupstats - -const ( - CGROUPSTATS_CMD_UNSPEC = C.__TASKSTATS_CMD_MAX - CGROUPSTATS_CMD_GET = C.CGROUPSTATS_CMD_GET - CGROUPSTATS_CMD_NEW = C.CGROUPSTATS_CMD_NEW - CGROUPSTATS_TYPE_UNSPEC = C.CGROUPSTATS_TYPE_UNSPEC - CGROUPSTATS_TYPE_CGROUP_STATS = C.CGROUPSTATS_TYPE_CGROUP_STATS - CGROUPSTATS_CMD_ATTR_UNSPEC = C.CGROUPSTATS_CMD_ATTR_UNSPEC - CGROUPSTATS_CMD_ATTR_FD = C.CGROUPSTATS_CMD_ATTR_FD -) - -// Generic netlink - -type Genlmsghdr C.struct_genlmsghdr - -const ( - CTRL_CMD_UNSPEC = C.CTRL_CMD_UNSPEC - CTRL_CMD_NEWFAMILY = C.CTRL_CMD_NEWFAMILY - CTRL_CMD_DELFAMILY = C.CTRL_CMD_DELFAMILY - CTRL_CMD_GETFAMILY = C.CTRL_CMD_GETFAMILY - CTRL_CMD_NEWOPS = C.CTRL_CMD_NEWOPS - CTRL_CMD_DELOPS = C.CTRL_CMD_DELOPS - CTRL_CMD_GETOPS = C.CTRL_CMD_GETOPS - CTRL_CMD_NEWMCAST_GRP = C.CTRL_CMD_NEWMCAST_GRP - CTRL_CMD_DELMCAST_GRP = C.CTRL_CMD_DELMCAST_GRP - CTRL_CMD_GETMCAST_GRP = C.CTRL_CMD_GETMCAST_GRP - CTRL_ATTR_UNSPEC = C.CTRL_ATTR_UNSPEC - CTRL_ATTR_FAMILY_ID = C.CTRL_ATTR_FAMILY_ID - CTRL_ATTR_FAMILY_NAME = C.CTRL_ATTR_FAMILY_NAME - CTRL_ATTR_VERSION = C.CTRL_ATTR_VERSION - CTRL_ATTR_HDRSIZE = C.CTRL_ATTR_HDRSIZE - CTRL_ATTR_MAXATTR = C.CTRL_ATTR_MAXATTR - CTRL_ATTR_OPS = C.CTRL_ATTR_OPS - CTRL_ATTR_MCAST_GROUPS = C.CTRL_ATTR_MCAST_GROUPS - CTRL_ATTR_OP_UNSPEC = C.CTRL_ATTR_OP_UNSPEC - CTRL_ATTR_OP_ID = C.CTRL_ATTR_OP_ID - CTRL_ATTR_OP_FLAGS = C.CTRL_ATTR_OP_FLAGS - CTRL_ATTR_MCAST_GRP_UNSPEC = C.CTRL_ATTR_MCAST_GRP_UNSPEC - CTRL_ATTR_MCAST_GRP_NAME = C.CTRL_ATTR_MCAST_GRP_NAME - CTRL_ATTR_MCAST_GRP_ID = C.CTRL_ATTR_MCAST_GRP_ID -) - -// CPU affinity - -type cpuMask C.__cpu_mask - -const ( - _CPU_SETSIZE = C.__CPU_SETSIZE - _NCPUBITS = C.__NCPUBITS -) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_386.s b/vendor/golang.org/x/sys/windows/asm_windows_386.s deleted file mode 100644 index 1c20dd2..0000000 --- a/vendor/golang.org/x/sys/windows/asm_windows_386.s +++ /dev/null @@ -1,13 +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. - -// -// System calls for 386, Windows are implemented in runtime/syscall_windows.goc -// - -TEXT ·getprocaddress(SB), 7, $0-8 - JMP syscall·getprocaddress(SB) - -TEXT ·loadlibrary(SB), 7, $0-4 - JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s deleted file mode 100644 index 4d025ab..0000000 --- a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s +++ /dev/null @@ -1,13 +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. - -// -// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc -// - -TEXT ·getprocaddress(SB), 7, $0-32 - JMP syscall·getprocaddress(SB) - -TEXT ·loadlibrary(SB), 7, $0-8 - JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go deleted file mode 100644 index e92c05b..0000000 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ /dev/null @@ -1,378 +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 windows - -import ( - "sync" - "sync/atomic" - "syscall" - "unsafe" -) - -// DLLError describes reasons for DLL load failures. -type DLLError struct { - Err error - ObjName string - Msg string -} - -func (e *DLLError) Error() string { return e.Msg } - -// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file. -func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno) -func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno) - -// A DLL implements access to a single DLL. -type DLL struct { - Name string - Handle Handle -} - -// LoadDLL loads DLL file into memory. -// -// Warning: using LoadDLL without an absolute path name is subject to -// DLL preloading attacks. To safely load a system DLL, use LazyDLL -// with System set to true, or use LoadLibraryEx directly. -func LoadDLL(name string) (dll *DLL, err error) { - namep, err := UTF16PtrFromString(name) - if err != nil { - return nil, err - } - h, e := loadlibrary(namep) - if e != 0 { - return nil, &DLLError{ - Err: e, - ObjName: name, - Msg: "Failed to load " + name + ": " + e.Error(), - } - } - d := &DLL{ - Name: name, - Handle: Handle(h), - } - return d, nil -} - -// MustLoadDLL is like LoadDLL but panics if load operation failes. -func MustLoadDLL(name string) *DLL { - d, e := LoadDLL(name) - if e != nil { - panic(e) - } - return d -} - -// FindProc searches DLL d for procedure named name and returns *Proc -// if found. It returns an error if search fails. -func (d *DLL) FindProc(name string) (proc *Proc, err error) { - namep, err := BytePtrFromString(name) - if err != nil { - return nil, err - } - a, e := getprocaddress(uintptr(d.Handle), namep) - if e != 0 { - return nil, &DLLError{ - Err: e, - ObjName: name, - Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), - } - } - p := &Proc{ - Dll: d, - Name: name, - addr: a, - } - return p, nil -} - -// MustFindProc is like FindProc but panics if search fails. -func (d *DLL) MustFindProc(name string) *Proc { - p, e := d.FindProc(name) - if e != nil { - panic(e) - } - return p -} - -// Release unloads DLL d from memory. -func (d *DLL) Release() (err error) { - return FreeLibrary(d.Handle) -} - -// A Proc implements access to a procedure inside a DLL. -type Proc struct { - Dll *DLL - Name string - addr uintptr -} - -// Addr returns the address of the procedure represented by p. -// The return value can be passed to Syscall to run the procedure. -func (p *Proc) Addr() uintptr { - return p.addr -} - -//go:uintptrescapes - -// Call executes procedure p with arguments a. It will panic, if more than 15 arguments -// are supplied. -// -// The returned error is always non-nil, constructed from the result of GetLastError. -// Callers must inspect the primary return value to decide whether an error occurred -// (according to the semantics of the specific function being called) before consulting -// the error. The error will be guaranteed to contain windows.Errno. -func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - switch len(a) { - case 0: - return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0) - case 1: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0) - case 2: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0) - case 3: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2]) - case 4: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0) - case 5: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0) - case 6: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5]) - case 7: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) - case 8: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) - case 9: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) - case 10: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) - case 11: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) - case 12: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) - case 13: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) - case 14: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) - case 15: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) - default: - panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".") - } -} - -// A LazyDLL implements access to a single DLL. -// It will delay the load of the DLL until the first -// call to its Handle method or to one of its -// LazyProc's Addr method. -type LazyDLL struct { - Name string - - // System determines whether the DLL must be loaded from the - // Windows System directory, bypassing the normal DLL search - // path. - System bool - - mu sync.Mutex - dll *DLL // non nil once DLL is loaded -} - -// Load loads DLL file d.Name into memory. It returns an error if fails. -// Load will not try to load DLL, if it is already loaded into memory. -func (d *LazyDLL) Load() error { - // Non-racy version of: - // if d.dll != nil { - if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil { - return nil - } - d.mu.Lock() - defer d.mu.Unlock() - if d.dll != nil { - return nil - } - - // kernel32.dll is special, since it's where LoadLibraryEx comes from. - // The kernel already special-cases its name, so it's always - // loaded from system32. - var dll *DLL - var err error - if d.Name == "kernel32.dll" { - dll, err = LoadDLL(d.Name) - } else { - dll, err = loadLibraryEx(d.Name, d.System) - } - if err != nil { - return err - } - - // Non-racy version of: - // d.dll = dll - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll)) - return nil -} - -// mustLoad is like Load but panics if search fails. -func (d *LazyDLL) mustLoad() { - e := d.Load() - if e != nil { - panic(e) - } -} - -// Handle returns d's module handle. -func (d *LazyDLL) Handle() uintptr { - d.mustLoad() - return uintptr(d.dll.Handle) -} - -// NewProc returns a LazyProc for accessing the named procedure in the DLL d. -func (d *LazyDLL) NewProc(name string) *LazyProc { - return &LazyProc{l: d, Name: name} -} - -// NewLazyDLL creates new LazyDLL associated with DLL file. -func NewLazyDLL(name string) *LazyDLL { - return &LazyDLL{Name: name} -} - -// NewLazySystemDLL is like NewLazyDLL, but will only -// search Windows System directory for the DLL if name is -// a base name (like "advapi32.dll"). -func NewLazySystemDLL(name string) *LazyDLL { - return &LazyDLL{Name: name, System: true} -} - -// A LazyProc implements access to a procedure inside a LazyDLL. -// It delays the lookup until the Addr method is called. -type LazyProc struct { - Name string - - mu sync.Mutex - l *LazyDLL - proc *Proc -} - -// Find searches DLL for procedure named p.Name. It returns -// an error if search fails. Find will not search procedure, -// if it is already found and loaded into memory. -func (p *LazyProc) Find() error { - // Non-racy version of: - // if p.proc == nil { - if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil { - p.mu.Lock() - defer p.mu.Unlock() - if p.proc == nil { - e := p.l.Load() - if e != nil { - return e - } - proc, e := p.l.dll.FindProc(p.Name) - if e != nil { - return e - } - // Non-racy version of: - // p.proc = proc - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc)) - } - } - return nil -} - -// mustFind is like Find but panics if search fails. -func (p *LazyProc) mustFind() { - e := p.Find() - if e != nil { - panic(e) - } -} - -// Addr returns the address of the procedure represented by p. -// The return value can be passed to Syscall to run the procedure. -// It will panic if the procedure cannot be found. -func (p *LazyProc) Addr() uintptr { - p.mustFind() - return p.proc.Addr() -} - -//go:uintptrescapes - -// Call executes procedure p with arguments a. It will panic, if more than 15 arguments -// are supplied. It will also panic if the procedure cannot be found. -// -// The returned error is always non-nil, constructed from the result of GetLastError. -// Callers must inspect the primary return value to decide whether an error occurred -// (according to the semantics of the specific function being called) before consulting -// the error. The error will be guaranteed to contain windows.Errno. -func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - p.mustFind() - return p.proc.Call(a...) -} - -var canDoSearchSystem32Once struct { - sync.Once - v bool -} - -func initCanDoSearchSystem32() { - // https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: - // "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows - // Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on - // systems that have KB2533623 installed. To determine whether the - // flags are available, use GetProcAddress to get the address of the - // AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories - // function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* - // flags can be used with LoadLibraryEx." - canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil) -} - -func canDoSearchSystem32() bool { - canDoSearchSystem32Once.Do(initCanDoSearchSystem32) - return canDoSearchSystem32Once.v -} - -func isBaseName(name string) bool { - for _, c := range name { - if c == ':' || c == '/' || c == '\\' { - return false - } - } - return true -} - -// loadLibraryEx wraps the Windows LoadLibraryEx function. -// -// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx -// -// If name is not an absolute path, LoadLibraryEx searches for the DLL -// in a variety of automatic locations unless constrained by flags. -// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx -func loadLibraryEx(name string, system bool) (*DLL, error) { - loadDLL := name - var flags uintptr - if system { - if canDoSearchSystem32() { - const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 - flags = LOAD_LIBRARY_SEARCH_SYSTEM32 - } else if isBaseName(name) { - // WindowsXP or unpatched Windows machine - // trying to load "foo.dll" out of the system - // folder, but LoadLibraryEx doesn't support - // that yet on their system, so emulate it. - windir, _ := Getenv("WINDIR") // old var; apparently works on XP - if windir == "" { - return nil, errString("%WINDIR% not defined") - } - loadDLL = windir + "\\System32\\" + name - } - } - h, err := LoadLibraryEx(loadDLL, 0, flags) - if err != nil { - return nil, err - } - return &DLL{Name: name, Handle: h}, nil -} - -type errString string - -func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go deleted file mode 100644 index bdc71e2..0000000 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ /dev/null @@ -1,29 +0,0 @@ -// 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. - -// Windows environment variables. - -package windows - -import "syscall" - -func Getenv(key string) (value string, found bool) { - return syscall.Getenv(key) -} - -func Setenv(key, value string) error { - return syscall.Setenv(key, value) -} - -func Clearenv() { - syscall.Clearenv() -} - -func Environ() []string { - return syscall.Environ() -} - -func Unsetenv(key string) error { - return syscall.Unsetenv(key) -} diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go deleted file mode 100644 index 40af946..0000000 --- a/vendor/golang.org/x/sys/windows/eventlog.go +++ /dev/null @@ -1,20 +0,0 @@ -// 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 windows - -package windows - -const ( - EVENTLOG_SUCCESS = 0 - EVENTLOG_ERROR_TYPE = 1 - EVENTLOG_WARNING_TYPE = 2 - EVENTLOG_INFORMATION_TYPE = 4 - EVENTLOG_AUDIT_SUCCESS = 8 - EVENTLOG_AUDIT_FAILURE = 16 -) - -//sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW -//sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource -//sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go deleted file mode 100644 index 3606c3a..0000000 --- a/vendor/golang.org/x/sys/windows/exec_windows.go +++ /dev/null @@ -1,97 +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. - -// Fork, exec, wait, etc. - -package windows - -// EscapeArg rewrites command line argument s as prescribed -// in http://msdn.microsoft.com/en-us/library/ms880421. -// This function returns "" (2 double quotes) if s is empty. -// Alternatively, these transformations are done: -// - every back slash (\) is doubled, but only if immediately -// followed by double quote ("); -// - every double quote (") is escaped by back slash (\); -// - finally, s is wrapped with double quotes (arg -> "arg"), -// but only if there is space or tab inside s. -func EscapeArg(s string) string { - if len(s) == 0 { - return "\"\"" - } - n := len(s) - hasSpace := false - for i := 0; i < len(s); i++ { - switch s[i] { - case '"', '\\': - n++ - case ' ', '\t': - hasSpace = true - } - } - if hasSpace { - n += 2 - } - if n == len(s) { - return s - } - - qs := make([]byte, n) - j := 0 - if hasSpace { - qs[j] = '"' - j++ - } - slashes := 0 - for i := 0; i < len(s); i++ { - switch s[i] { - default: - slashes = 0 - qs[j] = s[i] - case '\\': - slashes++ - qs[j] = s[i] - case '"': - for ; slashes > 0; slashes-- { - qs[j] = '\\' - j++ - } - qs[j] = '\\' - j++ - qs[j] = s[i] - } - j++ - } - if hasSpace { - for ; slashes > 0; slashes-- { - qs[j] = '\\' - j++ - } - qs[j] = '"' - j++ - } - return string(qs[:j]) -} - -func CloseOnExec(fd Handle) { - SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) -} - -// FullPath retrieves the full path of the specified file. -func FullPath(name string) (path string, err error) { - p, err := UTF16PtrFromString(name) - if err != nil { - return "", err - } - n := uint32(100) - for { - buf := make([]uint16, n) - n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil) - if err != nil { - return "", err - } - if n <= uint32(len(buf)) { - return UTF16ToString(buf[:n]), nil - } - } -} diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go deleted file mode 100644 index f80a420..0000000 --- a/vendor/golang.org/x/sys/windows/memory_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 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 windows - -const ( - MEM_COMMIT = 0x00001000 - MEM_RESERVE = 0x00002000 - MEM_DECOMMIT = 0x00004000 - MEM_RELEASE = 0x00008000 - MEM_RESET = 0x00080000 - MEM_TOP_DOWN = 0x00100000 - MEM_WRITE_WATCH = 0x00200000 - MEM_PHYSICAL = 0x00400000 - MEM_RESET_UNDO = 0x01000000 - MEM_LARGE_PAGES = 0x20000000 - - PAGE_NOACCESS = 0x01 - PAGE_READONLY = 0x02 - PAGE_READWRITE = 0x04 - PAGE_WRITECOPY = 0x08 - PAGE_EXECUTE_READ = 0x20 - PAGE_EXECUTE_READWRITE = 0x40 - PAGE_EXECUTE_WRITECOPY = 0x80 -) diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go deleted file mode 100644 index fb7db0e..0000000 --- a/vendor/golang.org/x/sys/windows/mksyscall.go +++ /dev/null @@ -1,7 +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 windows - -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go deleted file mode 100644 index a74e3e2..0000000 --- a/vendor/golang.org/x/sys/windows/race.go +++ /dev/null @@ -1,30 +0,0 @@ -// 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 windows,race - -package windows - -import ( - "runtime" - "unsafe" -) - -const raceenabled = true - -func raceAcquire(addr unsafe.Pointer) { - runtime.RaceAcquire(addr) -} - -func raceReleaseMerge(addr unsafe.Pointer) { - runtime.RaceReleaseMerge(addr) -} - -func raceReadRange(addr unsafe.Pointer, len int) { - runtime.RaceReadRange(addr, len) -} - -func raceWriteRange(addr unsafe.Pointer, len int) { - runtime.RaceWriteRange(addr, len) -} diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go deleted file mode 100644 index e44a3cb..0000000 --- a/vendor/golang.org/x/sys/windows/race0.go +++ /dev/null @@ -1,25 +0,0 @@ -// 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 windows,!race - -package windows - -import ( - "unsafe" -) - -const raceenabled = false - -func raceAcquire(addr unsafe.Pointer) { -} - -func raceReleaseMerge(addr unsafe.Pointer) { -} - -func raceReadRange(addr unsafe.Pointer, len int) { -} - -func raceWriteRange(addr unsafe.Pointer, len int) { -} diff --git a/vendor/golang.org/x/sys/windows/registry/export_test.go b/vendor/golang.org/x/sys/windows/registry/export_test.go deleted file mode 100644 index 8badf6f..0000000 --- a/vendor/golang.org/x/sys/windows/registry/export_test.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2015 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 - -package registry - -func (k Key) SetValue(name string, valtype uint32, data []byte) error { - return k.setValue(name, valtype, data) -} diff --git a/vendor/golang.org/x/sys/windows/registry/key.go b/vendor/golang.org/x/sys/windows/registry/key.go deleted file mode 100644 index d0beb19..0000000 --- a/vendor/golang.org/x/sys/windows/registry/key.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2015 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 - -// Package registry provides access to the Windows registry. -// -// Here is a simple example, opening a registry key and reading a string value from it. -// -// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) -// if err != nil { -// log.Fatal(err) -// } -// defer k.Close() -// -// s, _, err := k.GetStringValue("SystemRoot") -// if err != nil { -// log.Fatal(err) -// } -// fmt.Printf("Windows system root is %q\n", s) -// -package registry - -import ( - "io" - "syscall" - "time" -) - -const ( - // Registry key security and access rights. - // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx - // for details. - ALL_ACCESS = 0xf003f - CREATE_LINK = 0x00020 - CREATE_SUB_KEY = 0x00004 - ENUMERATE_SUB_KEYS = 0x00008 - EXECUTE = 0x20019 - NOTIFY = 0x00010 - QUERY_VALUE = 0x00001 - READ = 0x20019 - SET_VALUE = 0x00002 - WOW64_32KEY = 0x00200 - WOW64_64KEY = 0x00100 - WRITE = 0x20006 -) - -// Key is a handle to an open Windows registry key. -// Keys can be obtained by calling OpenKey; there are -// also some predefined root keys such as CURRENT_USER. -// Keys can be used directly in the Windows API. -type Key syscall.Handle - -const ( - // Windows defines some predefined root keys that are always open. - // An application can use these keys as entry points to the registry. - // Normally these keys are used in OpenKey to open new keys, - // but they can also be used anywhere a Key is required. - CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT) - CURRENT_USER = Key(syscall.HKEY_CURRENT_USER) - LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE) - USERS = Key(syscall.HKEY_USERS) - CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG) - PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA) -) - -// Close closes open key k. -func (k Key) Close() error { - return syscall.RegCloseKey(syscall.Handle(k)) -} - -// OpenKey opens a new key with path name relative to key k. -// It accepts any open key, including CURRENT_USER and others, -// and returns the new key and an error. -// The access parameter specifies desired access rights to the -// key to be opened. -func OpenKey(k Key, path string, access uint32) (Key, error) { - p, err := syscall.UTF16PtrFromString(path) - if err != nil { - return 0, err - } - var subkey syscall.Handle - err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey) - if err != nil { - return 0, err - } - return Key(subkey), nil -} - -// OpenRemoteKey opens a predefined registry key on another -// computer pcname. The key to be opened is specified by k, but -// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS. -// If pcname is "", OpenRemoteKey returns local computer key. -func OpenRemoteKey(pcname string, k Key) (Key, error) { - var err error - var p *uint16 - if pcname != "" { - p, err = syscall.UTF16PtrFromString(`\\` + pcname) - if err != nil { - return 0, err - } - } - var remoteKey syscall.Handle - err = regConnectRegistry(p, syscall.Handle(k), &remoteKey) - if err != nil { - return 0, err - } - return Key(remoteKey), nil -} - -// ReadSubKeyNames returns the names of subkeys of key k. -// The parameter n controls the number of returned names, -// analogous to the way os.File.Readdirnames works. -func (k Key) ReadSubKeyNames(n int) ([]string, error) { - ki, err := k.Stat() - if err != nil { - return nil, err - } - names := make([]string, 0, ki.SubKeyCount) - buf := make([]uint16, ki.MaxSubKeyLen+1) // extra room for terminating zero byte -loopItems: - for i := uint32(0); ; i++ { - if n > 0 { - if len(names) == n { - return names, nil - } - } - l := uint32(len(buf)) - for { - err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) - if err == nil { - break - } - if err == syscall.ERROR_MORE_DATA { - // Double buffer size and try again. - l = uint32(2 * len(buf)) - buf = make([]uint16, l) - continue - } - if err == _ERROR_NO_MORE_ITEMS { - break loopItems - } - return names, err - } - names = append(names, syscall.UTF16ToString(buf[:l])) - } - if n > len(names) { - return names, io.EOF - } - return names, nil -} - -// CreateKey creates a key named path under open key k. -// CreateKey returns the new key and a boolean flag that reports -// whether the key already existed. -// The access parameter specifies the access rights for the key -// to be created. -func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) { - var h syscall.Handle - var d uint32 - err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path), - 0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d) - if err != nil { - return 0, false, err - } - return Key(h), d == _REG_OPENED_EXISTING_KEY, nil -} - -// DeleteKey deletes the subkey path of key k and its values. -func DeleteKey(k Key, path string) error { - return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path)) -} - -// A KeyInfo describes the statistics of a key. It is returned by Stat. -type KeyInfo struct { - SubKeyCount uint32 - MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte - ValueCount uint32 - MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte - MaxValueLen uint32 // longest data component among the key's values, in bytes - lastWriteTime syscall.Filetime -} - -// ModTime returns the key's last write time. -func (ki *KeyInfo) ModTime() time.Time { - return time.Unix(0, ki.lastWriteTime.Nanoseconds()) -} - -// Stat retrieves information about the open key k. -func (k Key) Stat() (*KeyInfo, error) { - var ki KeyInfo - err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil, - &ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount, - &ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime) - if err != nil { - return nil, err - } - return &ki, nil -} diff --git a/vendor/golang.org/x/sys/windows/registry/mksyscall.go b/vendor/golang.org/x/sys/windows/registry/mksyscall.go deleted file mode 100644 index 0ac95ff..0000000 --- a/vendor/golang.org/x/sys/windows/registry/mksyscall.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2015 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 registry - -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go diff --git a/vendor/golang.org/x/sys/windows/registry/registry_test.go b/vendor/golang.org/x/sys/windows/registry/registry_test.go deleted file mode 100644 index 3cb9771..0000000 --- a/vendor/golang.org/x/sys/windows/registry/registry_test.go +++ /dev/null @@ -1,756 +0,0 @@ -// Copyright 2015 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 - -package registry_test - -import ( - "bytes" - "crypto/rand" - "os" - "syscall" - "testing" - "time" - "unsafe" - - "golang.org/x/sys/windows/registry" -) - -func randKeyName(prefix string) string { - const numbers = "0123456789" - buf := make([]byte, 10) - rand.Read(buf) - for i, b := range buf { - buf[i] = numbers[b%byte(len(numbers))] - } - return prefix + string(buf) -} - -func TestReadSubKeyNames(t *testing.T) { - k, err := registry.OpenKey(registry.CLASSES_ROOT, "TypeLib", registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) - if err != nil { - t.Fatal(err) - } - defer k.Close() - - names, err := k.ReadSubKeyNames(-1) - if err != nil { - t.Fatal(err) - } - var foundStdOle bool - for _, name := range names { - // Every PC has "stdole 2.0 OLE Automation" library installed. - if name == "{00020430-0000-0000-C000-000000000046}" { - foundStdOle = true - } - } - if !foundStdOle { - t.Fatal("could not find stdole 2.0 OLE Automation") - } -} - -func TestCreateOpenDeleteKey(t *testing.T) { - k, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) - if err != nil { - t.Fatal(err) - } - defer k.Close() - - testKName := randKeyName("TestCreateOpenDeleteKey_") - - testK, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) - if err != nil { - t.Fatal(err) - } - defer testK.Close() - - if exist { - t.Fatalf("key %q already exists", testKName) - } - - testKAgain, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) - if err != nil { - t.Fatal(err) - } - defer testKAgain.Close() - - if !exist { - t.Fatalf("key %q should already exist", testKName) - } - - testKOpened, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) - if err != nil { - t.Fatal(err) - } - defer testKOpened.Close() - - err = registry.DeleteKey(k, testKName) - if err != nil { - t.Fatal(err) - } - - testKOpenedAgain, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) - if err == nil { - defer testKOpenedAgain.Close() - t.Fatalf("key %q should already been deleted", testKName) - } - if err != registry.ErrNotExist { - t.Fatalf(`unexpected error ("not exist" expected): %v`, err) - } -} - -func equalStringSlice(a, b []string) bool { - if len(a) != len(b) { - return false - } - if a == nil { - return true - } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true -} - -type ValueTest struct { - Type uint32 - Name string - Value interface{} - WillFail bool -} - -var ValueTests = []ValueTest{ - {Type: registry.SZ, Name: "String1", Value: ""}, - {Type: registry.SZ, Name: "String2", Value: "\000", WillFail: true}, - {Type: registry.SZ, Name: "String3", Value: "Hello World"}, - {Type: registry.SZ, Name: "String4", Value: "Hello World\000", WillFail: true}, - {Type: registry.EXPAND_SZ, Name: "ExpString1", Value: ""}, - {Type: registry.EXPAND_SZ, Name: "ExpString2", Value: "\000", WillFail: true}, - {Type: registry.EXPAND_SZ, Name: "ExpString3", Value: "Hello World"}, - {Type: registry.EXPAND_SZ, Name: "ExpString4", Value: "Hello\000World", WillFail: true}, - {Type: registry.EXPAND_SZ, Name: "ExpString5", Value: "%PATH%"}, - {Type: registry.EXPAND_SZ, Name: "ExpString6", Value: "%NO_SUCH_VARIABLE%"}, - {Type: registry.EXPAND_SZ, Name: "ExpString7", Value: "%PATH%;."}, - {Type: registry.BINARY, Name: "Binary1", Value: []byte{}}, - {Type: registry.BINARY, Name: "Binary2", Value: []byte{1, 2, 3}}, - {Type: registry.BINARY, Name: "Binary3", Value: []byte{3, 2, 1, 0, 1, 2, 3}}, - {Type: registry.DWORD, Name: "Dword1", Value: uint64(0)}, - {Type: registry.DWORD, Name: "Dword2", Value: uint64(1)}, - {Type: registry.DWORD, Name: "Dword3", Value: uint64(0xff)}, - {Type: registry.DWORD, Name: "Dword4", Value: uint64(0xffff)}, - {Type: registry.QWORD, Name: "Qword1", Value: uint64(0)}, - {Type: registry.QWORD, Name: "Qword2", Value: uint64(1)}, - {Type: registry.QWORD, Name: "Qword3", Value: uint64(0xff)}, - {Type: registry.QWORD, Name: "Qword4", Value: uint64(0xffff)}, - {Type: registry.QWORD, Name: "Qword5", Value: uint64(0xffffff)}, - {Type: registry.QWORD, Name: "Qword6", Value: uint64(0xffffffff)}, - {Type: registry.MULTI_SZ, Name: "MultiString1", Value: []string{"a", "b", "c"}}, - {Type: registry.MULTI_SZ, Name: "MultiString2", Value: []string{"abc", "", "cba"}}, - {Type: registry.MULTI_SZ, Name: "MultiString3", Value: []string{""}}, - {Type: registry.MULTI_SZ, Name: "MultiString4", Value: []string{"abcdef"}}, - {Type: registry.MULTI_SZ, Name: "MultiString5", Value: []string{"\000"}, WillFail: true}, - {Type: registry.MULTI_SZ, Name: "MultiString6", Value: []string{"a\000b"}, WillFail: true}, - {Type: registry.MULTI_SZ, Name: "MultiString7", Value: []string{"ab", "\000", "cd"}, WillFail: true}, - {Type: registry.MULTI_SZ, Name: "MultiString8", Value: []string{"\000", "cd"}, WillFail: true}, - {Type: registry.MULTI_SZ, Name: "MultiString9", Value: []string{"ab", "\000"}, WillFail: true}, -} - -func setValues(t *testing.T, k registry.Key) { - for _, test := range ValueTests { - var err error - switch test.Type { - case registry.SZ: - err = k.SetStringValue(test.Name, test.Value.(string)) - case registry.EXPAND_SZ: - err = k.SetExpandStringValue(test.Name, test.Value.(string)) - case registry.MULTI_SZ: - err = k.SetStringsValue(test.Name, test.Value.([]string)) - case registry.BINARY: - err = k.SetBinaryValue(test.Name, test.Value.([]byte)) - case registry.DWORD: - err = k.SetDWordValue(test.Name, uint32(test.Value.(uint64))) - case registry.QWORD: - err = k.SetQWordValue(test.Name, test.Value.(uint64)) - default: - t.Fatalf("unsupported type %d for %s value", test.Type, test.Name) - } - if test.WillFail { - if err == nil { - t.Fatalf("setting %s value %q should fail, but succeeded", test.Name, test.Value) - } - } else { - if err != nil { - t.Fatal(err) - } - } - } -} - -func enumerateValues(t *testing.T, k registry.Key) { - names, err := k.ReadValueNames(-1) - if err != nil { - t.Error(err) - return - } - haveNames := make(map[string]bool) - for _, n := range names { - haveNames[n] = false - } - for _, test := range ValueTests { - wantFound := !test.WillFail - _, haveFound := haveNames[test.Name] - if wantFound && !haveFound { - t.Errorf("value %s is not found while enumerating", test.Name) - } - if haveFound && !wantFound { - t.Errorf("value %s is found while enumerating, but expected to fail", test.Name) - } - if haveFound { - delete(haveNames, test.Name) - } - } - for n, v := range haveNames { - t.Errorf("value %s (%v) is found while enumerating, but has not been cretaed", n, v) - } -} - -func testErrNotExist(t *testing.T, name string, err error) { - if err == nil { - t.Errorf("%s value should not exist", name) - return - } - if err != registry.ErrNotExist { - t.Errorf("reading %s value should return 'not exist' error, but got: %s", name, err) - return - } -} - -func testErrUnexpectedType(t *testing.T, test ValueTest, gottype uint32, err error) { - if err == nil { - t.Errorf("GetXValue(%q) should not succeed", test.Name) - return - } - if err != registry.ErrUnexpectedType { - t.Errorf("reading %s value should return 'unexpected key value type' error, but got: %s", test.Name, err) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } -} - -func testGetStringValue(t *testing.T, k registry.Key, test ValueTest) { - got, gottype, err := k.GetStringValue(test.Name) - if err != nil { - t.Errorf("GetStringValue(%s) failed: %v", test.Name, err) - return - } - if got != test.Value { - t.Errorf("want %s value %q, got %q", test.Name, test.Value, got) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } - if gottype == registry.EXPAND_SZ { - _, err = registry.ExpandString(got) - if err != nil { - t.Errorf("ExpandString(%s) failed: %v", got, err) - return - } - } -} - -func testGetIntegerValue(t *testing.T, k registry.Key, test ValueTest) { - got, gottype, err := k.GetIntegerValue(test.Name) - if err != nil { - t.Errorf("GetIntegerValue(%s) failed: %v", test.Name, err) - return - } - if got != test.Value.(uint64) { - t.Errorf("want %s value %v, got %v", test.Name, test.Value, got) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } -} - -func testGetBinaryValue(t *testing.T, k registry.Key, test ValueTest) { - got, gottype, err := k.GetBinaryValue(test.Name) - if err != nil { - t.Errorf("GetBinaryValue(%s) failed: %v", test.Name, err) - return - } - if !bytes.Equal(got, test.Value.([]byte)) { - t.Errorf("want %s value %v, got %v", test.Name, test.Value, got) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } -} - -func testGetStringsValue(t *testing.T, k registry.Key, test ValueTest) { - got, gottype, err := k.GetStringsValue(test.Name) - if err != nil { - t.Errorf("GetStringsValue(%s) failed: %v", test.Name, err) - return - } - if !equalStringSlice(got, test.Value.([]string)) { - t.Errorf("want %s value %#v, got %#v", test.Name, test.Value, got) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } -} - -func testGetValue(t *testing.T, k registry.Key, test ValueTest, size int) { - if size <= 0 { - return - } - // read data with no buffer - gotsize, gottype, err := k.GetValue(test.Name, nil) - if err != nil { - t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err) - return - } - if gotsize != size { - t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } - // read data with short buffer - gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size-1)) - if err == nil { - t.Errorf("GetValue(%s, [%d]byte) should fail, but succeeded", test.Name, size-1) - return - } - if err != registry.ErrShortBuffer { - t.Errorf("reading %s value should return 'short buffer' error, but got: %s", test.Name, err) - return - } - if gotsize != size { - t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } - // read full data - gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size)) - if err != nil { - t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err) - return - } - if gotsize != size { - t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) - return - } - if gottype != test.Type { - t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) - return - } - // check GetValue returns ErrNotExist as required - _, _, err = k.GetValue(test.Name+"_not_there", make([]byte, size)) - if err == nil { - t.Errorf("GetValue(%q) should not succeed", test.Name) - return - } - if err != registry.ErrNotExist { - t.Errorf("GetValue(%q) should return 'not exist' error, but got: %s", test.Name, err) - return - } -} - -func testValues(t *testing.T, k registry.Key) { - for _, test := range ValueTests { - switch test.Type { - case registry.SZ, registry.EXPAND_SZ: - if test.WillFail { - _, _, err := k.GetStringValue(test.Name) - testErrNotExist(t, test.Name, err) - } else { - testGetStringValue(t, k, test) - _, gottype, err := k.GetIntegerValue(test.Name) - testErrUnexpectedType(t, test, gottype, err) - // Size of utf16 string in bytes is not perfect, - // but correct for current test values. - // Size also includes terminating 0. - testGetValue(t, k, test, (len(test.Value.(string))+1)*2) - } - _, _, err := k.GetStringValue(test.Name + "_string_not_created") - testErrNotExist(t, test.Name+"_string_not_created", err) - case registry.DWORD, registry.QWORD: - testGetIntegerValue(t, k, test) - _, gottype, err := k.GetBinaryValue(test.Name) - testErrUnexpectedType(t, test, gottype, err) - _, _, err = k.GetIntegerValue(test.Name + "_int_not_created") - testErrNotExist(t, test.Name+"_int_not_created", err) - size := 8 - if test.Type == registry.DWORD { - size = 4 - } - testGetValue(t, k, test, size) - case registry.BINARY: - testGetBinaryValue(t, k, test) - _, gottype, err := k.GetStringsValue(test.Name) - testErrUnexpectedType(t, test, gottype, err) - _, _, err = k.GetBinaryValue(test.Name + "_byte_not_created") - testErrNotExist(t, test.Name+"_byte_not_created", err) - testGetValue(t, k, test, len(test.Value.([]byte))) - case registry.MULTI_SZ: - if test.WillFail { - _, _, err := k.GetStringsValue(test.Name) - testErrNotExist(t, test.Name, err) - } else { - testGetStringsValue(t, k, test) - _, gottype, err := k.GetStringValue(test.Name) - testErrUnexpectedType(t, test, gottype, err) - size := 0 - for _, s := range test.Value.([]string) { - size += len(s) + 1 // nil terminated - } - size += 1 // extra nil at the end - size *= 2 // count bytes, not uint16 - testGetValue(t, k, test, size) - } - _, _, err := k.GetStringsValue(test.Name + "_strings_not_created") - testErrNotExist(t, test.Name+"_strings_not_created", err) - default: - t.Errorf("unsupported type %d for %s value", test.Type, test.Name) - continue - } - } -} - -func testStat(t *testing.T, k registry.Key) { - subk, _, err := registry.CreateKey(k, "subkey", registry.CREATE_SUB_KEY) - if err != nil { - t.Error(err) - return - } - defer subk.Close() - - defer registry.DeleteKey(k, "subkey") - - ki, err := k.Stat() - if err != nil { - t.Error(err) - return - } - if ki.SubKeyCount != 1 { - t.Error("key must have 1 subkey") - } - if ki.MaxSubKeyLen != 6 { - t.Error("key max subkey name length must be 6") - } - if ki.ValueCount != 24 { - t.Errorf("key must have 24 values, but is %d", ki.ValueCount) - } - if ki.MaxValueNameLen != 12 { - t.Errorf("key max value name length must be 10, but is %d", ki.MaxValueNameLen) - } - if ki.MaxValueLen != 38 { - t.Errorf("key max value length must be 38, but is %d", ki.MaxValueLen) - } - if mt, ct := ki.ModTime(), time.Now(); ct.Sub(mt) > 100*time.Millisecond { - t.Errorf("key mod time is not close to current time: mtime=%v current=%v delta=%v", mt, ct, ct.Sub(mt)) - } -} - -func deleteValues(t *testing.T, k registry.Key) { - for _, test := range ValueTests { - if test.WillFail { - continue - } - err := k.DeleteValue(test.Name) - if err != nil { - t.Error(err) - continue - } - } - names, err := k.ReadValueNames(-1) - if err != nil { - t.Error(err) - return - } - if len(names) != 0 { - t.Errorf("some values remain after deletion: %v", names) - } -} - -func TestValues(t *testing.T) { - softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) - if err != nil { - t.Fatal(err) - } - defer softwareK.Close() - - testKName := randKeyName("TestValues_") - - k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) - if err != nil { - t.Fatal(err) - } - defer k.Close() - - if exist { - t.Fatalf("key %q already exists", testKName) - } - - defer registry.DeleteKey(softwareK, testKName) - - setValues(t, k) - - enumerateValues(t, k) - - testValues(t, k) - - testStat(t, k) - - deleteValues(t, k) -} - -func walkKey(t *testing.T, k registry.Key, kname string) { - names, err := k.ReadValueNames(-1) - if err != nil { - t.Fatalf("reading value names of %s failed: %v", kname, err) - } - for _, name := range names { - _, valtype, err := k.GetValue(name, nil) - if err != nil { - t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err) - } - switch valtype { - case registry.NONE: - case registry.SZ: - _, _, err := k.GetStringValue(name) - if err != nil { - t.Error(err) - } - case registry.EXPAND_SZ: - s, _, err := k.GetStringValue(name) - if err != nil { - t.Error(err) - } - _, err = registry.ExpandString(s) - if err != nil { - t.Error(err) - } - case registry.DWORD, registry.QWORD: - _, _, err := k.GetIntegerValue(name) - if err != nil { - t.Error(err) - } - case registry.BINARY: - _, _, err := k.GetBinaryValue(name) - if err != nil { - t.Error(err) - } - case registry.MULTI_SZ: - _, _, err := k.GetStringsValue(name) - if err != nil { - t.Error(err) - } - case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST: - // TODO: not implemented - default: - t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err) - } - } - - names, err = k.ReadSubKeyNames(-1) - if err != nil { - t.Fatalf("reading sub-keys of %s failed: %v", kname, err) - } - for _, name := range names { - func() { - subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) - if err != nil { - if err == syscall.ERROR_ACCESS_DENIED { - // ignore error, if we are not allowed to access this key - return - } - t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err) - } - defer subk.Close() - - walkKey(t, subk, kname+`\`+name) - }() - } -} - -func TestWalkFullRegistry(t *testing.T) { - if testing.Short() { - t.Skip("skipping long running test in short mode") - } - walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT") - walkKey(t, registry.CURRENT_USER, "CURRENT_USER") - walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE") - walkKey(t, registry.USERS, "USERS") - walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG") -} - -func TestExpandString(t *testing.T) { - got, err := registry.ExpandString("%PATH%") - if err != nil { - t.Fatal(err) - } - want := os.Getenv("PATH") - if got != want { - t.Errorf("want %q string expanded, got %q", want, got) - } -} - -func TestInvalidValues(t *testing.T) { - softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) - if err != nil { - t.Fatal(err) - } - defer softwareK.Close() - - testKName := randKeyName("TestInvalidValues_") - - k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) - if err != nil { - t.Fatal(err) - } - defer k.Close() - - if exist { - t.Fatalf("key %q already exists", testKName) - } - - defer registry.DeleteKey(softwareK, testKName) - - var tests = []struct { - Type uint32 - Name string - Data []byte - }{ - {registry.DWORD, "Dword1", nil}, - {registry.DWORD, "Dword2", []byte{1, 2, 3}}, - {registry.QWORD, "Qword1", nil}, - {registry.QWORD, "Qword2", []byte{1, 2, 3}}, - {registry.QWORD, "Qword3", []byte{1, 2, 3, 4, 5, 6, 7}}, - {registry.MULTI_SZ, "MultiString1", nil}, - {registry.MULTI_SZ, "MultiString2", []byte{0}}, - {registry.MULTI_SZ, "MultiString3", []byte{'a', 'b', 0}}, - {registry.MULTI_SZ, "MultiString4", []byte{'a', 0, 0, 'b', 0}}, - {registry.MULTI_SZ, "MultiString5", []byte{'a', 0, 0}}, - } - - for _, test := range tests { - err := k.SetValue(test.Name, test.Type, test.Data) - if err != nil { - t.Fatalf("SetValue for %q failed: %v", test.Name, err) - } - } - - for _, test := range tests { - switch test.Type { - case registry.DWORD, registry.QWORD: - value, valType, err := k.GetIntegerValue(test.Name) - if err == nil { - t.Errorf("GetIntegerValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) - } - case registry.MULTI_SZ: - value, valType, err := k.GetStringsValue(test.Name) - if err == nil { - if len(value) != 0 { - t.Errorf("GetStringsValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) - } - } - default: - t.Errorf("unsupported type %d for %s value", test.Type, test.Name) - } - } -} - -func TestGetMUIStringValue(t *testing.T) { - if err := registry.LoadRegLoadMUIString(); err != nil { - t.Skip("regLoadMUIString not supported; skipping") - } - if err := procGetDynamicTimeZoneInformation.Find(); err != nil { - t.Skipf("%s not supported; skipping", procGetDynamicTimeZoneInformation.Name) - } - var dtzi DynamicTimezoneinformation - if _, err := GetDynamicTimeZoneInformation(&dtzi); err != nil { - t.Fatal(err) - } - tzKeyName := syscall.UTF16ToString(dtzi.TimeZoneKeyName[:]) - timezoneK, err := registry.OpenKey(registry.LOCAL_MACHINE, - `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\`+tzKeyName, registry.READ) - if err != nil { - t.Fatal(err) - } - defer timezoneK.Close() - - type testType struct { - name string - want string - } - var tests = []testType{ - {"MUI_Std", syscall.UTF16ToString(dtzi.StandardName[:])}, - } - if dtzi.DynamicDaylightTimeDisabled == 0 { - tests = append(tests, testType{"MUI_Dlt", syscall.UTF16ToString(dtzi.DaylightName[:])}) - } - - for _, test := range tests { - got, err := timezoneK.GetMUIStringValue(test.name) - if err != nil { - t.Error("GetMUIStringValue:", err) - } - - if got != test.want { - t.Errorf("GetMUIStringValue: %s: Got %q, want %q", test.name, got, test.want) - } - } -} - -type DynamicTimezoneinformation struct { - Bias int32 - StandardName [32]uint16 - StandardDate syscall.Systemtime - StandardBias int32 - DaylightName [32]uint16 - DaylightDate syscall.Systemtime - DaylightBias int32 - TimeZoneKeyName [128]uint16 - DynamicDaylightTimeDisabled uint8 -} - -var ( - kernel32DLL = syscall.NewLazyDLL("kernel32") - - procGetDynamicTimeZoneInformation = kernel32DLL.NewProc("GetDynamicTimeZoneInformation") -) - -func GetDynamicTimeZoneInformation(dtzi *DynamicTimezoneinformation) (rc uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetDynamicTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(dtzi)), 0, 0) - rc = uint32(r0) - if rc == 0xffffffff { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/vendor/golang.org/x/sys/windows/registry/syscall.go b/vendor/golang.org/x/sys/windows/registry/syscall.go deleted file mode 100644 index e66643c..0000000 --- a/vendor/golang.org/x/sys/windows/registry/syscall.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 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 - -package registry - -import "syscall" - -const ( - _REG_OPTION_NON_VOLATILE = 0 - - _REG_CREATED_NEW_KEY = 1 - _REG_OPENED_EXISTING_KEY = 2 - - _ERROR_NO_MORE_ITEMS syscall.Errno = 259 -) - -func LoadRegLoadMUIString() error { - return procRegLoadMUIStringW.Find() -} - -//sys regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW -//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW -//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW -//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW -//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW -//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW -//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW - -//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW diff --git a/vendor/golang.org/x/sys/windows/registry/value.go b/vendor/golang.org/x/sys/windows/registry/value.go deleted file mode 100644 index 71d4e15..0000000 --- a/vendor/golang.org/x/sys/windows/registry/value.go +++ /dev/null @@ -1,384 +0,0 @@ -// Copyright 2015 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 - -package registry - -import ( - "errors" - "io" - "syscall" - "unicode/utf16" - "unsafe" -) - -const ( - // Registry value types. - NONE = 0 - SZ = 1 - EXPAND_SZ = 2 - BINARY = 3 - DWORD = 4 - DWORD_BIG_ENDIAN = 5 - LINK = 6 - MULTI_SZ = 7 - RESOURCE_LIST = 8 - FULL_RESOURCE_DESCRIPTOR = 9 - RESOURCE_REQUIREMENTS_LIST = 10 - QWORD = 11 -) - -var ( - // ErrShortBuffer is returned when the buffer was too short for the operation. - ErrShortBuffer = syscall.ERROR_MORE_DATA - - // ErrNotExist is returned when a registry key or value does not exist. - ErrNotExist = syscall.ERROR_FILE_NOT_FOUND - - // ErrUnexpectedType is returned by Get*Value when the value's type was unexpected. - ErrUnexpectedType = errors.New("unexpected key value type") -) - -// GetValue retrieves the type and data for the specified value associated -// with an open key k. It fills up buffer buf and returns the retrieved -// byte count n. If buf is too small to fit the stored value it returns -// ErrShortBuffer error along with the required buffer size n. -// If no buffer is provided, it returns true and actual buffer size n. -// If no buffer is provided, GetValue returns the value's type only. -// If the value does not exist, the error returned is ErrNotExist. -// -// GetValue is a low level function. If value's type is known, use the appropriate -// Get*Value function instead. -func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) { - pname, err := syscall.UTF16PtrFromString(name) - if err != nil { - return 0, 0, err - } - var pbuf *byte - if len(buf) > 0 { - pbuf = (*byte)(unsafe.Pointer(&buf[0])) - } - l := uint32(len(buf)) - err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l) - if err != nil { - return int(l), valtype, err - } - return int(l), valtype, nil -} - -func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) { - p, err := syscall.UTF16PtrFromString(name) - if err != nil { - return nil, 0, err - } - var t uint32 - n := uint32(len(buf)) - for { - err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n) - if err == nil { - return buf[:n], t, nil - } - if err != syscall.ERROR_MORE_DATA { - return nil, 0, err - } - if n <= uint32(len(buf)) { - return nil, 0, err - } - buf = make([]byte, n) - } -} - -// GetStringValue retrieves the string value for the specified -// value name associated with an open key k. It also returns the value's type. -// If value does not exist, GetStringValue returns ErrNotExist. -// If value is not SZ or EXPAND_SZ, it will return the correct value -// type and ErrUnexpectedType. -func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) { - data, typ, err2 := k.getValue(name, make([]byte, 64)) - if err2 != nil { - return "", typ, err2 - } - switch typ { - case SZ, EXPAND_SZ: - default: - return "", typ, ErrUnexpectedType - } - if len(data) == 0 { - return "", typ, nil - } - u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:] - return syscall.UTF16ToString(u), typ, nil -} - -// GetMUIStringValue retrieves the localized string value for -// the specified value name associated with an open key k. -// If the value name doesn't exist or the localized string value -// can't be resolved, GetMUIStringValue returns ErrNotExist. -// GetMUIStringValue panics if the system doesn't support -// regLoadMUIString; use LoadRegLoadMUIString to check if -// regLoadMUIString is supported before calling this function. -func (k Key) GetMUIStringValue(name string) (string, error) { - pname, err := syscall.UTF16PtrFromString(name) - if err != nil { - return "", err - } - - buf := make([]uint16, 1024) - var buflen uint32 - var pdir *uint16 - - err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) - if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path - - // Try to resolve the string value using the system directory as - // a DLL search path; this assumes the string value is of the form - // @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320. - - // This approach works with tzres.dll but may have to be revised - // in the future to allow callers to provide custom search paths. - - var s string - s, err = ExpandString("%SystemRoot%\\system32\\") - if err != nil { - return "", err - } - pdir, err = syscall.UTF16PtrFromString(s) - if err != nil { - return "", err - } - - err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) - } - - for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed - if buflen <= uint32(len(buf)) { - break // Buffer not growing, assume race; break - } - buf = make([]uint16, buflen) - err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) - } - - if err != nil { - return "", err - } - - return syscall.UTF16ToString(buf), nil -} - -// ExpandString expands environment-variable strings and replaces -// them with the values defined for the current user. -// Use ExpandString to expand EXPAND_SZ strings. -func ExpandString(value string) (string, error) { - if value == "" { - return "", nil - } - p, err := syscall.UTF16PtrFromString(value) - if err != nil { - return "", err - } - r := make([]uint16, 100) - for { - n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r))) - if err != nil { - return "", err - } - if n <= uint32(len(r)) { - u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:] - return syscall.UTF16ToString(u), nil - } - r = make([]uint16, n) - } -} - -// GetStringsValue retrieves the []string value for the specified -// value name associated with an open key k. It also returns the value's type. -// If value does not exist, GetStringsValue returns ErrNotExist. -// If value is not MULTI_SZ, it will return the correct value -// type and ErrUnexpectedType. -func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) { - data, typ, err2 := k.getValue(name, make([]byte, 64)) - if err2 != nil { - return nil, typ, err2 - } - if typ != MULTI_SZ { - return nil, typ, ErrUnexpectedType - } - if len(data) == 0 { - return nil, typ, nil - } - p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2] - if len(p) == 0 { - return nil, typ, nil - } - if p[len(p)-1] == 0 { - p = p[:len(p)-1] // remove terminating null - } - val = make([]string, 0, 5) - from := 0 - for i, c := range p { - if c == 0 { - val = append(val, string(utf16.Decode(p[from:i]))) - from = i + 1 - } - } - return val, typ, nil -} - -// GetIntegerValue retrieves the integer value for the specified -// value name associated with an open key k. It also returns the value's type. -// If value does not exist, GetIntegerValue returns ErrNotExist. -// If value is not DWORD or QWORD, it will return the correct value -// type and ErrUnexpectedType. -func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) { - data, typ, err2 := k.getValue(name, make([]byte, 8)) - if err2 != nil { - return 0, typ, err2 - } - switch typ { - case DWORD: - if len(data) != 4 { - return 0, typ, errors.New("DWORD value is not 4 bytes long") - } - return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil - case QWORD: - if len(data) != 8 { - return 0, typ, errors.New("QWORD value is not 8 bytes long") - } - return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil - default: - return 0, typ, ErrUnexpectedType - } -} - -// GetBinaryValue retrieves the binary value for the specified -// value name associated with an open key k. It also returns the value's type. -// If value does not exist, GetBinaryValue returns ErrNotExist. -// If value is not BINARY, it will return the correct value -// type and ErrUnexpectedType. -func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) { - data, typ, err2 := k.getValue(name, make([]byte, 64)) - if err2 != nil { - return nil, typ, err2 - } - if typ != BINARY { - return nil, typ, ErrUnexpectedType - } - return data, typ, nil -} - -func (k Key) setValue(name string, valtype uint32, data []byte) error { - p, err := syscall.UTF16PtrFromString(name) - if err != nil { - return err - } - if len(data) == 0 { - return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0) - } - return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data))) -} - -// SetDWordValue sets the data and type of a name value -// under key k to value and DWORD. -func (k Key) SetDWordValue(name string, value uint32) error { - return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:]) -} - -// SetQWordValue sets the data and type of a name value -// under key k to value and QWORD. -func (k Key) SetQWordValue(name string, value uint64) error { - return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:]) -} - -func (k Key) setStringValue(name string, valtype uint32, value string) error { - v, err := syscall.UTF16FromString(value) - if err != nil { - return err - } - buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2] - return k.setValue(name, valtype, buf) -} - -// SetStringValue sets the data and type of a name value -// under key k to value and SZ. The value must not contain a zero byte. -func (k Key) SetStringValue(name, value string) error { - return k.setStringValue(name, SZ, value) -} - -// SetExpandStringValue sets the data and type of a name value -// under key k to value and EXPAND_SZ. The value must not contain a zero byte. -func (k Key) SetExpandStringValue(name, value string) error { - return k.setStringValue(name, EXPAND_SZ, value) -} - -// SetStringsValue sets the data and type of a name value -// under key k to value and MULTI_SZ. The value strings -// must not contain a zero byte. -func (k Key) SetStringsValue(name string, value []string) error { - ss := "" - for _, s := range value { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return errors.New("string cannot have 0 inside") - } - } - ss += s + "\x00" - } - v := utf16.Encode([]rune(ss + "\x00")) - buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2] - return k.setValue(name, MULTI_SZ, buf) -} - -// SetBinaryValue sets the data and type of a name value -// under key k to value and BINARY. -func (k Key) SetBinaryValue(name string, value []byte) error { - return k.setValue(name, BINARY, value) -} - -// DeleteValue removes a named value from the key k. -func (k Key) DeleteValue(name string) error { - return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name)) -} - -// ReadValueNames returns the value names of key k. -// The parameter n controls the number of returned names, -// analogous to the way os.File.Readdirnames works. -func (k Key) ReadValueNames(n int) ([]string, error) { - ki, err := k.Stat() - if err != nil { - return nil, err - } - names := make([]string, 0, ki.ValueCount) - buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character -loopItems: - for i := uint32(0); ; i++ { - if n > 0 { - if len(names) == n { - return names, nil - } - } - l := uint32(len(buf)) - for { - err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) - if err == nil { - break - } - if err == syscall.ERROR_MORE_DATA { - // Double buffer size and try again. - l = uint32(2 * len(buf)) - buf = make([]uint16, l) - continue - } - if err == _ERROR_NO_MORE_ITEMS { - break loopItems - } - return names, err - } - names = append(names, syscall.UTF16ToString(buf[:l])) - } - if n > len(names) { - return names, io.EOF - } - return names, nil -} diff --git a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go deleted file mode 100644 index ceebdd7..0000000 --- a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go +++ /dev/null @@ -1,120 +0,0 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT - -package registry - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - - procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW") - procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW") - procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW") - procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") - procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW") - procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW") - procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW") - procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW") -) - -func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition))) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result))) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go deleted file mode 100644 index f1ec5dc..0000000 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ /dev/null @@ -1,476 +0,0 @@ -// 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 windows - -import ( - "syscall" - "unsafe" -) - -const ( - STANDARD_RIGHTS_REQUIRED = 0xf0000 - STANDARD_RIGHTS_READ = 0x20000 - STANDARD_RIGHTS_WRITE = 0x20000 - STANDARD_RIGHTS_EXECUTE = 0x20000 - STANDARD_RIGHTS_ALL = 0x1F0000 -) - -const ( - NameUnknown = 0 - NameFullyQualifiedDN = 1 - NameSamCompatible = 2 - NameDisplay = 3 - NameUniqueId = 6 - NameCanonical = 7 - NameUserPrincipal = 8 - NameCanonicalEx = 9 - NameServicePrincipal = 10 - NameDnsDomain = 12 -) - -// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. -// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx -//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW -//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW - -// TranslateAccountName converts a directory service -// object name from one format to another. -func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { - u, e := UTF16PtrFromString(username) - if e != nil { - return "", e - } - n := uint32(50) - for { - b := make([]uint16, n) - e = TranslateName(u, from, to, &b[0], &n) - if e == nil { - return UTF16ToString(b[:n]), nil - } - if e != ERROR_INSUFFICIENT_BUFFER { - return "", e - } - if n <= uint32(len(b)) { - return "", e - } - } -} - -const ( - // do not reorder - NetSetupUnknownStatus = iota - NetSetupUnjoined - NetSetupWorkgroupName - NetSetupDomainName -) - -type UserInfo10 struct { - Name *uint16 - Comment *uint16 - UsrComment *uint16 - FullName *uint16 -} - -//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo -//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation -//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree - -const ( - // do not reorder - SidTypeUser = 1 + iota - SidTypeGroup - SidTypeDomain - SidTypeAlias - SidTypeWellKnownGroup - SidTypeDeletedAccount - SidTypeInvalid - SidTypeUnknown - SidTypeComputer - SidTypeLabel -) - -type SidIdentifierAuthority struct { - Value [6]byte -} - -var ( - SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}} - SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}} - SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}} - SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}} - SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}} - SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}} - SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}} -) - -const ( - SECURITY_NULL_RID = 0 - SECURITY_WORLD_RID = 0 - SECURITY_LOCAL_RID = 0 - SECURITY_CREATOR_OWNER_RID = 0 - SECURITY_CREATOR_GROUP_RID = 1 - SECURITY_DIALUP_RID = 1 - SECURITY_NETWORK_RID = 2 - SECURITY_BATCH_RID = 3 - SECURITY_INTERACTIVE_RID = 4 - SECURITY_LOGON_IDS_RID = 5 - SECURITY_SERVICE_RID = 6 - SECURITY_LOCAL_SYSTEM_RID = 18 - SECURITY_BUILTIN_DOMAIN_RID = 32 - SECURITY_PRINCIPAL_SELF_RID = 10 - SECURITY_CREATOR_OWNER_SERVER_RID = 0x2 - SECURITY_CREATOR_GROUP_SERVER_RID = 0x3 - SECURITY_LOGON_IDS_RID_COUNT = 0x3 - SECURITY_ANONYMOUS_LOGON_RID = 0x7 - SECURITY_PROXY_RID = 0x8 - SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9 - SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID - SECURITY_AUTHENTICATED_USER_RID = 0xb - SECURITY_RESTRICTED_CODE_RID = 0xc - SECURITY_NT_NON_UNIQUE_RID = 0x15 -) - -// Predefined domain-relative RIDs for local groups. -// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx -const ( - DOMAIN_ALIAS_RID_ADMINS = 0x220 - DOMAIN_ALIAS_RID_USERS = 0x221 - DOMAIN_ALIAS_RID_GUESTS = 0x222 - DOMAIN_ALIAS_RID_POWER_USERS = 0x223 - DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224 - DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225 - DOMAIN_ALIAS_RID_PRINT_OPS = 0x226 - DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227 - DOMAIN_ALIAS_RID_REPLICATOR = 0x228 - DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229 - DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a - DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b - DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c - DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d - DOMAIN_ALIAS_RID_MONITORING_USERS = 0X22e - DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f - DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 - DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 - DOMAIN_ALIAS_RID_DCOM_USERS = 0x232 - DOMAIN_ALIAS_RID_IUSERS = 0x238 - DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239 - DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b - DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c - DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d - DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e -) - -//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW -//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW -//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW -//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW -//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid -//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid -//sys AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid -//sys FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid -//sys EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid - -// The security identifier (SID) structure is a variable-length -// structure used to uniquely identify users or groups. -type SID struct{} - -// StringToSid converts a string-format security identifier -// sid into a valid, functional sid. -func StringToSid(s string) (*SID, error) { - var sid *SID - p, e := UTF16PtrFromString(s) - if e != nil { - return nil, e - } - e = ConvertStringSidToSid(p, &sid) - if e != nil { - return nil, e - } - defer LocalFree((Handle)(unsafe.Pointer(sid))) - return sid.Copy() -} - -// LookupSID retrieves a security identifier sid for the account -// and the name of the domain on which the account was found. -// System specify target computer to search. -func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { - if len(account) == 0 { - return nil, "", 0, syscall.EINVAL - } - acc, e := UTF16PtrFromString(account) - if e != nil { - return nil, "", 0, e - } - var sys *uint16 - if len(system) > 0 { - sys, e = UTF16PtrFromString(system) - if e != nil { - return nil, "", 0, e - } - } - n := uint32(50) - dn := uint32(50) - for { - b := make([]byte, n) - db := make([]uint16, dn) - sid = (*SID)(unsafe.Pointer(&b[0])) - e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) - if e == nil { - return sid, UTF16ToString(db), accType, nil - } - if e != ERROR_INSUFFICIENT_BUFFER { - return nil, "", 0, e - } - if n <= uint32(len(b)) { - return nil, "", 0, e - } - } -} - -// String converts sid to a string format -// suitable for display, storage, or transmission. -func (sid *SID) String() (string, error) { - var s *uint16 - e := ConvertSidToStringSid(sid, &s) - if e != nil { - return "", e - } - defer LocalFree((Handle)(unsafe.Pointer(s))) - return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil -} - -// Len returns the length, in bytes, of a valid security identifier sid. -func (sid *SID) Len() int { - return int(GetLengthSid(sid)) -} - -// Copy creates a duplicate of security identifier sid. -func (sid *SID) Copy() (*SID, error) { - b := make([]byte, sid.Len()) - sid2 := (*SID)(unsafe.Pointer(&b[0])) - e := CopySid(uint32(len(b)), sid2, sid) - if e != nil { - return nil, e - } - return sid2, nil -} - -// LookupAccount retrieves the name of the account for this sid -// and the name of the first domain on which this sid is found. -// System specify target computer to search for. -func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { - var sys *uint16 - if len(system) > 0 { - sys, err = UTF16PtrFromString(system) - if err != nil { - return "", "", 0, err - } - } - n := uint32(50) - dn := uint32(50) - for { - b := make([]uint16, n) - db := make([]uint16, dn) - e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) - if e == nil { - return UTF16ToString(b), UTF16ToString(db), accType, nil - } - if e != ERROR_INSUFFICIENT_BUFFER { - return "", "", 0, e - } - if n <= uint32(len(b)) { - return "", "", 0, e - } - } -} - -const ( - // do not reorder - TOKEN_ASSIGN_PRIMARY = 1 << iota - TOKEN_DUPLICATE - TOKEN_IMPERSONATE - TOKEN_QUERY - TOKEN_QUERY_SOURCE - TOKEN_ADJUST_PRIVILEGES - TOKEN_ADJUST_GROUPS - TOKEN_ADJUST_DEFAULT - - TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | - TOKEN_ASSIGN_PRIMARY | - TOKEN_DUPLICATE | - TOKEN_IMPERSONATE | - TOKEN_QUERY | - TOKEN_QUERY_SOURCE | - TOKEN_ADJUST_PRIVILEGES | - TOKEN_ADJUST_GROUPS | - TOKEN_ADJUST_DEFAULT - TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY - TOKEN_WRITE = STANDARD_RIGHTS_WRITE | - TOKEN_ADJUST_PRIVILEGES | - TOKEN_ADJUST_GROUPS | - TOKEN_ADJUST_DEFAULT - TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE -) - -const ( - // do not reorder - TokenUser = 1 + iota - TokenGroups - TokenPrivileges - TokenOwner - TokenPrimaryGroup - TokenDefaultDacl - TokenSource - TokenType - TokenImpersonationLevel - TokenStatistics - TokenRestrictedSids - TokenSessionId - TokenGroupsAndPrivileges - TokenSessionReference - TokenSandBoxInert - TokenAuditPolicy - TokenOrigin - TokenElevationType - TokenLinkedToken - TokenElevation - TokenHasRestrictions - TokenAccessInformation - TokenVirtualizationAllowed - TokenVirtualizationEnabled - TokenIntegrityLevel - TokenUIAccess - TokenMandatoryPolicy - TokenLogonSid - MaxTokenInfoClass -) - -type SIDAndAttributes struct { - Sid *SID - Attributes uint32 -} - -type Tokenuser struct { - User SIDAndAttributes -} - -type Tokenprimarygroup struct { - PrimaryGroup *SID -} - -type Tokengroups struct { - GroupCount uint32 - Groups [1]SIDAndAttributes -} - -// Authorization Functions -//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership -//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken -//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation -//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW - -// An access token contains the security information for a logon session. -// The system creates an access token when a user logs on, and every -// process executed on behalf of the user has a copy of the token. -// The token identifies the user, the user's groups, and the user's -// privileges. The system uses the token to control access to securable -// objects and to control the ability of the user to perform various -// system-related operations on the local computer. -type Token Handle - -// OpenCurrentProcessToken opens the access token -// associated with current process. -func OpenCurrentProcessToken() (Token, error) { - p, e := GetCurrentProcess() - if e != nil { - return 0, e - } - var t Token - e = OpenProcessToken(p, TOKEN_QUERY, &t) - if e != nil { - return 0, e - } - return t, nil -} - -// Close releases access to access token. -func (t Token) Close() error { - return CloseHandle(Handle(t)) -} - -// getInfo retrieves a specified type of information about an access token. -func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { - n := uint32(initSize) - for { - b := make([]byte, n) - e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) - if e == nil { - return unsafe.Pointer(&b[0]), nil - } - if e != ERROR_INSUFFICIENT_BUFFER { - return nil, e - } - if n <= uint32(len(b)) { - return nil, e - } - } -} - -// GetTokenUser retrieves access token t user account information. -func (t Token) GetTokenUser() (*Tokenuser, error) { - i, e := t.getInfo(TokenUser, 50) - if e != nil { - return nil, e - } - return (*Tokenuser)(i), nil -} - -// GetTokenGroups retrieves group accounts associated with access token t. -func (t Token) GetTokenGroups() (*Tokengroups, error) { - i, e := t.getInfo(TokenGroups, 50) - if e != nil { - return nil, e - } - return (*Tokengroups)(i), nil -} - -// GetTokenPrimaryGroup retrieves access token t primary group information. -// A pointer to a SID structure representing a group that will become -// the primary group of any objects created by a process using this access token. -func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { - i, e := t.getInfo(TokenPrimaryGroup, 50) - if e != nil { - return nil, e - } - return (*Tokenprimarygroup)(i), nil -} - -// GetUserProfileDirectory retrieves path to the -// root directory of the access token t user's profile. -func (t Token) GetUserProfileDirectory() (string, error) { - n := uint32(100) - for { - b := make([]uint16, n) - e := GetUserProfileDirectory(t, &b[0], &n) - if e == nil { - return UTF16ToString(b), nil - } - if e != ERROR_INSUFFICIENT_BUFFER { - return "", e - } - if n <= uint32(len(b)) { - return "", e - } - } -} - -// IsMember reports whether the access token t is a member of the provided SID. -func (t Token) IsMember(sid *SID) (bool, error) { - var b int32 - if e := checkTokenMembership(t, sid, &b); e != nil { - return false, e - } - return b != 0, nil -} diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go deleted file mode 100644 index a500dd7..0000000 --- a/vendor/golang.org/x/sys/windows/service.go +++ /dev/null @@ -1,164 +0,0 @@ -// 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 windows - -package windows - -const ( - SC_MANAGER_CONNECT = 1 - SC_MANAGER_CREATE_SERVICE = 2 - SC_MANAGER_ENUMERATE_SERVICE = 4 - SC_MANAGER_LOCK = 8 - SC_MANAGER_QUERY_LOCK_STATUS = 16 - SC_MANAGER_MODIFY_BOOT_CONFIG = 32 - SC_MANAGER_ALL_ACCESS = 0xf003f -) - -//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW - -const ( - SERVICE_KERNEL_DRIVER = 1 - SERVICE_FILE_SYSTEM_DRIVER = 2 - SERVICE_ADAPTER = 4 - SERVICE_RECOGNIZER_DRIVER = 8 - SERVICE_WIN32_OWN_PROCESS = 16 - SERVICE_WIN32_SHARE_PROCESS = 32 - SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS - SERVICE_INTERACTIVE_PROCESS = 256 - SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER - SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS - - SERVICE_BOOT_START = 0 - SERVICE_SYSTEM_START = 1 - SERVICE_AUTO_START = 2 - SERVICE_DEMAND_START = 3 - SERVICE_DISABLED = 4 - - SERVICE_ERROR_IGNORE = 0 - SERVICE_ERROR_NORMAL = 1 - SERVICE_ERROR_SEVERE = 2 - SERVICE_ERROR_CRITICAL = 3 - - SC_STATUS_PROCESS_INFO = 0 - - SERVICE_STOPPED = 1 - SERVICE_START_PENDING = 2 - SERVICE_STOP_PENDING = 3 - SERVICE_RUNNING = 4 - SERVICE_CONTINUE_PENDING = 5 - SERVICE_PAUSE_PENDING = 6 - SERVICE_PAUSED = 7 - SERVICE_NO_CHANGE = 0xffffffff - - SERVICE_ACCEPT_STOP = 1 - SERVICE_ACCEPT_PAUSE_CONTINUE = 2 - SERVICE_ACCEPT_SHUTDOWN = 4 - SERVICE_ACCEPT_PARAMCHANGE = 8 - SERVICE_ACCEPT_NETBINDCHANGE = 16 - SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 - SERVICE_ACCEPT_POWEREVENT = 64 - SERVICE_ACCEPT_SESSIONCHANGE = 128 - - SERVICE_CONTROL_STOP = 1 - SERVICE_CONTROL_PAUSE = 2 - SERVICE_CONTROL_CONTINUE = 3 - SERVICE_CONTROL_INTERROGATE = 4 - SERVICE_CONTROL_SHUTDOWN = 5 - SERVICE_CONTROL_PARAMCHANGE = 6 - SERVICE_CONTROL_NETBINDADD = 7 - SERVICE_CONTROL_NETBINDREMOVE = 8 - SERVICE_CONTROL_NETBINDENABLE = 9 - SERVICE_CONTROL_NETBINDDISABLE = 10 - SERVICE_CONTROL_DEVICEEVENT = 11 - SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 - SERVICE_CONTROL_POWEREVENT = 13 - SERVICE_CONTROL_SESSIONCHANGE = 14 - - SERVICE_ACTIVE = 1 - SERVICE_INACTIVE = 2 - SERVICE_STATE_ALL = 3 - - SERVICE_QUERY_CONFIG = 1 - SERVICE_CHANGE_CONFIG = 2 - SERVICE_QUERY_STATUS = 4 - SERVICE_ENUMERATE_DEPENDENTS = 8 - SERVICE_START = 16 - SERVICE_STOP = 32 - SERVICE_PAUSE_CONTINUE = 64 - SERVICE_INTERROGATE = 128 - SERVICE_USER_DEFINED_CONTROL = 256 - SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL - SERVICE_RUNS_IN_SYSTEM_PROCESS = 1 - SERVICE_CONFIG_DESCRIPTION = 1 - SERVICE_CONFIG_FAILURE_ACTIONS = 2 - - NO_ERROR = 0 - - SC_ENUM_PROCESS_INFO = 0 -) - -type SERVICE_STATUS struct { - ServiceType uint32 - CurrentState uint32 - ControlsAccepted uint32 - Win32ExitCode uint32 - ServiceSpecificExitCode uint32 - CheckPoint uint32 - WaitHint uint32 -} - -type SERVICE_TABLE_ENTRY struct { - ServiceName *uint16 - ServiceProc uintptr -} - -type QUERY_SERVICE_CONFIG struct { - ServiceType uint32 - StartType uint32 - ErrorControl uint32 - BinaryPathName *uint16 - LoadOrderGroup *uint16 - TagId uint32 - Dependencies *uint16 - ServiceStartName *uint16 - DisplayName *uint16 -} - -type SERVICE_DESCRIPTION struct { - Description *uint16 -} - -type SERVICE_STATUS_PROCESS struct { - ServiceType uint32 - CurrentState uint32 - ControlsAccepted uint32 - Win32ExitCode uint32 - ServiceSpecificExitCode uint32 - CheckPoint uint32 - WaitHint uint32 - ProcessId uint32 - ServiceFlags uint32 -} - -type ENUM_SERVICE_STATUS_PROCESS struct { - ServiceName *uint16 - DisplayName *uint16 - ServiceStatusProcess SERVICE_STATUS_PROCESS -} - -//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle -//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW -//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW -//sys DeleteService(service Handle) (err error) = advapi32.DeleteService -//sys StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW -//sys QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus -//sys ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService -//sys StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW -//sys SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus -//sys ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW -//sys QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW -//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W -//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W -//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go deleted file mode 100644 index 917cc2a..0000000 --- a/vendor/golang.org/x/sys/windows/str.go +++ /dev/null @@ -1,22 +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 windows - -package windows - -func itoa(val int) string { // do it here rather than with fmt to avoid dependency - if val < 0 { - return "-" + itoa(-val) - } - var buf [32]byte // big enough for int64 - i := len(buf) - 1 - for val >= 10 { - buf[i] = byte(val%10 + '0') - i-- - val /= 10 - } - buf[i] = byte(val + '0') - return string(buf[i:]) -} diff --git a/vendor/golang.org/x/sys/windows/svc/debug/log.go b/vendor/golang.org/x/sys/windows/svc/debug/log.go deleted file mode 100644 index e51ab42..0000000 --- a/vendor/golang.org/x/sys/windows/svc/debug/log.go +++ /dev/null @@ -1,56 +0,0 @@ -// 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 windows - -package debug - -import ( - "os" - "strconv" -) - -// Log interface allows different log implementations to be used. -type Log interface { - Close() error - Info(eid uint32, msg string) error - Warning(eid uint32, msg string) error - Error(eid uint32, msg string) error -} - -// ConsoleLog provides access to the console. -type ConsoleLog struct { - Name string -} - -// New creates new ConsoleLog. -func New(source string) *ConsoleLog { - return &ConsoleLog{Name: source} -} - -// Close closes console log l. -func (l *ConsoleLog) Close() error { - return nil -} - -func (l *ConsoleLog) report(kind string, eid uint32, msg string) error { - s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n" - _, err := os.Stdout.Write([]byte(s)) - return err -} - -// Info writes an information event msg with event id eid to the console l. -func (l *ConsoleLog) Info(eid uint32, msg string) error { - return l.report("info", eid, msg) -} - -// Warning writes an warning event msg with event id eid to the console l. -func (l *ConsoleLog) Warning(eid uint32, msg string) error { - return l.report("warn", eid, msg) -} - -// Error writes an error event msg with event id eid to the console l. -func (l *ConsoleLog) Error(eid uint32, msg string) error { - return l.report("error", eid, msg) -} diff --git a/vendor/golang.org/x/sys/windows/svc/debug/service.go b/vendor/golang.org/x/sys/windows/svc/debug/service.go deleted file mode 100644 index 123df98..0000000 --- a/vendor/golang.org/x/sys/windows/svc/debug/service.go +++ /dev/null @@ -1,45 +0,0 @@ -// 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 windows - -// Package debug provides facilities to execute svc.Handler on console. -// -package debug - -import ( - "os" - "os/signal" - "syscall" - - "golang.org/x/sys/windows/svc" -) - -// Run executes service name by calling appropriate handler function. -// The process is running on console, unlike real service. Use Ctrl+C to -// send "Stop" command to your service. -func Run(name string, handler svc.Handler) error { - cmds := make(chan svc.ChangeRequest) - changes := make(chan svc.Status) - - sig := make(chan os.Signal) - signal.Notify(sig) - - go func() { - status := svc.Status{State: svc.Stopped} - for { - select { - case <-sig: - cmds <- svc.ChangeRequest{svc.Stop, 0, 0, status} - case status = <-changes: - } - } - }() - - _, errno := handler.Execute([]string{name}, cmds, changes) - if errno != 0 { - return syscall.Errno(errno) - } - return nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/event.go b/vendor/golang.org/x/sys/windows/svc/event.go deleted file mode 100644 index 0508e22..0000000 --- a/vendor/golang.org/x/sys/windows/svc/event.go +++ /dev/null @@ -1,48 +0,0 @@ -// 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 windows - -package svc - -import ( - "errors" - - "golang.org/x/sys/windows" -) - -// event represents auto-reset, initially non-signaled Windows event. -// It is used to communicate between go and asm parts of this package. -type event struct { - h windows.Handle -} - -func newEvent() (*event, error) { - h, err := windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return nil, err - } - return &event{h: h}, nil -} - -func (e *event) Close() error { - return windows.CloseHandle(e.h) -} - -func (e *event) Set() error { - return windows.SetEvent(e.h) -} - -func (e *event) Wait() error { - s, err := windows.WaitForSingleObject(e.h, windows.INFINITE) - switch s { - case windows.WAIT_OBJECT_0: - break - case windows.WAIT_FAILED: - return err - default: - return errors.New("unexpected result from WaitForSingleObject") - } - return nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/install.go b/vendor/golang.org/x/sys/windows/svc/eventlog/install.go deleted file mode 100644 index c76a376..0000000 --- a/vendor/golang.org/x/sys/windows/svc/eventlog/install.go +++ /dev/null @@ -1,80 +0,0 @@ -// 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 windows - -package eventlog - -import ( - "errors" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" -) - -const ( - // Log levels. - Info = windows.EVENTLOG_INFORMATION_TYPE - Warning = windows.EVENTLOG_WARNING_TYPE - Error = windows.EVENTLOG_ERROR_TYPE -) - -const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application` - -// Install modifies PC registry to allow logging with an event source src. -// It adds all required keys and values to the event log registry key. -// Install uses msgFile as the event message file. If useExpandKey is true, -// the event message file is installed as REG_EXPAND_SZ value, -// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and -// log.Info to specify events supported by the new event source. -func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error { - appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY) - if err != nil { - return err - } - defer appkey.Close() - - sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE) - if err != nil { - return err - } - defer sk.Close() - if alreadyExist { - return errors.New(addKeyName + `\` + src + " registry key already exists") - } - - err = sk.SetDWordValue("CustomSource", 1) - if err != nil { - return err - } - if useExpandKey { - err = sk.SetExpandStringValue("EventMessageFile", msgFile) - } else { - err = sk.SetStringValue("EventMessageFile", msgFile) - } - if err != nil { - return err - } - err = sk.SetDWordValue("TypesSupported", eventsSupported) - if err != nil { - return err - } - return nil -} - -// InstallAsEventCreate is the same as Install, but uses -// %SystemRoot%\System32\EventCreate.exe as the event message file. -func InstallAsEventCreate(src string, eventsSupported uint32) error { - return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported) -} - -// Remove deletes all registry elements installed by the correspondent Install. -func Remove(src string) error { - appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE) - if err != nil { - return err - } - defer appkey.Close() - return registry.DeleteKey(appkey, src) -} diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/log.go b/vendor/golang.org/x/sys/windows/svc/eventlog/log.go deleted file mode 100644 index 46e5153..0000000 --- a/vendor/golang.org/x/sys/windows/svc/eventlog/log.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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 windows - -// Package eventlog implements access to Windows event log. -// -package eventlog - -import ( - "errors" - "syscall" - - "golang.org/x/sys/windows" -) - -// Log provides access to the system log. -type Log struct { - Handle windows.Handle -} - -// Open retrieves a handle to the specified event log. -func Open(source string) (*Log, error) { - return OpenRemote("", source) -} - -// OpenRemote does the same as Open, but on different computer host. -func OpenRemote(host, source string) (*Log, error) { - if source == "" { - return nil, errors.New("Specify event log source") - } - var s *uint16 - if host != "" { - s = syscall.StringToUTF16Ptr(host) - } - h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source)) - if err != nil { - return nil, err - } - return &Log{Handle: h}, nil -} - -// Close closes event log l. -func (l *Log) Close() error { - return windows.DeregisterEventSource(l.Handle) -} - -func (l *Log) report(etype uint16, eid uint32, msg string) error { - ss := []*uint16{syscall.StringToUTF16Ptr(msg)} - return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil) -} - -// Info writes an information event msg with event id eid to the end of event log l. -// When EventCreate.exe is used, eid must be between 1 and 1000. -func (l *Log) Info(eid uint32, msg string) error { - return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg) -} - -// Warning writes an warning event msg with event id eid to the end of event log l. -// When EventCreate.exe is used, eid must be between 1 and 1000. -func (l *Log) Warning(eid uint32, msg string) error { - return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg) -} - -// Error writes an error event msg with event id eid to the end of event log l. -// When EventCreate.exe is used, eid must be between 1 and 1000. -func (l *Log) Error(eid uint32, msg string) error { - return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg) -} diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go b/vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go deleted file mode 100644 index 6fbbd4a..0000000 --- a/vendor/golang.org/x/sys/windows/svc/eventlog/log_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// 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 windows - -package eventlog_test - -import ( - "testing" - - "golang.org/x/sys/windows/svc/eventlog" -) - -func TestLog(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode - it modifies system logs") - } - - const name = "mylog" - const supports = eventlog.Error | eventlog.Warning | eventlog.Info - err := eventlog.InstallAsEventCreate(name, supports) - if err != nil { - t.Fatalf("Install failed: %s", err) - } - defer func() { - err = eventlog.Remove(name) - if err != nil { - t.Fatalf("Remove failed: %s", err) - } - }() - - l, err := eventlog.Open(name) - if err != nil { - t.Fatalf("Open failed: %s", err) - } - defer l.Close() - - err = l.Info(1, "info") - if err != nil { - t.Fatalf("Info failed: %s", err) - } - err = l.Warning(2, "warning") - if err != nil { - t.Fatalf("Warning failed: %s", err) - } - err = l.Error(3, "error") - if err != nil { - t.Fatalf("Error failed: %s", err) - } -} diff --git a/vendor/golang.org/x/sys/windows/svc/example/beep.go b/vendor/golang.org/x/sys/windows/svc/example/beep.go deleted file mode 100644 index dcf2340..0000000 --- a/vendor/golang.org/x/sys/windows/svc/example/beep.go +++ /dev/null @@ -1,22 +0,0 @@ -// 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 windows - -package main - -import ( - "syscall" -) - -// BUG(brainman): MessageBeep Windows api is broken on Windows 7, -// so this example does not beep when runs as service on Windows 7. - -var ( - beepFunc = syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBeep") -) - -func beep() { - beepFunc.Call(0xffffffff) -} diff --git a/vendor/golang.org/x/sys/windows/svc/example/install.go b/vendor/golang.org/x/sys/windows/svc/example/install.go deleted file mode 100644 index 39cb00d..0000000 --- a/vendor/golang.org/x/sys/windows/svc/example/install.go +++ /dev/null @@ -1,92 +0,0 @@ -// 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 windows - -package main - -import ( - "fmt" - "os" - "path/filepath" - - "golang.org/x/sys/windows/svc/eventlog" - "golang.org/x/sys/windows/svc/mgr" -) - -func exePath() (string, error) { - prog := os.Args[0] - p, err := filepath.Abs(prog) - if err != nil { - return "", err - } - fi, err := os.Stat(p) - if err == nil { - if !fi.Mode().IsDir() { - return p, nil - } - err = fmt.Errorf("%s is directory", p) - } - if filepath.Ext(p) == "" { - p += ".exe" - fi, err := os.Stat(p) - if err == nil { - if !fi.Mode().IsDir() { - return p, nil - } - err = fmt.Errorf("%s is directory", p) - } - } - return "", err -} - -func installService(name, desc string) error { - exepath, err := exePath() - if err != nil { - return err - } - m, err := mgr.Connect() - if err != nil { - return err - } - defer m.Disconnect() - s, err := m.OpenService(name) - if err == nil { - s.Close() - return fmt.Errorf("service %s already exists", name) - } - s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started") - if err != nil { - return err - } - defer s.Close() - err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info) - if err != nil { - s.Delete() - return fmt.Errorf("SetupEventLogSource() failed: %s", err) - } - return nil -} - -func removeService(name string) error { - m, err := mgr.Connect() - if err != nil { - return err - } - defer m.Disconnect() - s, err := m.OpenService(name) - if err != nil { - return fmt.Errorf("service %s is not installed", name) - } - defer s.Close() - err = s.Delete() - if err != nil { - return err - } - err = eventlog.Remove(name) - if err != nil { - return fmt.Errorf("RemoveEventLogSource() failed: %s", err) - } - return nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/example/main.go b/vendor/golang.org/x/sys/windows/svc/example/main.go deleted file mode 100644 index dc96c08..0000000 --- a/vendor/golang.org/x/sys/windows/svc/example/main.go +++ /dev/null @@ -1,76 +0,0 @@ -// 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 windows - -// Example service program that beeps. -// -// The program demonstrates how to create Windows service and -// install / remove it on a computer. It also shows how to -// stop / start / pause / continue any service, and how to -// write to event log. It also shows how to use debug -// facilities available in debug package. -// -package main - -import ( - "fmt" - "log" - "os" - "strings" - - "golang.org/x/sys/windows/svc" -) - -func usage(errmsg string) { - fmt.Fprintf(os.Stderr, - "%s\n\n"+ - "usage: %s \n"+ - " where is one of\n"+ - " install, remove, debug, start, stop, pause or continue.\n", - errmsg, os.Args[0]) - os.Exit(2) -} - -func main() { - const svcName = "myservice" - - isIntSess, err := svc.IsAnInteractiveSession() - if err != nil { - log.Fatalf("failed to determine if we are running in an interactive session: %v", err) - } - if !isIntSess { - runService(svcName, false) - return - } - - if len(os.Args) < 2 { - usage("no command specified") - } - - cmd := strings.ToLower(os.Args[1]) - switch cmd { - case "debug": - runService(svcName, true) - return - case "install": - err = installService(svcName, "my service") - case "remove": - err = removeService(svcName) - case "start": - err = startService(svcName) - case "stop": - err = controlService(svcName, svc.Stop, svc.Stopped) - case "pause": - err = controlService(svcName, svc.Pause, svc.Paused) - case "continue": - err = controlService(svcName, svc.Continue, svc.Running) - default: - usage(fmt.Sprintf("invalid command %s", cmd)) - } - if err != nil { - log.Fatalf("failed to %s %s: %v", cmd, svcName, err) - } - return -} diff --git a/vendor/golang.org/x/sys/windows/svc/example/manage.go b/vendor/golang.org/x/sys/windows/svc/example/manage.go deleted file mode 100644 index 782dbd9..0000000 --- a/vendor/golang.org/x/sys/windows/svc/example/manage.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 windows - -package main - -import ( - "fmt" - "time" - - "golang.org/x/sys/windows/svc" - "golang.org/x/sys/windows/svc/mgr" -) - -func startService(name string) error { - m, err := mgr.Connect() - if err != nil { - return err - } - defer m.Disconnect() - s, err := m.OpenService(name) - if err != nil { - return fmt.Errorf("could not access service: %v", err) - } - defer s.Close() - err = s.Start("is", "manual-started") - if err != nil { - return fmt.Errorf("could not start service: %v", err) - } - return nil -} - -func controlService(name string, c svc.Cmd, to svc.State) error { - m, err := mgr.Connect() - if err != nil { - return err - } - defer m.Disconnect() - s, err := m.OpenService(name) - if err != nil { - return fmt.Errorf("could not access service: %v", err) - } - defer s.Close() - status, err := s.Control(c) - if err != nil { - return fmt.Errorf("could not send control=%d: %v", c, err) - } - timeout := time.Now().Add(10 * time.Second) - for status.State != to { - if timeout.Before(time.Now()) { - return fmt.Errorf("timeout waiting for service to go to state=%d", to) - } - time.Sleep(300 * time.Millisecond) - status, err = s.Query() - if err != nil { - return fmt.Errorf("could not retrieve service status: %v", err) - } - } - return nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/example/service.go b/vendor/golang.org/x/sys/windows/svc/example/service.go deleted file mode 100644 index 237e809..0000000 --- a/vendor/golang.org/x/sys/windows/svc/example/service.go +++ /dev/null @@ -1,82 +0,0 @@ -// 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 windows - -package main - -import ( - "fmt" - "time" - - "golang.org/x/sys/windows/svc" - "golang.org/x/sys/windows/svc/debug" - "golang.org/x/sys/windows/svc/eventlog" -) - -var elog debug.Log - -type myservice struct{} - -func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { - const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue - changes <- svc.Status{State: svc.StartPending} - fasttick := time.Tick(500 * time.Millisecond) - slowtick := time.Tick(2 * time.Second) - tick := fasttick - changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} -loop: - for { - select { - case <-tick: - beep() - elog.Info(1, "beep") - case c := <-r: - switch c.Cmd { - case svc.Interrogate: - changes <- c.CurrentStatus - // Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4 - time.Sleep(100 * time.Millisecond) - changes <- c.CurrentStatus - case svc.Stop, svc.Shutdown: - break loop - case svc.Pause: - changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted} - tick = slowtick - case svc.Continue: - changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - tick = fasttick - default: - elog.Error(1, fmt.Sprintf("unexpected control request #%d", c)) - } - } - } - changes <- svc.Status{State: svc.StopPending} - return -} - -func runService(name string, isDebug bool) { - var err error - if isDebug { - elog = debug.New(name) - } else { - elog, err = eventlog.Open(name) - if err != nil { - return - } - } - defer elog.Close() - - elog.Info(1, fmt.Sprintf("starting %s service", name)) - run := svc.Run - if isDebug { - run = debug.Run - } - err = run(name, &myservice{}) - if err != nil { - elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err)) - return - } - elog.Info(1, fmt.Sprintf("%s service stopped", name)) -} diff --git a/vendor/golang.org/x/sys/windows/svc/go12.c b/vendor/golang.org/x/sys/windows/svc/go12.c deleted file mode 100644 index 6f1be1f..0000000 --- a/vendor/golang.org/x/sys/windows/svc/go12.c +++ /dev/null @@ -1,24 +0,0 @@ -// 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 windows -// +build !go1.3 - -// copied from pkg/runtime -typedef unsigned int uint32; -typedef unsigned long long int uint64; -#ifdef _64BIT -typedef uint64 uintptr; -#else -typedef uint32 uintptr; -#endif - -// from sys_386.s or sys_amd64.s -void ·servicemain(void); - -void -·getServiceMain(uintptr *r) -{ - *r = (uintptr)·servicemain; -} diff --git a/vendor/golang.org/x/sys/windows/svc/go12.go b/vendor/golang.org/x/sys/windows/svc/go12.go deleted file mode 100644 index cd8b913..0000000 --- a/vendor/golang.org/x/sys/windows/svc/go12.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 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 -// +build !go1.3 - -package svc - -// from go12.c -func getServiceMain(r *uintptr) diff --git a/vendor/golang.org/x/sys/windows/svc/go13.go b/vendor/golang.org/x/sys/windows/svc/go13.go deleted file mode 100644 index 9d7f3ce..0000000 --- a/vendor/golang.org/x/sys/windows/svc/go13.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 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 -// +build go1.3 - -package svc - -import "unsafe" - -const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const - -// Should be a built-in for unsafe.Pointer? -func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { - return unsafe.Pointer(uintptr(p) + x) -} - -// funcPC returns the entry PC of the function f. -// It assumes that f is a func value. Otherwise the behavior is undefined. -func funcPC(f interface{}) uintptr { - return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize)) -} - -// from sys_386.s and sys_amd64.s -func servicectlhandler(ctl uint32) uintptr -func servicemain(argc uint32, argv **uint16) - -func getServiceMain(r *uintptr) { - *r = funcPC(servicemain) -} diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/config.go b/vendor/golang.org/x/sys/windows/svc/mgr/config.go deleted file mode 100644 index 0a6edba..0000000 --- a/vendor/golang.org/x/sys/windows/svc/mgr/config.go +++ /dev/null @@ -1,139 +0,0 @@ -// 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 windows - -package mgr - -import ( - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -const ( - // Service start types. - StartManual = windows.SERVICE_DEMAND_START // the service must be started manually - StartAutomatic = windows.SERVICE_AUTO_START // the service will start by itself whenever the computer reboots - StartDisabled = windows.SERVICE_DISABLED // the service cannot be started - - // The severity of the error, and action taken, - // if this service fails to start. - ErrorCritical = windows.SERVICE_ERROR_CRITICAL - ErrorIgnore = windows.SERVICE_ERROR_IGNORE - ErrorNormal = windows.SERVICE_ERROR_NORMAL - ErrorSevere = windows.SERVICE_ERROR_SEVERE -) - -// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it. - -type Config struct { - ServiceType uint32 - StartType uint32 - ErrorControl uint32 - BinaryPathName string // fully qualified path to the service binary file, can also include arguments for an auto-start service - LoadOrderGroup string - TagId uint32 - Dependencies []string - ServiceStartName string // name of the account under which the service should run - DisplayName string - Password string - Description string -} - -func toString(p *uint16) string { - if p == nil { - return "" - } - return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:]) -} - -func toStringSlice(ps *uint16) []string { - if ps == nil { - return nil - } - r := make([]string, 0) - for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ { - if p[i] == 0 { - // empty string marks the end - if i <= from { - break - } - r = append(r, string(utf16.Decode(p[from:i]))) - from = i + 1 - } - } - return r -} - -// Config retrieves service s configuration paramteres. -func (s *Service) Config() (Config, error) { - var p *windows.QUERY_SERVICE_CONFIG - n := uint32(1024) - for { - b := make([]byte, n) - p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0])) - err := windows.QueryServiceConfig(s.Handle, p, n, &n) - if err == nil { - break - } - if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER { - return Config{}, err - } - if n <= uint32(len(b)) { - return Config{}, err - } - } - - var p2 *windows.SERVICE_DESCRIPTION - n = uint32(1024) - for { - b := make([]byte, n) - p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0])) - err := windows.QueryServiceConfig2(s.Handle, - windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n) - if err == nil { - break - } - if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER { - return Config{}, err - } - if n <= uint32(len(b)) { - return Config{}, err - } - } - - return Config{ - ServiceType: p.ServiceType, - StartType: p.StartType, - ErrorControl: p.ErrorControl, - BinaryPathName: toString(p.BinaryPathName), - LoadOrderGroup: toString(p.LoadOrderGroup), - TagId: p.TagId, - Dependencies: toStringSlice(p.Dependencies), - ServiceStartName: toString(p.ServiceStartName), - DisplayName: toString(p.DisplayName), - Description: toString(p2.Description), - }, nil -} - -func updateDescription(handle windows.Handle, desc string) error { - d := windows.SERVICE_DESCRIPTION{toPtr(desc)} - return windows.ChangeServiceConfig2(handle, - windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d))) -} - -// UpdateConfig updates service s configuration parameters. -func (s *Service) UpdateConfig(c Config) error { - err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType, - c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup), - nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), - toPtr(c.Password), toPtr(c.DisplayName)) - if err != nil { - return err - } - return updateDescription(s.Handle, c.Description) -} diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go b/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go deleted file mode 100644 index 76965b5..0000000 --- a/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go +++ /dev/null @@ -1,162 +0,0 @@ -// 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 windows - -// Package mgr can be used to manage Windows service programs. -// It can be used to install and remove them. It can also start, -// stop and pause them. The package can query / change current -// service state and config parameters. -// -package mgr - -import ( - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -// Mgr is used to manage Windows service. -type Mgr struct { - Handle windows.Handle -} - -// Connect establishes a connection to the service control manager. -func Connect() (*Mgr, error) { - return ConnectRemote("") -} - -// ConnectRemote establishes a connection to the -// service control manager on computer named host. -func ConnectRemote(host string) (*Mgr, error) { - var s *uint16 - if host != "" { - s = syscall.StringToUTF16Ptr(host) - } - h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS) - if err != nil { - return nil, err - } - return &Mgr{Handle: h}, nil -} - -// Disconnect closes connection to the service control manager m. -func (m *Mgr) Disconnect() error { - return windows.CloseServiceHandle(m.Handle) -} - -func toPtr(s string) *uint16 { - if len(s) == 0 { - return nil - } - return syscall.StringToUTF16Ptr(s) -} - -// toStringBlock terminates strings in ss with 0, and then -// concatenates them together. It also adds extra 0 at the end. -func toStringBlock(ss []string) *uint16 { - if len(ss) == 0 { - return nil - } - t := "" - for _, s := range ss { - if s != "" { - t += s + "\x00" - } - } - if t == "" { - return nil - } - t += "\x00" - return &utf16.Encode([]rune(t))[0] -} - -// CreateService installs new service name on the system. -// The service will be executed by running exepath binary. -// Use config c to specify service parameters. -// Any args will be passed as command-line arguments when -// the service is started; these arguments are distinct from -// the arguments passed to Service.Start or via the "Start -// parameters" field in the service's Properties dialog box. -func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) { - if c.StartType == 0 { - c.StartType = StartManual - } - if c.ErrorControl == 0 { - c.ErrorControl = ErrorNormal - } - if c.ServiceType == 0 { - c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS - } - s := syscall.EscapeArg(exepath) - for _, v := range args { - s += " " + syscall.EscapeArg(v) - } - h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName), - windows.SERVICE_ALL_ACCESS, c.ServiceType, - c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup), - nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password)) - if err != nil { - return nil, err - } - if c.Description != "" { - err = updateDescription(h, c.Description) - if err != nil { - return nil, err - } - } - return &Service{Name: name, Handle: h}, nil -} - -// OpenService retrieves access to service name, so it can -// be interrogated and controlled. -func (m *Mgr) OpenService(name string) (*Service, error) { - h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS) - if err != nil { - return nil, err - } - return &Service{Name: name, Handle: h}, nil -} - -// ListServices enumerates services in the specified -// service control manager database m. -// If the caller does not have the SERVICE_QUERY_STATUS -// access right to a service, the service is silently -// omitted from the list of services returned. -func (m *Mgr) ListServices() ([]string, error) { - var err error - var bytesNeeded, servicesReturned uint32 - var buf []byte - for { - var p *byte - if len(buf) > 0 { - p = &buf[0] - } - err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO, - windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL, - p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil) - if err == nil { - break - } - if err != syscall.ERROR_MORE_DATA { - return nil, err - } - if bytesNeeded <= uint32(len(buf)) { - return nil, err - } - buf = make([]byte, bytesNeeded) - } - if servicesReturned == 0 { - return nil, nil - } - services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned] - var names []string - for _, s := range services { - name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:]) - names = append(names, name) - } - return names, nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go b/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go deleted file mode 100644 index 1569a22..0000000 --- a/vendor/golang.org/x/sys/windows/svc/mgr/mgr_test.go +++ /dev/null @@ -1,169 +0,0 @@ -// 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 windows - -package mgr_test - -import ( - "os" - "path/filepath" - "sort" - "strings" - "syscall" - "testing" - "time" - - "golang.org/x/sys/windows/svc/mgr" -) - -func TestOpenLanManServer(t *testing.T) { - m, err := mgr.Connect() - if err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED { - t.Skip("Skipping test: we don't have rights to manage services.") - } - t.Fatalf("SCM connection failed: %s", err) - } - defer m.Disconnect() - - s, err := m.OpenService("LanmanServer") - if err != nil { - t.Fatalf("OpenService(lanmanserver) failed: %s", err) - } - defer s.Close() - - _, err = s.Config() - if err != nil { - t.Fatalf("Config failed: %s", err) - } -} - -func install(t *testing.T, m *mgr.Mgr, name, exepath string, c mgr.Config) { - // Sometimes it takes a while for the service to get - // removed after previous test run. - for i := 0; ; i++ { - s, err := m.OpenService(name) - if err != nil { - break - } - s.Close() - - if i > 10 { - t.Fatalf("service %s already exists", name) - } - time.Sleep(300 * time.Millisecond) - } - - s, err := m.CreateService(name, exepath, c) - if err != nil { - t.Fatalf("CreateService(%s) failed: %v", name, err) - } - defer s.Close() -} - -func depString(d []string) string { - if len(d) == 0 { - return "" - } - for i := range d { - d[i] = strings.ToLower(d[i]) - } - ss := sort.StringSlice(d) - ss.Sort() - return strings.Join([]string(ss), " ") -} - -func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config { - is, err := s.Config() - if err != nil { - t.Fatalf("Config failed: %s", err) - } - if should.DisplayName != is.DisplayName { - t.Fatalf("config mismatch: DisplayName is %q, but should have %q", is.DisplayName, should.DisplayName) - } - if should.StartType != is.StartType { - t.Fatalf("config mismatch: StartType is %v, but should have %v", is.StartType, should.StartType) - } - if should.Description != is.Description { - t.Fatalf("config mismatch: Description is %q, but should have %q", is.Description, should.Description) - } - if depString(should.Dependencies) != depString(is.Dependencies) { - t.Fatalf("config mismatch: Dependencies is %v, but should have %v", is.Dependencies, should.Dependencies) - } - return is -} - -func remove(t *testing.T, s *mgr.Service) { - err := s.Delete() - if err != nil { - t.Fatalf("Delete failed: %s", err) - } -} - -func TestMyService(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode - it modifies system services") - } - - const name = "myservice" - - m, err := mgr.Connect() - if err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED { - t.Skip("Skipping test: we don't have rights to manage services.") - } - t.Fatalf("SCM connection failed: %s", err) - } - defer m.Disconnect() - - c := mgr.Config{ - StartType: mgr.StartDisabled, - DisplayName: "my service", - Description: "my service is just a test", - Dependencies: []string{"LanmanServer", "W32Time"}, - } - - exename := os.Args[0] - exepath, err := filepath.Abs(exename) - if err != nil { - t.Fatalf("filepath.Abs(%s) failed: %s", exename, err) - } - - install(t, m, name, exepath, c) - - s, err := m.OpenService(name) - if err != nil { - t.Fatalf("service %s is not installed", name) - } - defer s.Close() - - c.BinaryPathName = exepath - c = testConfig(t, s, c) - - c.StartType = mgr.StartManual - err = s.UpdateConfig(c) - if err != nil { - t.Fatalf("UpdateConfig failed: %v", err) - } - - testConfig(t, s, c) - - svcnames, err := m.ListServices() - if err != nil { - t.Fatalf("ListServices failed: %v", err) - } - var myserviceIsInstalled bool - for _, sn := range svcnames { - if sn == name { - myserviceIsInstalled = true - break - } - } - if !myserviceIsInstalled { - t.Errorf("ListServices failed to find %q service", name) - } - - remove(t, s) -} diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/service.go b/vendor/golang.org/x/sys/windows/svc/mgr/service.go deleted file mode 100644 index fdc46af..0000000 --- a/vendor/golang.org/x/sys/windows/svc/mgr/service.go +++ /dev/null @@ -1,72 +0,0 @@ -// 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 windows - -package mgr - -import ( - "syscall" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/svc" -) - -// TODO(brainman): Use EnumDependentServices to enumerate dependent services. - -// Service is used to access Windows service. -type Service struct { - Name string - Handle windows.Handle -} - -// Delete marks service s for deletion from the service control manager database. -func (s *Service) Delete() error { - return windows.DeleteService(s.Handle) -} - -// Close relinquish access to the service s. -func (s *Service) Close() error { - return windows.CloseServiceHandle(s.Handle) -} - -// Start starts service s. -// args will be passed to svc.Handler.Execute. -func (s *Service) Start(args ...string) error { - var p **uint16 - if len(args) > 0 { - vs := make([]*uint16, len(args)) - for i := range vs { - vs[i] = syscall.StringToUTF16Ptr(args[i]) - } - p = &vs[0] - } - return windows.StartService(s.Handle, uint32(len(args)), p) -} - -// Control sends state change request c to the servce s. -func (s *Service) Control(c svc.Cmd) (svc.Status, error) { - var t windows.SERVICE_STATUS - err := windows.ControlService(s.Handle, uint32(c), &t) - if err != nil { - return svc.Status{}, err - } - return svc.Status{ - State: svc.State(t.CurrentState), - Accepts: svc.Accepted(t.ControlsAccepted), - }, nil -} - -// Query returns current status of service s. -func (s *Service) Query() (svc.Status, error) { - var t windows.SERVICE_STATUS - err := windows.QueryServiceStatus(s.Handle, &t) - if err != nil { - return svc.Status{}, err - } - return svc.Status{ - State: svc.State(t.CurrentState), - Accepts: svc.Accepted(t.ControlsAccepted), - }, nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/security.go b/vendor/golang.org/x/sys/windows/svc/security.go deleted file mode 100644 index 6fbc923..0000000 --- a/vendor/golang.org/x/sys/windows/svc/security.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 windows - -package svc - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -func allocSid(subAuth0 uint32) (*windows.SID, error) { - var sid *windows.SID - err := windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY, - 1, subAuth0, 0, 0, 0, 0, 0, 0, 0, &sid) - if err != nil { - return nil, err - } - return sid, nil -} - -// IsAnInteractiveSession determines if calling process is running interactively. -// It queries the process token for membership in the Interactive group. -// http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s -func IsAnInteractiveSession() (bool, error) { - interSid, err := allocSid(windows.SECURITY_INTERACTIVE_RID) - if err != nil { - return false, err - } - defer windows.FreeSid(interSid) - - serviceSid, err := allocSid(windows.SECURITY_SERVICE_RID) - if err != nil { - return false, err - } - defer windows.FreeSid(serviceSid) - - t, err := windows.OpenCurrentProcessToken() - if err != nil { - return false, err - } - defer t.Close() - - gs, err := t.GetTokenGroups() - if err != nil { - return false, err - } - p := unsafe.Pointer(&gs.Groups[0]) - groups := (*[2 << 20]windows.SIDAndAttributes)(p)[:gs.GroupCount] - for _, g := range groups { - if windows.EqualSid(g.Sid, interSid) { - return true, nil - } - if windows.EqualSid(g.Sid, serviceSid) { - return false, nil - } - } - return false, nil -} diff --git a/vendor/golang.org/x/sys/windows/svc/service.go b/vendor/golang.org/x/sys/windows/svc/service.go deleted file mode 100644 index 903cba3..0000000 --- a/vendor/golang.org/x/sys/windows/svc/service.go +++ /dev/null @@ -1,363 +0,0 @@ -// 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 windows - -// Package svc provides everything required to build Windows service. -// -package svc - -import ( - "errors" - "runtime" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -// State describes service execution state (Stopped, Running and so on). -type State uint32 - -const ( - Stopped = State(windows.SERVICE_STOPPED) - StartPending = State(windows.SERVICE_START_PENDING) - StopPending = State(windows.SERVICE_STOP_PENDING) - Running = State(windows.SERVICE_RUNNING) - ContinuePending = State(windows.SERVICE_CONTINUE_PENDING) - PausePending = State(windows.SERVICE_PAUSE_PENDING) - Paused = State(windows.SERVICE_PAUSED) -) - -// Cmd represents service state change request. It is sent to a service -// by the service manager, and should be actioned upon by the service. -type Cmd uint32 - -const ( - Stop = Cmd(windows.SERVICE_CONTROL_STOP) - Pause = Cmd(windows.SERVICE_CONTROL_PAUSE) - Continue = Cmd(windows.SERVICE_CONTROL_CONTINUE) - Interrogate = Cmd(windows.SERVICE_CONTROL_INTERROGATE) - Shutdown = Cmd(windows.SERVICE_CONTROL_SHUTDOWN) - ParamChange = Cmd(windows.SERVICE_CONTROL_PARAMCHANGE) - NetBindAdd = Cmd(windows.SERVICE_CONTROL_NETBINDADD) - NetBindRemove = Cmd(windows.SERVICE_CONTROL_NETBINDREMOVE) - NetBindEnable = Cmd(windows.SERVICE_CONTROL_NETBINDENABLE) - NetBindDisable = Cmd(windows.SERVICE_CONTROL_NETBINDDISABLE) - DeviceEvent = Cmd(windows.SERVICE_CONTROL_DEVICEEVENT) - HardwareProfileChange = Cmd(windows.SERVICE_CONTROL_HARDWAREPROFILECHANGE) - PowerEvent = Cmd(windows.SERVICE_CONTROL_POWEREVENT) - SessionChange = Cmd(windows.SERVICE_CONTROL_SESSIONCHANGE) -) - -// Accepted is used to describe commands accepted by the service. -// Note that Interrogate is always accepted. -type Accepted uint32 - -const ( - AcceptStop = Accepted(windows.SERVICE_ACCEPT_STOP) - AcceptShutdown = Accepted(windows.SERVICE_ACCEPT_SHUTDOWN) - AcceptPauseAndContinue = Accepted(windows.SERVICE_ACCEPT_PAUSE_CONTINUE) - AcceptParamChange = Accepted(windows.SERVICE_ACCEPT_PARAMCHANGE) - AcceptNetBindChange = Accepted(windows.SERVICE_ACCEPT_NETBINDCHANGE) - AcceptHardwareProfileChange = Accepted(windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE) - AcceptPowerEvent = Accepted(windows.SERVICE_ACCEPT_POWEREVENT) - AcceptSessionChange = Accepted(windows.SERVICE_ACCEPT_SESSIONCHANGE) -) - -// Status combines State and Accepted commands to fully describe running service. -type Status struct { - State State - Accepts Accepted - CheckPoint uint32 // used to report progress during a lengthy operation - WaitHint uint32 // estimated time required for a pending operation, in milliseconds -} - -// ChangeRequest is sent to the service Handler to request service status change. -type ChangeRequest struct { - Cmd Cmd - EventType uint32 - EventData uintptr - CurrentStatus Status -} - -// Handler is the interface that must be implemented to build Windows service. -type Handler interface { - - // Execute will be called by the package code at the start of - // the service, and the service will exit once Execute completes. - // Inside Execute you must read service change requests from r and - // act accordingly. You must keep service control manager up to date - // about state of your service by writing into s as required. - // args contains service name followed by argument strings passed - // to the service. - // You can provide service exit code in exitCode return parameter, - // with 0 being "no error". You can also indicate if exit code, - // if any, is service specific or not by using svcSpecificEC - // parameter. - Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32) -} - -var ( - // These are used by asm code. - goWaitsH uintptr - cWaitsH uintptr - ssHandle uintptr - sName *uint16 - sArgc uintptr - sArgv **uint16 - ctlHandlerExProc uintptr - cSetEvent uintptr - cWaitForSingleObject uintptr - cRegisterServiceCtrlHandlerExW uintptr -) - -func init() { - k := syscall.MustLoadDLL("kernel32.dll") - cSetEvent = k.MustFindProc("SetEvent").Addr() - cWaitForSingleObject = k.MustFindProc("WaitForSingleObject").Addr() - a := syscall.MustLoadDLL("advapi32.dll") - cRegisterServiceCtrlHandlerExW = a.MustFindProc("RegisterServiceCtrlHandlerExW").Addr() -} - -// The HandlerEx prototype also has a context pointer but since we don't use -// it at start-up time we don't have to pass it over either. -type ctlEvent struct { - cmd Cmd - eventType uint32 - eventData uintptr - errno uint32 -} - -// service provides access to windows service api. -type service struct { - name string - h windows.Handle - cWaits *event - goWaits *event - c chan ctlEvent - handler Handler -} - -func newService(name string, handler Handler) (*service, error) { - var s service - var err error - s.name = name - s.c = make(chan ctlEvent) - s.handler = handler - s.cWaits, err = newEvent() - if err != nil { - return nil, err - } - s.goWaits, err = newEvent() - if err != nil { - s.cWaits.Close() - return nil, err - } - return &s, nil -} - -func (s *service) close() error { - s.cWaits.Close() - s.goWaits.Close() - return nil -} - -type exitCode struct { - isSvcSpecific bool - errno uint32 -} - -func (s *service) updateStatus(status *Status, ec *exitCode) error { - if s.h == 0 { - return errors.New("updateStatus with no service status handle") - } - var t windows.SERVICE_STATUS - t.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS - t.CurrentState = uint32(status.State) - if status.Accepts&AcceptStop != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_STOP - } - if status.Accepts&AcceptShutdown != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_SHUTDOWN - } - if status.Accepts&AcceptPauseAndContinue != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_PAUSE_CONTINUE - } - if status.Accepts&AcceptParamChange != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_PARAMCHANGE - } - if status.Accepts&AcceptNetBindChange != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_NETBINDCHANGE - } - if status.Accepts&AcceptHardwareProfileChange != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE - } - if status.Accepts&AcceptPowerEvent != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_POWEREVENT - } - if status.Accepts&AcceptSessionChange != 0 { - t.ControlsAccepted |= windows.SERVICE_ACCEPT_SESSIONCHANGE - } - if ec.errno == 0 { - t.Win32ExitCode = windows.NO_ERROR - t.ServiceSpecificExitCode = windows.NO_ERROR - } else if ec.isSvcSpecific { - t.Win32ExitCode = uint32(windows.ERROR_SERVICE_SPECIFIC_ERROR) - t.ServiceSpecificExitCode = ec.errno - } else { - t.Win32ExitCode = ec.errno - t.ServiceSpecificExitCode = windows.NO_ERROR - } - t.CheckPoint = status.CheckPoint - t.WaitHint = status.WaitHint - return windows.SetServiceStatus(s.h, &t) -} - -const ( - sysErrSetServiceStatusFailed = uint32(syscall.APPLICATION_ERROR) + iota - sysErrNewThreadInCallback -) - -func (s *service) run() { - s.goWaits.Wait() - s.h = windows.Handle(ssHandle) - argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc] - args := make([]string, len(argv)) - for i, a := range argv { - args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:]) - } - - cmdsToHandler := make(chan ChangeRequest) - changesFromHandler := make(chan Status) - exitFromHandler := make(chan exitCode) - - go func() { - ss, errno := s.handler.Execute(args, cmdsToHandler, changesFromHandler) - exitFromHandler <- exitCode{ss, errno} - }() - - status := Status{State: Stopped} - ec := exitCode{isSvcSpecific: true, errno: 0} - var outch chan ChangeRequest - inch := s.c - var cmd Cmd - var evtype uint32 - var evdata uintptr -loop: - for { - select { - case r := <-inch: - if r.errno != 0 { - ec.errno = r.errno - break loop - } - inch = nil - outch = cmdsToHandler - cmd = r.cmd - evtype = r.eventType - evdata = r.eventData - case outch <- ChangeRequest{cmd, evtype, evdata, status}: - inch = s.c - outch = nil - case c := <-changesFromHandler: - err := s.updateStatus(&c, &ec) - if err != nil { - // best suitable error number - ec.errno = sysErrSetServiceStatusFailed - if err2, ok := err.(syscall.Errno); ok { - ec.errno = uint32(err2) - } - break loop - } - status = c - case ec = <-exitFromHandler: - break loop - } - } - - s.updateStatus(&Status{State: Stopped}, &ec) - s.cWaits.Set() -} - -func newCallback(fn interface{}) (cb uintptr, err error) { - defer func() { - r := recover() - if r == nil { - return - } - cb = 0 - switch v := r.(type) { - case string: - err = errors.New(v) - case error: - err = v - default: - err = errors.New("unexpected panic in syscall.NewCallback") - } - }() - return syscall.NewCallback(fn), nil -} - -// BUG(brainman): There is no mechanism to run multiple services -// inside one single executable. Perhaps, it can be overcome by -// using RegisterServiceCtrlHandlerEx Windows api. - -// Run executes service name by calling appropriate handler function. -func Run(name string, handler Handler) error { - runtime.LockOSThread() - - tid := windows.GetCurrentThreadId() - - s, err := newService(name, handler) - if err != nil { - return err - } - - ctlHandler := func(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr { - e := ctlEvent{cmd: Cmd(ctl), eventType: evtype, eventData: evdata} - // We assume that this callback function is running on - // the same thread as Run. Nowhere in MS documentation - // I could find statement to guarantee that. So putting - // check here to verify, otherwise things will go bad - // quickly, if ignored. - i := windows.GetCurrentThreadId() - if i != tid { - e.errno = sysErrNewThreadInCallback - } - s.c <- e - // Always return NO_ERROR (0) for now. - return 0 - } - - var svcmain uintptr - getServiceMain(&svcmain) - t := []windows.SERVICE_TABLE_ENTRY{ - {syscall.StringToUTF16Ptr(s.name), svcmain}, - {nil, 0}, - } - - goWaitsH = uintptr(s.goWaits.h) - cWaitsH = uintptr(s.cWaits.h) - sName = t[0].ServiceName - ctlHandlerExProc, err = newCallback(ctlHandler) - if err != nil { - return err - } - - go s.run() - - err = windows.StartServiceCtrlDispatcher(&t[0]) - if err != nil { - return err - } - return nil -} - -// StatusHandle returns service status handle. It is safe to call this function -// from inside the Handler.Execute because then it is guaranteed to be set. -// This code will have to change once multiple services are possible per process. -func StatusHandle() windows.Handle { - return windows.Handle(ssHandle) -} diff --git a/vendor/golang.org/x/sys/windows/svc/svc_test.go b/vendor/golang.org/x/sys/windows/svc/svc_test.go deleted file mode 100644 index da7ec66..0000000 --- a/vendor/golang.org/x/sys/windows/svc/svc_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// 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 windows - -package svc_test - -import ( - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "testing" - "time" - - "golang.org/x/sys/windows/svc" - "golang.org/x/sys/windows/svc/mgr" -) - -func getState(t *testing.T, s *mgr.Service) svc.State { - status, err := s.Query() - if err != nil { - t.Fatalf("Query(%s) failed: %s", s.Name, err) - } - return status.State -} - -func testState(t *testing.T, s *mgr.Service, want svc.State) { - have := getState(t, s) - if have != want { - t.Fatalf("%s state is=%d want=%d", s.Name, have, want) - } -} - -func waitState(t *testing.T, s *mgr.Service, want svc.State) { - for i := 0; ; i++ { - have := getState(t, s) - if have == want { - return - } - if i > 10 { - t.Fatalf("%s state is=%d, waiting timeout", s.Name, have) - } - time.Sleep(300 * time.Millisecond) - } -} - -func TestExample(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode - it modifies system services") - } - - const name = "myservice" - - m, err := mgr.Connect() - if err != nil { - t.Fatalf("SCM connection failed: %s", err) - } - defer m.Disconnect() - - dir, err := ioutil.TempDir("", "svc") - if err != nil { - t.Fatalf("failed to create temp directory: %v", err) - } - defer os.RemoveAll(dir) - - exepath := filepath.Join(dir, "a.exe") - o, err := exec.Command("go", "build", "-o", exepath, "golang.org/x/sys/windows/svc/example").CombinedOutput() - if err != nil { - t.Fatalf("failed to build service program: %v\n%v", err, string(o)) - } - - s, err := m.OpenService(name) - if err == nil { - err = s.Delete() - if err != nil { - s.Close() - t.Fatalf("Delete failed: %s", err) - } - s.Close() - } - s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: "my service"}, "is", "auto-started") - if err != nil { - t.Fatalf("CreateService(%s) failed: %v", name, err) - } - defer s.Close() - - testState(t, s, svc.Stopped) - err = s.Start("is", "manual-started") - if err != nil { - t.Fatalf("Start(%s) failed: %s", s.Name, err) - } - waitState(t, s, svc.Running) - time.Sleep(1 * time.Second) - - // testing deadlock from issues 4. - _, err = s.Control(svc.Interrogate) - if err != nil { - t.Fatalf("Control(%s) failed: %s", s.Name, err) - } - _, err = s.Control(svc.Interrogate) - if err != nil { - t.Fatalf("Control(%s) failed: %s", s.Name, err) - } - time.Sleep(1 * time.Second) - - _, err = s.Control(svc.Stop) - if err != nil { - t.Fatalf("Control(%s) failed: %s", s.Name, err) - } - waitState(t, s, svc.Stopped) - - err = s.Delete() - if err != nil { - t.Fatalf("Delete failed: %s", err) - } -} diff --git a/vendor/golang.org/x/sys/windows/svc/sys_386.s b/vendor/golang.org/x/sys/windows/svc/sys_386.s deleted file mode 100644 index 2c82a9d..0000000 --- a/vendor/golang.org/x/sys/windows/svc/sys_386.s +++ /dev/null @@ -1,68 +0,0 @@ -// 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 windows - -// func servicemain(argc uint32, argv **uint16) -TEXT ·servicemain(SB),7,$0 - MOVL argc+0(FP), AX - MOVL AX, ·sArgc(SB) - MOVL argv+4(FP), AX - MOVL AX, ·sArgv(SB) - - PUSHL BP - PUSHL BX - PUSHL SI - PUSHL DI - - SUBL $12, SP - - MOVL ·sName(SB), AX - MOVL AX, (SP) - MOVL $·servicectlhandler(SB), AX - MOVL AX, 4(SP) - MOVL $0, 8(SP) - MOVL ·cRegisterServiceCtrlHandlerExW(SB), AX - MOVL SP, BP - CALL AX - MOVL BP, SP - CMPL AX, $0 - JE exit - MOVL AX, ·ssHandle(SB) - - MOVL ·goWaitsH(SB), AX - MOVL AX, (SP) - MOVL ·cSetEvent(SB), AX - MOVL SP, BP - CALL AX - MOVL BP, SP - - MOVL ·cWaitsH(SB), AX - MOVL AX, (SP) - MOVL $-1, AX - MOVL AX, 4(SP) - MOVL ·cWaitForSingleObject(SB), AX - MOVL SP, BP - CALL AX - MOVL BP, SP - -exit: - ADDL $12, SP - - POPL DI - POPL SI - POPL BX - POPL BP - - MOVL 0(SP), CX - ADDL $12, SP - JMP CX - -// I do not know why, but this seems to be the only way to call -// ctlHandlerProc on Windows 7. - -// func servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr { -TEXT ·servicectlhandler(SB),7,$0 - MOVL ·ctlHandlerExProc(SB), CX - JMP CX diff --git a/vendor/golang.org/x/sys/windows/svc/sys_amd64.s b/vendor/golang.org/x/sys/windows/svc/sys_amd64.s deleted file mode 100644 index 06b4259..0000000 --- a/vendor/golang.org/x/sys/windows/svc/sys_amd64.s +++ /dev/null @@ -1,42 +0,0 @@ -// 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 windows - -// func servicemain(argc uint32, argv **uint16) -TEXT ·servicemain(SB),7,$0 - MOVL CX, ·sArgc(SB) - MOVL DX, ·sArgv(SB) - - SUBQ $32, SP // stack for the first 4 syscall params - - MOVQ ·sName(SB), CX - MOVQ $·servicectlhandler(SB), DX - // BUG(pastarmovj): Figure out a way to pass in context in R8. - MOVQ ·cRegisterServiceCtrlHandlerExW(SB), AX - CALL AX - CMPQ AX, $0 - JE exit - MOVQ AX, ·ssHandle(SB) - - MOVQ ·goWaitsH(SB), CX - MOVQ ·cSetEvent(SB), AX - CALL AX - - MOVQ ·cWaitsH(SB), CX - MOVQ $4294967295, DX - MOVQ ·cWaitForSingleObject(SB), AX - CALL AX - -exit: - ADDQ $32, SP - RET - -// I do not know why, but this seems to be the only way to call -// ctlHandlerProc on Windows 7. - -// func ·servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr { -TEXT ·servicectlhandler(SB),7,$0 - MOVQ ·ctlHandlerExProc(SB), AX - JMP AX diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go deleted file mode 100644 index b07bc23..0000000 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ /dev/null @@ -1,71 +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 windows - -// Package windows contains an interface to the low-level operating system -// primitives. OS details vary depending on the underlying system, and -// by default, godoc will display the OS-specific documentation for the current -// system. If you want godoc to display syscall documentation for another -// system, set $GOOS and $GOARCH to the desired system. For example, if -// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS -// to freebsd and $GOARCH to arm. -// The primary use of this package is inside other packages that provide a more -// portable interface to the system, such as "os", "time" and "net". Use -// those packages rather than this one if you can. -// For details of the functions and data types in this package consult -// the manuals for the appropriate operating system. -// These calls return err == nil to indicate success; otherwise -// err represents an operating system error describing the failure and -// holds a value of type syscall.Errno. -package windows // import "golang.org/x/sys/windows" - -import ( - "syscall" -) - -// ByteSliceFromString returns a NUL-terminated slice of bytes -// containing the text of s. If s contains a NUL byte at any -// location, it returns (nil, syscall.EINVAL). -func ByteSliceFromString(s string) ([]byte, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, syscall.EINVAL - } - } - a := make([]byte, len(s)+1) - copy(a, s) - return a, nil -} - -// BytePtrFromString returns a pointer to a NUL-terminated array of -// bytes containing the text of s. If s contains a NUL byte at any -// location, it returns (nil, syscall.EINVAL). -func BytePtrFromString(s string) (*byte, error) { - a, err := ByteSliceFromString(s) - if err != nil { - return nil, err - } - return &a[0], nil -} - -// Single-word zero for use when we need a valid pointer to 0 bytes. -// See mksyscall.pl. -var _zero uintptr - -func (ts *Timespec) Unix() (sec int64, nsec int64) { - return int64(ts.Sec), int64(ts.Nsec) -} - -func (tv *Timeval) Unix() (sec int64, nsec int64) { - return int64(tv.Sec), int64(tv.Usec) * 1000 -} - -func (ts *Timespec) Nano() int64 { - return int64(ts.Sec)*1e9 + int64(ts.Nsec) -} - -func (tv *Timeval) Nano() int64 { - return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 -} diff --git a/vendor/golang.org/x/sys/windows/syscall_test.go b/vendor/golang.org/x/sys/windows/syscall_test.go deleted file mode 100644 index d7009e4..0000000 --- a/vendor/golang.org/x/sys/windows/syscall_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2013 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 - -package windows_test - -import ( - "syscall" - "testing" - - "golang.org/x/sys/windows" -) - -func testSetGetenv(t *testing.T, key, value string) { - err := windows.Setenv(key, value) - if err != nil { - t.Fatalf("Setenv failed to set %q: %v", value, err) - } - newvalue, found := windows.Getenv(key) - if !found { - t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value) - } - if newvalue != value { - t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value) - } -} - -func TestEnv(t *testing.T) { - testSetGetenv(t, "TESTENV", "AVALUE") - // make sure TESTENV gets set to "", not deleted - testSetGetenv(t, "TESTENV", "") -} - -func TestGetProcAddressByOrdinal(t *testing.T) { - // Attempt calling shlwapi.dll:IsOS, resolving it by ordinal, as - // suggested in - // https://msdn.microsoft.com/en-us/library/windows/desktop/bb773795.aspx - h, err := windows.LoadLibrary("shlwapi.dll") - if err != nil { - t.Fatalf("Failed to load shlwapi.dll: %s", err) - } - procIsOS, err := windows.GetProcAddressByOrdinal(h, 437) - if err != nil { - t.Fatalf("Could not find shlwapi.dll:IsOS by ordinal: %s", err) - } - const OS_NT = 1 - r, _, _ := syscall.Syscall(procIsOS, 1, OS_NT, 0, 0) - if r == 0 { - t.Error("shlwapi.dll:IsOS(OS_NT) returned 0, expected non-zero value") - } -} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go deleted file mode 100644 index 1e9f4bb..0000000 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ /dev/null @@ -1,1153 +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. - -// Windows system calls. - -package windows - -import ( - errorspkg "errors" - "sync" - "syscall" - "unicode/utf16" - "unsafe" -) - -type Handle uintptr - -const ( - InvalidHandle = ^Handle(0) - - // Flags for DefineDosDevice. - DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 - DDD_NO_BROADCAST_SYSTEM = 0x00000008 - DDD_RAW_TARGET_PATH = 0x00000001 - DDD_REMOVE_DEFINITION = 0x00000002 - - // Return values for GetDriveType. - DRIVE_UNKNOWN = 0 - DRIVE_NO_ROOT_DIR = 1 - DRIVE_REMOVABLE = 2 - DRIVE_FIXED = 3 - DRIVE_REMOTE = 4 - DRIVE_CDROM = 5 - DRIVE_RAMDISK = 6 - - // File system flags from GetVolumeInformation and GetVolumeInformationByHandle. - FILE_CASE_SENSITIVE_SEARCH = 0x00000001 - FILE_CASE_PRESERVED_NAMES = 0x00000002 - FILE_FILE_COMPRESSION = 0x00000010 - FILE_DAX_VOLUME = 0x20000000 - FILE_NAMED_STREAMS = 0x00040000 - FILE_PERSISTENT_ACLS = 0x00000008 - FILE_READ_ONLY_VOLUME = 0x00080000 - FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 - FILE_SUPPORTS_ENCRYPTION = 0x00020000 - FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000 - FILE_SUPPORTS_HARD_LINKS = 0x00400000 - FILE_SUPPORTS_OBJECT_IDS = 0x00010000 - FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000 - FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 - FILE_SUPPORTS_SPARSE_FILES = 0x00000040 - FILE_SUPPORTS_TRANSACTIONS = 0x00200000 - FILE_SUPPORTS_USN_JOURNAL = 0x02000000 - FILE_UNICODE_ON_DISK = 0x00000004 - FILE_VOLUME_IS_COMPRESSED = 0x00008000 - FILE_VOLUME_QUOTAS = 0x00000020 -) - -// StringToUTF16 is deprecated. Use UTF16FromString instead. -// If s contains a NUL byte this function panics instead of -// returning an error. -func StringToUTF16(s string) []uint16 { - a, err := UTF16FromString(s) - if err != nil { - panic("windows: string with NUL passed to StringToUTF16") - } - return a -} - -// UTF16FromString returns the UTF-16 encoding of the UTF-8 string -// s, with a terminating NUL added. If s contains a NUL byte at any -// location, it returns (nil, syscall.EINVAL). -func UTF16FromString(s string) ([]uint16, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, syscall.EINVAL - } - } - return utf16.Encode([]rune(s + "\x00")), nil -} - -// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, -// with a terminating NUL removed. -func UTF16ToString(s []uint16) string { - for i, v := range s { - if v == 0 { - s = s[0:i] - break - } - } - return string(utf16.Decode(s)) -} - -// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. -// If s contains a NUL byte this function panics instead of -// returning an error. -func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } - -// UTF16PtrFromString returns pointer to the UTF-16 encoding of -// the UTF-8 string s, with a terminating NUL added. If s -// contains a NUL byte at any location, it returns (nil, syscall.EINVAL). -func UTF16PtrFromString(s string) (*uint16, error) { - a, err := UTF16FromString(s) - if err != nil { - return nil, err - } - return &a[0], nil -} - -func Getpagesize() int { return 4096 } - -// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. -// This is useful when interoperating with Windows code requiring callbacks. -func NewCallback(fn interface{}) uintptr { - return syscall.NewCallback(fn) -} - -// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. -// This is useful when interoperating with Windows code requiring callbacks. -func NewCallbackCDecl(fn interface{}) uintptr { - return syscall.NewCallbackCDecl(fn) -} - -// windows api calls - -//sys GetLastError() (lasterr error) -//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW -//sys LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW -//sys FreeLibrary(handle Handle) (err error) -//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) -//sys GetVersion() (ver uint32, err error) -//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW -//sys ExitProcess(exitcode uint32) -//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW -//sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) -//sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) -//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] -//sys CloseHandle(handle Handle) (err error) -//sys GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle] -//sys SetStdHandle(stdhandle uint32, handle Handle) (err error) -//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW -//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW -//sys FindClose(handle Handle) (err error) -//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) -//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW -//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW -//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW -//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW -//sys DeleteFile(path *uint16) (err error) = DeleteFileW -//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW -//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW -//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW -//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW -//sys SetEndOfFile(handle Handle) (err error) -//sys GetSystemTimeAsFileTime(time *Filetime) -//sys GetSystemTimePreciseAsFileTime(time *Filetime) -//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] -//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) -//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) -//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) -//sys CancelIo(s Handle) (err error) -//sys CancelIoEx(s Handle, o *Overlapped) (err error) -//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW -//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) -//sys TerminateProcess(handle Handle, exitcode uint32) (err error) -//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) -//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW -//sys GetCurrentProcess() (pseudoHandle Handle, err error) -//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) -//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) -//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] -//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW -//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) -//sys GetFileType(filehandle Handle) (n uint32, err error) -//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW -//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext -//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom -//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW -//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW -//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW -//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW -//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) -//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW -//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW -//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW -//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW -//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW -//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] -//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) -//sys FlushFileBuffers(handle Handle) (err error) -//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW -//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW -//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW -//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW -//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) -//sys UnmapViewOfFile(addr uintptr) (err error) -//sys FlushViewOfFile(addr uintptr, length uintptr) (err error) -//sys VirtualLock(addr uintptr, length uintptr) (err error) -//sys VirtualUnlock(addr uintptr, length uintptr) (err error) -//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc -//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree -//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect -//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile -//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW -//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW -//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore -//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore -//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore -//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore -//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain -//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain -//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext -//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext -//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy -//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW -//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey -//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW -//sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW -//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW -//sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId -//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode -//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode -//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo -//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW -//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW -//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot -//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW -//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW -//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) -// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. -//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW -//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW -//sys GetCurrentThreadId() (id uint32) -//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW -//sys CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW -//sys OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW -//sys SetEvent(event Handle) (err error) = kernel32.SetEvent -//sys ResetEvent(event Handle) (err error) = kernel32.ResetEvent -//sys PulseEvent(event Handle) (err error) = kernel32.PulseEvent - -// Volume Management Functions -//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW -//sys DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW -//sys FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW -//sys FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW -//sys FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW -//sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW -//sys FindVolumeClose(findVolume Handle) (err error) -//sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) -//sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW -//sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] -//sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW -//sys GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW -//sys GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW -//sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW -//sys GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW -//sys GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW -//sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW -//sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW -//sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW - -// syscall interface implementation for other packages - -// GetProcAddressByOrdinal retrieves the address of the exported -// function from module by ordinal. -func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) - proc = uintptr(r0) - if proc == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Exit(code int) { ExitProcess(uint32(code)) } - -func makeInheritSa() *SecurityAttributes { - var sa SecurityAttributes - sa.Length = uint32(unsafe.Sizeof(sa)) - sa.InheritHandle = 1 - return &sa -} - -func Open(path string, mode int, perm uint32) (fd Handle, err error) { - if len(path) == 0 { - return InvalidHandle, ERROR_FILE_NOT_FOUND - } - pathp, err := UTF16PtrFromString(path) - if err != nil { - return InvalidHandle, err - } - var access uint32 - switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { - case O_RDONLY: - access = GENERIC_READ - case O_WRONLY: - access = GENERIC_WRITE - case O_RDWR: - access = GENERIC_READ | GENERIC_WRITE - } - if mode&O_CREAT != 0 { - access |= GENERIC_WRITE - } - if mode&O_APPEND != 0 { - access &^= GENERIC_WRITE - access |= FILE_APPEND_DATA - } - sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) - var sa *SecurityAttributes - if mode&O_CLOEXEC == 0 { - sa = makeInheritSa() - } - var createmode uint32 - switch { - case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): - createmode = CREATE_NEW - case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): - createmode = CREATE_ALWAYS - case mode&O_CREAT == O_CREAT: - createmode = OPEN_ALWAYS - case mode&O_TRUNC == O_TRUNC: - createmode = TRUNCATE_EXISTING - default: - createmode = OPEN_EXISTING - } - h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0) - return h, e -} - -func Read(fd Handle, p []byte) (n int, err error) { - var done uint32 - e := ReadFile(fd, p, &done, nil) - if e != nil { - if e == ERROR_BROKEN_PIPE { - // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin - return 0, nil - } - return 0, e - } - if raceenabled { - if done > 0 { - raceWriteRange(unsafe.Pointer(&p[0]), int(done)) - } - raceAcquire(unsafe.Pointer(&ioSync)) - } - return int(done), nil -} - -func Write(fd Handle, p []byte) (n int, err error) { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(&ioSync)) - } - var done uint32 - e := WriteFile(fd, p, &done, nil) - if e != nil { - return 0, e - } - if raceenabled && done > 0 { - raceReadRange(unsafe.Pointer(&p[0]), int(done)) - } - return int(done), nil -} - -var ioSync int64 - -func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { - var w uint32 - switch whence { - case 0: - w = FILE_BEGIN - case 1: - w = FILE_CURRENT - case 2: - w = FILE_END - } - hi := int32(offset >> 32) - lo := int32(offset) - // use GetFileType to check pipe, pipe can't do seek - ft, _ := GetFileType(fd) - if ft == FILE_TYPE_PIPE { - return 0, syscall.EPIPE - } - rlo, e := SetFilePointer(fd, lo, &hi, w) - if e != nil { - return 0, e - } - return int64(hi)<<32 + int64(rlo), nil -} - -func Close(fd Handle) (err error) { - return CloseHandle(fd) -} - -var ( - Stdin = getStdHandle(STD_INPUT_HANDLE) - Stdout = getStdHandle(STD_OUTPUT_HANDLE) - Stderr = getStdHandle(STD_ERROR_HANDLE) -) - -func getStdHandle(stdhandle uint32) (fd Handle) { - r, _ := GetStdHandle(stdhandle) - CloseOnExec(r) - return r -} - -const ImplementsGetwd = true - -func Getwd() (wd string, err error) { - b := make([]uint16, 300) - n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) - if e != nil { - return "", e - } - return string(utf16.Decode(b[0:n])), nil -} - -func Chdir(path string) (err error) { - pathp, err := UTF16PtrFromString(path) - if err != nil { - return err - } - return SetCurrentDirectory(pathp) -} - -func Mkdir(path string, mode uint32) (err error) { - pathp, err := UTF16PtrFromString(path) - if err != nil { - return err - } - return CreateDirectory(pathp, nil) -} - -func Rmdir(path string) (err error) { - pathp, err := UTF16PtrFromString(path) - if err != nil { - return err - } - return RemoveDirectory(pathp) -} - -func Unlink(path string) (err error) { - pathp, err := UTF16PtrFromString(path) - if err != nil { - return err - } - return DeleteFile(pathp) -} - -func Rename(oldpath, newpath string) (err error) { - from, err := UTF16PtrFromString(oldpath) - if err != nil { - return err - } - to, err := UTF16PtrFromString(newpath) - if err != nil { - return err - } - return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) -} - -func ComputerName() (name string, err error) { - var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 - b := make([]uint16, n) - e := GetComputerName(&b[0], &n) - if e != nil { - return "", e - } - return string(utf16.Decode(b[0:n])), nil -} - -func Ftruncate(fd Handle, length int64) (err error) { - curoffset, e := Seek(fd, 0, 1) - if e != nil { - return e - } - defer Seek(fd, curoffset, 0) - _, e = Seek(fd, length, 0) - if e != nil { - return e - } - e = SetEndOfFile(fd) - if e != nil { - return e - } - return nil -} - -func Gettimeofday(tv *Timeval) (err error) { - var ft Filetime - GetSystemTimeAsFileTime(&ft) - *tv = NsecToTimeval(ft.Nanoseconds()) - return nil -} - -func Pipe(p []Handle) (err error) { - if len(p) != 2 { - return syscall.EINVAL - } - var r, w Handle - e := CreatePipe(&r, &w, makeInheritSa(), 0) - if e != nil { - return e - } - p[0] = r - p[1] = w - return nil -} - -func Utimes(path string, tv []Timeval) (err error) { - if len(tv) != 2 { - return syscall.EINVAL - } - pathp, e := UTF16PtrFromString(path) - if e != nil { - return e - } - h, e := CreateFile(pathp, - FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) - if e != nil { - return e - } - defer Close(h) - a := NsecToFiletime(tv[0].Nanoseconds()) - w := NsecToFiletime(tv[1].Nanoseconds()) - return SetFileTime(h, nil, &a, &w) -} - -func UtimesNano(path string, ts []Timespec) (err error) { - if len(ts) != 2 { - return syscall.EINVAL - } - pathp, e := UTF16PtrFromString(path) - if e != nil { - return e - } - h, e := CreateFile(pathp, - FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) - if e != nil { - return e - } - defer Close(h) - a := NsecToFiletime(TimespecToNsec(ts[0])) - w := NsecToFiletime(TimespecToNsec(ts[1])) - return SetFileTime(h, nil, &a, &w) -} - -func Fsync(fd Handle) (err error) { - return FlushFileBuffers(fd) -} - -func Chmod(path string, mode uint32) (err error) { - if mode == 0 { - return syscall.EINVAL - } - p, e := UTF16PtrFromString(path) - if e != nil { - return e - } - attrs, e := GetFileAttributes(p) - if e != nil { - return e - } - if mode&S_IWRITE != 0 { - attrs &^= FILE_ATTRIBUTE_READONLY - } else { - attrs |= FILE_ATTRIBUTE_READONLY - } - return SetFileAttributes(p, attrs) -} - -func LoadGetSystemTimePreciseAsFileTime() error { - return procGetSystemTimePreciseAsFileTime.Find() -} - -func LoadCancelIoEx() error { - return procCancelIoEx.Find() -} - -func LoadSetFileCompletionNotificationModes() error { - return procSetFileCompletionNotificationModes.Find() -} - -// net api calls - -const socket_error = uintptr(^uint32(0)) - -//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup -//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup -//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl -//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket -//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt -//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt -//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind -//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect -//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname -//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername -//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen -//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown -//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket -//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx -//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs -//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv -//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend -//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom -//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo -//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname -//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname -//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs -//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname -//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W -//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree -//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W -//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW -//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW -//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry -//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo -//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes -//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW -//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses -//sys GetACP() (acp uint32) = kernel32.GetACP -//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar - -// For testing: clients can set this flag to force -// creation of IPv6 sockets to return EAFNOSUPPORT. -var SocketDisableIPv6 bool - -type RawSockaddrInet4 struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]uint8 -} - -type RawSockaddrInet6 struct { - Family uint16 - Port uint16 - Flowinfo uint32 - Addr [16]byte /* in6_addr */ - Scope_id uint32 -} - -type RawSockaddr struct { - Family uint16 - Data [14]int8 -} - -type RawSockaddrAny struct { - Addr RawSockaddr - Pad [96]int8 -} - -type Sockaddr interface { - sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs -} - -type SockaddrInet4 struct { - Port int - Addr [4]byte - raw RawSockaddrInet4 -} - -func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { - if sa.Port < 0 || sa.Port > 0xFFFF { - return nil, 0, syscall.EINVAL - } - sa.raw.Family = AF_INET - p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) - p[0] = byte(sa.Port >> 8) - p[1] = byte(sa.Port) - for i := 0; i < len(sa.Addr); i++ { - sa.raw.Addr[i] = sa.Addr[i] - } - return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil -} - -type SockaddrInet6 struct { - Port int - ZoneId uint32 - Addr [16]byte - raw RawSockaddrInet6 -} - -func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { - if sa.Port < 0 || sa.Port > 0xFFFF { - return nil, 0, syscall.EINVAL - } - sa.raw.Family = AF_INET6 - p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) - p[0] = byte(sa.Port >> 8) - p[1] = byte(sa.Port) - sa.raw.Scope_id = sa.ZoneId - for i := 0; i < len(sa.Addr); i++ { - sa.raw.Addr[i] = sa.Addr[i] - } - return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil -} - -type SockaddrUnix struct { - Name string -} - -func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { - // TODO(brainman): implement SockaddrUnix.sockaddr() - return nil, 0, syscall.EWINDOWS -} - -func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { - switch rsa.Addr.Family { - case AF_UNIX: - return nil, syscall.EWINDOWS - - case AF_INET: - pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) - sa := new(SockaddrInet4) - p := (*[2]byte)(unsafe.Pointer(&pp.Port)) - sa.Port = int(p[0])<<8 + int(p[1]) - for i := 0; i < len(sa.Addr); i++ { - sa.Addr[i] = pp.Addr[i] - } - return sa, nil - - case AF_INET6: - pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) - sa := new(SockaddrInet6) - p := (*[2]byte)(unsafe.Pointer(&pp.Port)) - sa.Port = int(p[0])<<8 + int(p[1]) - sa.ZoneId = pp.Scope_id - for i := 0; i < len(sa.Addr); i++ { - sa.Addr[i] = pp.Addr[i] - } - return sa, nil - } - return nil, syscall.EAFNOSUPPORT -} - -func Socket(domain, typ, proto int) (fd Handle, err error) { - if domain == AF_INET6 && SocketDisableIPv6 { - return InvalidHandle, syscall.EAFNOSUPPORT - } - return socket(int32(domain), int32(typ), int32(proto)) -} - -func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { - v := int32(value) - return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) -} - -func Bind(fd Handle, sa Sockaddr) (err error) { - ptr, n, err := sa.sockaddr() - if err != nil { - return err - } - return bind(fd, ptr, n) -} - -func Connect(fd Handle, sa Sockaddr) (err error) { - ptr, n, err := sa.sockaddr() - if err != nil { - return err - } - return connect(fd, ptr, n) -} - -func Getsockname(fd Handle) (sa Sockaddr, err error) { - var rsa RawSockaddrAny - l := int32(unsafe.Sizeof(rsa)) - if err = getsockname(fd, &rsa, &l); err != nil { - return - } - return rsa.Sockaddr() -} - -func Getpeername(fd Handle) (sa Sockaddr, err error) { - var rsa RawSockaddrAny - l := int32(unsafe.Sizeof(rsa)) - if err = getpeername(fd, &rsa, &l); err != nil { - return - } - return rsa.Sockaddr() -} - -func Listen(s Handle, n int) (err error) { - return listen(s, int32(n)) -} - -func Shutdown(fd Handle, how int) (err error) { - return shutdown(fd, int32(how)) -} - -func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { - rsa, l, err := to.sockaddr() - if err != nil { - return err - } - return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) -} - -func LoadGetAddrInfo() error { - return procGetAddrInfoW.Find() -} - -var connectExFunc struct { - once sync.Once - addr uintptr - err error -} - -func LoadConnectEx() error { - connectExFunc.once.Do(func() { - var s Handle - s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) - if connectExFunc.err != nil { - return - } - defer CloseHandle(s) - var n uint32 - connectExFunc.err = WSAIoctl(s, - SIO_GET_EXTENSION_FUNCTION_POINTER, - (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), - uint32(unsafe.Sizeof(WSAID_CONNECTEX)), - (*byte)(unsafe.Pointer(&connectExFunc.addr)), - uint32(unsafe.Sizeof(connectExFunc.addr)), - &n, nil, 0) - }) - return connectExFunc.err -} - -func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { - err := LoadConnectEx() - if err != nil { - return errorspkg.New("failed to find ConnectEx: " + err.Error()) - } - ptr, n, err := sa.sockaddr() - if err != nil { - return err - } - return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) -} - -var sendRecvMsgFunc struct { - once sync.Once - sendAddr uintptr - recvAddr uintptr - err error -} - -func loadWSASendRecvMsg() error { - sendRecvMsgFunc.once.Do(func() { - var s Handle - s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) - if sendRecvMsgFunc.err != nil { - return - } - defer CloseHandle(s) - var n uint32 - sendRecvMsgFunc.err = WSAIoctl(s, - SIO_GET_EXTENSION_FUNCTION_POINTER, - (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), - uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), - (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), - uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), - &n, nil, 0) - if sendRecvMsgFunc.err != nil { - return - } - sendRecvMsgFunc.err = WSAIoctl(s, - SIO_GET_EXTENSION_FUNCTION_POINTER, - (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), - uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), - (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), - uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), - &n, nil, 0) - }) - return sendRecvMsgFunc.err -} - -func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error { - err := loadWSASendRecvMsg() - if err != nil { - return err - } - r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return err -} - -func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error { - err := loadWSASendRecvMsg() - if err != nil { - return err - } - r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return err -} - -// Invented structures to support what package os expects. -type Rusage struct { - CreationTime Filetime - ExitTime Filetime - KernelTime Filetime - UserTime Filetime -} - -type WaitStatus struct { - ExitCode uint32 -} - -func (w WaitStatus) Exited() bool { return true } - -func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } - -func (w WaitStatus) Signal() Signal { return -1 } - -func (w WaitStatus) CoreDump() bool { return false } - -func (w WaitStatus) Stopped() bool { return false } - -func (w WaitStatus) Continued() bool { return false } - -func (w WaitStatus) StopSignal() Signal { return -1 } - -func (w WaitStatus) Signaled() bool { return false } - -func (w WaitStatus) TrapCause() int { return -1 } - -// Timespec is an invented structure on Windows, but here for -// consistency with the corresponding package for other operating systems. -type Timespec struct { - Sec int64 - Nsec int64 -} - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return -} - -// TODO(brainman): fix all needed for net - -func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS } -func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { - return 0, nil, syscall.EWINDOWS -} -func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return syscall.EWINDOWS } -func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS } - -// The Linger struct is wrong but we only noticed after Go 1. -// sysLinger is the real system call structure. - -// BUG(brainman): The definition of Linger is not appropriate for direct use -// with Setsockopt and Getsockopt. -// Use SetsockoptLinger instead. - -type Linger struct { - Onoff int32 - Linger int32 -} - -type sysLinger struct { - Onoff uint16 - Linger uint16 -} - -type IPMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type IPv6Mreq struct { - Multiaddr [16]byte /* in6_addr */ - Interface uint32 -} - -func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS } - -func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { - sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} - return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) -} - -func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { - return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) -} -func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { - return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) -} -func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { - return syscall.EWINDOWS -} - -func Getpid() (pid int) { return int(getCurrentProcessId()) } - -func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { - // NOTE(rsc): The Win32finddata struct is wrong for the system call: - // the two paths are each one uint16 short. Use the correct struct, - // a win32finddata1, and then copy the results out. - // There is no loss of expressivity here, because the final - // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. - // For Go 1.1, we might avoid the allocation of win32finddata1 here - // by adding a final Bug [2]uint16 field to the struct and then - // adjusting the fields in the result directly. - var data1 win32finddata1 - handle, err = findFirstFile1(name, &data1) - if err == nil { - copyFindData(data, &data1) - } - return -} - -func FindNextFile(handle Handle, data *Win32finddata) (err error) { - var data1 win32finddata1 - err = findNextFile1(handle, &data1) - if err == nil { - copyFindData(data, &data1) - } - return -} - -func getProcessEntry(pid int) (*ProcessEntry32, error) { - snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) - if err != nil { - return nil, err - } - defer CloseHandle(snapshot) - var procEntry ProcessEntry32 - procEntry.Size = uint32(unsafe.Sizeof(procEntry)) - if err = Process32First(snapshot, &procEntry); err != nil { - return nil, err - } - for { - if procEntry.ProcessID == uint32(pid) { - return &procEntry, nil - } - err = Process32Next(snapshot, &procEntry) - if err != nil { - return nil, err - } - } -} - -func Getppid() (ppid int) { - pe, err := getProcessEntry(Getpid()) - if err != nil { - return -1 - } - return int(pe.ParentProcessID) -} - -// TODO(brainman): fix all needed for os -func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS } -func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS } -func Symlink(path, link string) (err error) { return syscall.EWINDOWS } - -func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS } -func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } -func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } -func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS } - -func Getuid() (uid int) { return -1 } -func Geteuid() (euid int) { return -1 } -func Getgid() (gid int) { return -1 } -func Getegid() (egid int) { return -1 } -func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } - -type Signal int - -func (s Signal) Signal() {} - -func (s Signal) String() string { - if 0 <= s && int(s) < len(signals) { - str := signals[s] - if str != "" { - return str - } - } - return "signal " + itoa(int(s)) -} - -func LoadCreateSymbolicLink() error { - return procCreateSymbolicLinkW.Find() -} - -// Readlink returns the destination of the named symbolic link. -func Readlink(path string, buf []byte) (n int, err error) { - fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) - if err != nil { - return -1, err - } - defer CloseHandle(fd) - - rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) - var bytesReturned uint32 - err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) - if err != nil { - return -1, err - } - - rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) - var s string - switch rdb.ReparseTag { - case IO_REPARSE_TAG_SYMLINK: - data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) - p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) - s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) - case IO_REPARSE_TAG_MOUNT_POINT: - data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) - p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) - s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) - default: - // the path is not a symlink or junction but another type of reparse - // point - return -1, syscall.ENOENT - } - n = copy(buf, []byte(s)) - - return n, nil -} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows_test.go b/vendor/golang.org/x/sys/windows/syscall_windows_test.go deleted file mode 100644 index 9c7133c..0000000 --- a/vendor/golang.org/x/sys/windows/syscall_windows_test.go +++ /dev/null @@ -1,107 +0,0 @@ -// 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 windows_test - -import ( - "io/ioutil" - "os" - "path/filepath" - "syscall" - "testing" - "unsafe" - - "golang.org/x/sys/windows" -) - -func TestWin32finddata(t *testing.T) { - dir, err := ioutil.TempDir("", "go-build") - if err != nil { - t.Fatalf("failed to create temp directory: %v", err) - } - defer os.RemoveAll(dir) - - path := filepath.Join(dir, "long_name.and_extension") - f, err := os.Create(path) - if err != nil { - t.Fatalf("failed to create %v: %v", path, err) - } - f.Close() - - type X struct { - fd windows.Win32finddata - got byte - pad [10]byte // to protect ourselves - - } - var want byte = 2 // it is unlikely to have this character in the filename - x := X{got: want} - - pathp, _ := windows.UTF16PtrFromString(path) - h, err := windows.FindFirstFile(pathp, &(x.fd)) - if err != nil { - t.Fatalf("FindFirstFile failed: %v", err) - } - err = windows.FindClose(h) - if err != nil { - t.Fatalf("FindClose failed: %v", err) - } - - if x.got != want { - t.Fatalf("memory corruption: want=%d got=%d", want, x.got) - } -} - -func TestFormatMessage(t *testing.T) { - dll := windows.MustLoadDLL("pdh.dll") - - pdhOpenQuery := func(datasrc *uint16, userdata uint32, query *windows.Handle) (errno uintptr) { - r0, _, _ := syscall.Syscall(dll.MustFindProc("PdhOpenQueryW").Addr(), 3, uintptr(unsafe.Pointer(datasrc)), uintptr(userdata), uintptr(unsafe.Pointer(query))) - return r0 - } - - pdhCloseQuery := func(query windows.Handle) (errno uintptr) { - r0, _, _ := syscall.Syscall(dll.MustFindProc("PdhCloseQuery").Addr(), 1, uintptr(query), 0, 0) - return r0 - } - - var q windows.Handle - name, err := windows.UTF16PtrFromString("no_such_source") - if err != nil { - t.Fatal(err) - } - errno := pdhOpenQuery(name, 0, &q) - if errno == 0 { - pdhCloseQuery(q) - t.Fatal("PdhOpenQuery succeeded, but expected to fail.") - } - - const flags uint32 = syscall.FORMAT_MESSAGE_FROM_HMODULE | syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY | syscall.FORMAT_MESSAGE_IGNORE_INSERTS - buf := make([]uint16, 300) - _, err = windows.FormatMessage(flags, uintptr(dll.Handle), uint32(errno), 0, buf, nil) - if err != nil { - t.Fatalf("FormatMessage for handle=%x and errno=%x failed: %v", dll.Handle, errno, err) - } -} - -func abort(funcname string, err error) { - panic(funcname + " failed: " + err.Error()) -} - -func ExampleLoadLibrary() { - h, err := windows.LoadLibrary("kernel32.dll") - if err != nil { - abort("LoadLibrary", err) - } - defer windows.FreeLibrary(h) - proc, err := windows.GetProcAddress(h, "GetVersion") - if err != nil { - abort("GetProcAddress", err) - } - r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0) - major := byte(r) - minor := uint8(r >> 8) - build := uint16(r >> 16) - print("windows version ", major, ".", minor, " (Build ", build, ")\n") -} diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go deleted file mode 100644 index 52c2037..0000000 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ /dev/null @@ -1,1333 +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 windows - -import "syscall" - -const ( - // Windows errors. - ERROR_FILE_NOT_FOUND syscall.Errno = 2 - ERROR_PATH_NOT_FOUND syscall.Errno = 3 - ERROR_ACCESS_DENIED syscall.Errno = 5 - ERROR_NO_MORE_FILES syscall.Errno = 18 - ERROR_HANDLE_EOF syscall.Errno = 38 - ERROR_NETNAME_DELETED syscall.Errno = 64 - ERROR_FILE_EXISTS syscall.Errno = 80 - ERROR_BROKEN_PIPE syscall.Errno = 109 - ERROR_BUFFER_OVERFLOW syscall.Errno = 111 - ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122 - ERROR_MOD_NOT_FOUND syscall.Errno = 126 - ERROR_PROC_NOT_FOUND syscall.Errno = 127 - ERROR_ALREADY_EXISTS syscall.Errno = 183 - ERROR_ENVVAR_NOT_FOUND syscall.Errno = 203 - ERROR_MORE_DATA syscall.Errno = 234 - ERROR_OPERATION_ABORTED syscall.Errno = 995 - ERROR_IO_PENDING syscall.Errno = 997 - ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066 - ERROR_NOT_FOUND syscall.Errno = 1168 - ERROR_PRIVILEGE_NOT_HELD syscall.Errno = 1314 - WSAEACCES syscall.Errno = 10013 - WSAEMSGSIZE syscall.Errno = 10040 - WSAECONNRESET syscall.Errno = 10054 -) - -const ( - // Invented values to support what package os expects. - O_RDONLY = 0x00000 - O_WRONLY = 0x00001 - O_RDWR = 0x00002 - O_CREAT = 0x00040 - O_EXCL = 0x00080 - O_NOCTTY = 0x00100 - O_TRUNC = 0x00200 - O_NONBLOCK = 0x00800 - O_APPEND = 0x00400 - O_SYNC = 0x01000 - O_ASYNC = 0x02000 - O_CLOEXEC = 0x80000 -) - -const ( - // More invented values for signals - SIGHUP = Signal(0x1) - SIGINT = Signal(0x2) - SIGQUIT = Signal(0x3) - SIGILL = Signal(0x4) - SIGTRAP = Signal(0x5) - SIGABRT = Signal(0x6) - SIGBUS = Signal(0x7) - SIGFPE = Signal(0x8) - SIGKILL = Signal(0x9) - SIGSEGV = Signal(0xb) - SIGPIPE = Signal(0xd) - SIGALRM = Signal(0xe) - SIGTERM = Signal(0xf) -) - -var signals = [...]string{ - 1: "hangup", - 2: "interrupt", - 3: "quit", - 4: "illegal instruction", - 5: "trace/breakpoint trap", - 6: "aborted", - 7: "bus error", - 8: "floating point exception", - 9: "killed", - 10: "user defined signal 1", - 11: "segmentation fault", - 12: "user defined signal 2", - 13: "broken pipe", - 14: "alarm clock", - 15: "terminated", -} - -const ( - GENERIC_READ = 0x80000000 - GENERIC_WRITE = 0x40000000 - GENERIC_EXECUTE = 0x20000000 - GENERIC_ALL = 0x10000000 - - FILE_LIST_DIRECTORY = 0x00000001 - FILE_APPEND_DATA = 0x00000004 - FILE_WRITE_ATTRIBUTES = 0x00000100 - - FILE_SHARE_READ = 0x00000001 - FILE_SHARE_WRITE = 0x00000002 - FILE_SHARE_DELETE = 0x00000004 - FILE_ATTRIBUTE_READONLY = 0x00000001 - FILE_ATTRIBUTE_HIDDEN = 0x00000002 - FILE_ATTRIBUTE_SYSTEM = 0x00000004 - FILE_ATTRIBUTE_DIRECTORY = 0x00000010 - FILE_ATTRIBUTE_ARCHIVE = 0x00000020 - FILE_ATTRIBUTE_NORMAL = 0x00000080 - FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 - - INVALID_FILE_ATTRIBUTES = 0xffffffff - - CREATE_NEW = 1 - CREATE_ALWAYS = 2 - OPEN_EXISTING = 3 - OPEN_ALWAYS = 4 - TRUNCATE_EXISTING = 5 - - FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 - FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 - FILE_FLAG_OVERLAPPED = 0x40000000 - - HANDLE_FLAG_INHERIT = 0x00000001 - STARTF_USESTDHANDLES = 0x00000100 - STARTF_USESHOWWINDOW = 0x00000001 - DUPLICATE_CLOSE_SOURCE = 0x00000001 - DUPLICATE_SAME_ACCESS = 0x00000002 - - STD_INPUT_HANDLE = -10 & (1<<32 - 1) - STD_OUTPUT_HANDLE = -11 & (1<<32 - 1) - STD_ERROR_HANDLE = -12 & (1<<32 - 1) - - FILE_BEGIN = 0 - FILE_CURRENT = 1 - FILE_END = 2 - - LANG_ENGLISH = 0x09 - SUBLANG_ENGLISH_US = 0x01 - - FORMAT_MESSAGE_ALLOCATE_BUFFER = 256 - FORMAT_MESSAGE_IGNORE_INSERTS = 512 - FORMAT_MESSAGE_FROM_STRING = 1024 - FORMAT_MESSAGE_FROM_HMODULE = 2048 - FORMAT_MESSAGE_FROM_SYSTEM = 4096 - FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 - FORMAT_MESSAGE_MAX_WIDTH_MASK = 255 - - MAX_PATH = 260 - MAX_LONG_PATH = 32768 - - MAX_COMPUTERNAME_LENGTH = 15 - - TIME_ZONE_ID_UNKNOWN = 0 - TIME_ZONE_ID_STANDARD = 1 - - TIME_ZONE_ID_DAYLIGHT = 2 - IGNORE = 0 - INFINITE = 0xffffffff - - WAIT_TIMEOUT = 258 - WAIT_ABANDONED = 0x00000080 - WAIT_OBJECT_0 = 0x00000000 - WAIT_FAILED = 0xFFFFFFFF - - PROCESS_TERMINATE = 1 - PROCESS_QUERY_INFORMATION = 0x00000400 - SYNCHRONIZE = 0x00100000 - - FILE_MAP_COPY = 0x01 - FILE_MAP_WRITE = 0x02 - FILE_MAP_READ = 0x04 - FILE_MAP_EXECUTE = 0x20 - - CTRL_C_EVENT = 0 - CTRL_BREAK_EVENT = 1 - - // Windows reserves errors >= 1<<29 for application use. - APPLICATION_ERROR = 1 << 29 -) - -const ( - // Process creation flags. - CREATE_BREAKAWAY_FROM_JOB = 0x01000000 - CREATE_DEFAULT_ERROR_MODE = 0x04000000 - CREATE_NEW_CONSOLE = 0x00000010 - CREATE_NEW_PROCESS_GROUP = 0x00000200 - CREATE_NO_WINDOW = 0x08000000 - CREATE_PROTECTED_PROCESS = 0x00040000 - CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 - CREATE_SEPARATE_WOW_VDM = 0x00000800 - CREATE_SHARED_WOW_VDM = 0x00001000 - CREATE_SUSPENDED = 0x00000004 - CREATE_UNICODE_ENVIRONMENT = 0x00000400 - DEBUG_ONLY_THIS_PROCESS = 0x00000002 - DEBUG_PROCESS = 0x00000001 - DETACHED_PROCESS = 0x00000008 - EXTENDED_STARTUPINFO_PRESENT = 0x00080000 - INHERIT_PARENT_AFFINITY = 0x00010000 -) - -const ( - // flags for CreateToolhelp32Snapshot - TH32CS_SNAPHEAPLIST = 0x01 - TH32CS_SNAPPROCESS = 0x02 - TH32CS_SNAPTHREAD = 0x04 - TH32CS_SNAPMODULE = 0x08 - TH32CS_SNAPMODULE32 = 0x10 - TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD - TH32CS_INHERIT = 0x80000000 -) - -const ( - // filters for ReadDirectoryChangesW - FILE_NOTIFY_CHANGE_FILE_NAME = 0x001 - FILE_NOTIFY_CHANGE_DIR_NAME = 0x002 - FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004 - FILE_NOTIFY_CHANGE_SIZE = 0x008 - FILE_NOTIFY_CHANGE_LAST_WRITE = 0x010 - FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020 - FILE_NOTIFY_CHANGE_CREATION = 0x040 - FILE_NOTIFY_CHANGE_SECURITY = 0x100 -) - -const ( - // do not reorder - FILE_ACTION_ADDED = iota + 1 - FILE_ACTION_REMOVED - FILE_ACTION_MODIFIED - FILE_ACTION_RENAMED_OLD_NAME - FILE_ACTION_RENAMED_NEW_NAME -) - -const ( - // wincrypt.h - PROV_RSA_FULL = 1 - PROV_RSA_SIG = 2 - PROV_DSS = 3 - PROV_FORTEZZA = 4 - PROV_MS_EXCHANGE = 5 - PROV_SSL = 6 - PROV_RSA_SCHANNEL = 12 - PROV_DSS_DH = 13 - PROV_EC_ECDSA_SIG = 14 - PROV_EC_ECNRA_SIG = 15 - PROV_EC_ECDSA_FULL = 16 - PROV_EC_ECNRA_FULL = 17 - PROV_DH_SCHANNEL = 18 - PROV_SPYRUS_LYNKS = 20 - PROV_RNG = 21 - PROV_INTEL_SEC = 22 - PROV_REPLACE_OWF = 23 - PROV_RSA_AES = 24 - CRYPT_VERIFYCONTEXT = 0xF0000000 - CRYPT_NEWKEYSET = 0x00000008 - CRYPT_DELETEKEYSET = 0x00000010 - CRYPT_MACHINE_KEYSET = 0x00000020 - CRYPT_SILENT = 0x00000040 - CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080 - - USAGE_MATCH_TYPE_AND = 0 - USAGE_MATCH_TYPE_OR = 1 - - X509_ASN_ENCODING = 0x00000001 - PKCS_7_ASN_ENCODING = 0x00010000 - - CERT_STORE_PROV_MEMORY = 2 - - CERT_STORE_ADD_ALWAYS = 4 - - CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004 - - CERT_TRUST_NO_ERROR = 0x00000000 - CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001 - CERT_TRUST_IS_REVOKED = 0x00000004 - CERT_TRUST_IS_NOT_SIGNATURE_VALID = 0x00000008 - CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 0x00000010 - CERT_TRUST_IS_UNTRUSTED_ROOT = 0x00000020 - CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 0x00000040 - CERT_TRUST_IS_CYCLIC = 0x00000080 - CERT_TRUST_INVALID_EXTENSION = 0x00000100 - CERT_TRUST_INVALID_POLICY_CONSTRAINTS = 0x00000200 - CERT_TRUST_INVALID_BASIC_CONSTRAINTS = 0x00000400 - CERT_TRUST_INVALID_NAME_CONSTRAINTS = 0x00000800 - CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000 - CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000 - CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000 - CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000 - CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000 - CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000 - CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000 - CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000 - - CERT_CHAIN_POLICY_BASE = 1 - CERT_CHAIN_POLICY_AUTHENTICODE = 2 - CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3 - CERT_CHAIN_POLICY_SSL = 4 - CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5 - CERT_CHAIN_POLICY_NT_AUTH = 6 - CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7 - CERT_CHAIN_POLICY_EV = 8 - - CERT_E_EXPIRED = 0x800B0101 - CERT_E_ROLE = 0x800B0103 - CERT_E_PURPOSE = 0x800B0106 - CERT_E_UNTRUSTEDROOT = 0x800B0109 - CERT_E_CN_NO_MATCH = 0x800B010F - - AUTHTYPE_CLIENT = 1 - AUTHTYPE_SERVER = 2 -) - -var ( - OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00") - OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00") - OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00") -) - -// Invented values to support what package os expects. -type Timeval struct { - Sec int32 - Usec int32 -} - -func (tv *Timeval) Nanoseconds() int64 { - return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3 -} - -func NsecToTimeval(nsec int64) (tv Timeval) { - tv.Sec = int32(nsec / 1e9) - tv.Usec = int32(nsec % 1e9 / 1e3) - return -} - -type SecurityAttributes struct { - Length uint32 - SecurityDescriptor uintptr - InheritHandle uint32 -} - -type Overlapped struct { - Internal uintptr - InternalHigh uintptr - Offset uint32 - OffsetHigh uint32 - HEvent Handle -} - -type FileNotifyInformation struct { - NextEntryOffset uint32 - Action uint32 - FileNameLength uint32 - FileName uint16 -} - -type Filetime struct { - LowDateTime uint32 - HighDateTime uint32 -} - -// Nanoseconds returns Filetime ft in nanoseconds -// since Epoch (00:00:00 UTC, January 1, 1970). -func (ft *Filetime) Nanoseconds() int64 { - // 100-nanosecond intervals since January 1, 1601 - nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) - // change starting time to the Epoch (00:00:00 UTC, January 1, 1970) - nsec -= 116444736000000000 - // convert into nanoseconds - nsec *= 100 - return nsec -} - -func NsecToFiletime(nsec int64) (ft Filetime) { - // convert into 100-nanosecond - nsec /= 100 - // change starting time to January 1, 1601 - nsec += 116444736000000000 - // split into high / low - ft.LowDateTime = uint32(nsec & 0xffffffff) - ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff) - return ft -} - -type Win32finddata struct { - FileAttributes uint32 - CreationTime Filetime - LastAccessTime Filetime - LastWriteTime Filetime - FileSizeHigh uint32 - FileSizeLow uint32 - Reserved0 uint32 - Reserved1 uint32 - FileName [MAX_PATH - 1]uint16 - AlternateFileName [13]uint16 -} - -// This is the actual system call structure. -// Win32finddata is what we committed to in Go 1. -type win32finddata1 struct { - FileAttributes uint32 - CreationTime Filetime - LastAccessTime Filetime - LastWriteTime Filetime - FileSizeHigh uint32 - FileSizeLow uint32 - Reserved0 uint32 - Reserved1 uint32 - FileName [MAX_PATH]uint16 - AlternateFileName [14]uint16 -} - -func copyFindData(dst *Win32finddata, src *win32finddata1) { - dst.FileAttributes = src.FileAttributes - dst.CreationTime = src.CreationTime - dst.LastAccessTime = src.LastAccessTime - dst.LastWriteTime = src.LastWriteTime - dst.FileSizeHigh = src.FileSizeHigh - dst.FileSizeLow = src.FileSizeLow - dst.Reserved0 = src.Reserved0 - dst.Reserved1 = src.Reserved1 - - // The src is 1 element bigger than dst, but it must be NUL. - copy(dst.FileName[:], src.FileName[:]) - copy(dst.AlternateFileName[:], src.AlternateFileName[:]) -} - -type ByHandleFileInformation struct { - FileAttributes uint32 - CreationTime Filetime - LastAccessTime Filetime - LastWriteTime Filetime - VolumeSerialNumber uint32 - FileSizeHigh uint32 - FileSizeLow uint32 - NumberOfLinks uint32 - FileIndexHigh uint32 - FileIndexLow uint32 -} - -const ( - GetFileExInfoStandard = 0 - GetFileExMaxInfoLevel = 1 -) - -type Win32FileAttributeData struct { - FileAttributes uint32 - CreationTime Filetime - LastAccessTime Filetime - LastWriteTime Filetime - FileSizeHigh uint32 - FileSizeLow uint32 -} - -// ShowWindow constants -const ( - // winuser.h - SW_HIDE = 0 - SW_NORMAL = 1 - SW_SHOWNORMAL = 1 - SW_SHOWMINIMIZED = 2 - SW_SHOWMAXIMIZED = 3 - SW_MAXIMIZE = 3 - SW_SHOWNOACTIVATE = 4 - SW_SHOW = 5 - SW_MINIMIZE = 6 - SW_SHOWMINNOACTIVE = 7 - SW_SHOWNA = 8 - SW_RESTORE = 9 - SW_SHOWDEFAULT = 10 - SW_FORCEMINIMIZE = 11 -) - -type StartupInfo struct { - Cb uint32 - _ *uint16 - Desktop *uint16 - Title *uint16 - X uint32 - Y uint32 - XSize uint32 - YSize uint32 - XCountChars uint32 - YCountChars uint32 - FillAttribute uint32 - Flags uint32 - ShowWindow uint16 - _ uint16 - _ *byte - StdInput Handle - StdOutput Handle - StdErr Handle -} - -type ProcessInformation struct { - Process Handle - Thread Handle - ProcessId uint32 - ThreadId uint32 -} - -type ProcessEntry32 struct { - Size uint32 - Usage uint32 - ProcessID uint32 - DefaultHeapID uintptr - ModuleID uint32 - Threads uint32 - ParentProcessID uint32 - PriClassBase int32 - Flags uint32 - ExeFile [MAX_PATH]uint16 -} - -type Systemtime struct { - Year uint16 - Month uint16 - DayOfWeek uint16 - Day uint16 - Hour uint16 - Minute uint16 - Second uint16 - Milliseconds uint16 -} - -type Timezoneinformation struct { - Bias int32 - StandardName [32]uint16 - StandardDate Systemtime - StandardBias int32 - DaylightName [32]uint16 - DaylightDate Systemtime - DaylightBias int32 -} - -// Socket related. - -const ( - AF_UNSPEC = 0 - AF_UNIX = 1 - AF_INET = 2 - AF_INET6 = 23 - AF_NETBIOS = 17 - - SOCK_STREAM = 1 - SOCK_DGRAM = 2 - SOCK_RAW = 3 - SOCK_SEQPACKET = 5 - - IPPROTO_IP = 0 - IPPROTO_IPV6 = 0x29 - IPPROTO_TCP = 6 - IPPROTO_UDP = 17 - - SOL_SOCKET = 0xffff - SO_REUSEADDR = 4 - SO_KEEPALIVE = 8 - SO_DONTROUTE = 16 - SO_BROADCAST = 32 - SO_LINGER = 128 - SO_RCVBUF = 0x1002 - SO_SNDBUF = 0x1001 - SO_UPDATE_ACCEPT_CONTEXT = 0x700b - SO_UPDATE_CONNECT_CONTEXT = 0x7010 - - IOC_OUT = 0x40000000 - IOC_IN = 0x80000000 - IOC_VENDOR = 0x18000000 - IOC_INOUT = IOC_IN | IOC_OUT - IOC_WS2 = 0x08000000 - SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 - SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 - SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 - - // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 - - IP_TOS = 0x3 - IP_TTL = 0x4 - IP_MULTICAST_IF = 0x9 - IP_MULTICAST_TTL = 0xa - IP_MULTICAST_LOOP = 0xb - IP_ADD_MEMBERSHIP = 0xc - IP_DROP_MEMBERSHIP = 0xd - - IPV6_V6ONLY = 0x1b - IPV6_UNICAST_HOPS = 0x4 - IPV6_MULTICAST_IF = 0x9 - IPV6_MULTICAST_HOPS = 0xa - IPV6_MULTICAST_LOOP = 0xb - IPV6_JOIN_GROUP = 0xc - IPV6_LEAVE_GROUP = 0xd - - MSG_OOB = 0x1 - MSG_PEEK = 0x2 - MSG_DONTROUTE = 0x4 - MSG_WAITALL = 0x8 - - MSG_TRUNC = 0x0100 - MSG_CTRUNC = 0x0200 - MSG_BCAST = 0x0400 - MSG_MCAST = 0x0800 - - SOMAXCONN = 0x7fffffff - - TCP_NODELAY = 1 - - SHUT_RD = 0 - SHUT_WR = 1 - SHUT_RDWR = 2 - - WSADESCRIPTION_LEN = 256 - WSASYS_STATUS_LEN = 128 -) - -type WSABuf struct { - Len uint32 - Buf *byte -} - -type WSAMsg struct { - Name *syscall.RawSockaddrAny - Namelen int32 - Buffers *WSABuf - BufferCount uint32 - Control WSABuf - Flags uint32 -} - -// Invented values to support what package os expects. -const ( - S_IFMT = 0x1f000 - S_IFIFO = 0x1000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFBLK = 0x6000 - S_IFREG = 0x8000 - S_IFLNK = 0xa000 - S_IFSOCK = 0xc000 - S_ISUID = 0x800 - S_ISGID = 0x400 - S_ISVTX = 0x200 - S_IRUSR = 0x100 - S_IWRITE = 0x80 - S_IWUSR = 0x80 - S_IXUSR = 0x40 -) - -const ( - FILE_TYPE_CHAR = 0x0002 - FILE_TYPE_DISK = 0x0001 - FILE_TYPE_PIPE = 0x0003 - FILE_TYPE_REMOTE = 0x8000 - FILE_TYPE_UNKNOWN = 0x0000 -) - -type Hostent struct { - Name *byte - Aliases **byte - AddrType uint16 - Length uint16 - AddrList **byte -} - -type Protoent struct { - Name *byte - Aliases **byte - Proto uint16 -} - -const ( - DNS_TYPE_A = 0x0001 - DNS_TYPE_NS = 0x0002 - DNS_TYPE_MD = 0x0003 - DNS_TYPE_MF = 0x0004 - DNS_TYPE_CNAME = 0x0005 - DNS_TYPE_SOA = 0x0006 - DNS_TYPE_MB = 0x0007 - DNS_TYPE_MG = 0x0008 - DNS_TYPE_MR = 0x0009 - DNS_TYPE_NULL = 0x000a - DNS_TYPE_WKS = 0x000b - DNS_TYPE_PTR = 0x000c - DNS_TYPE_HINFO = 0x000d - DNS_TYPE_MINFO = 0x000e - DNS_TYPE_MX = 0x000f - DNS_TYPE_TEXT = 0x0010 - DNS_TYPE_RP = 0x0011 - DNS_TYPE_AFSDB = 0x0012 - DNS_TYPE_X25 = 0x0013 - DNS_TYPE_ISDN = 0x0014 - DNS_TYPE_RT = 0x0015 - DNS_TYPE_NSAP = 0x0016 - DNS_TYPE_NSAPPTR = 0x0017 - DNS_TYPE_SIG = 0x0018 - DNS_TYPE_KEY = 0x0019 - DNS_TYPE_PX = 0x001a - DNS_TYPE_GPOS = 0x001b - DNS_TYPE_AAAA = 0x001c - DNS_TYPE_LOC = 0x001d - DNS_TYPE_NXT = 0x001e - DNS_TYPE_EID = 0x001f - DNS_TYPE_NIMLOC = 0x0020 - DNS_TYPE_SRV = 0x0021 - DNS_TYPE_ATMA = 0x0022 - DNS_TYPE_NAPTR = 0x0023 - DNS_TYPE_KX = 0x0024 - DNS_TYPE_CERT = 0x0025 - DNS_TYPE_A6 = 0x0026 - DNS_TYPE_DNAME = 0x0027 - DNS_TYPE_SINK = 0x0028 - DNS_TYPE_OPT = 0x0029 - DNS_TYPE_DS = 0x002B - DNS_TYPE_RRSIG = 0x002E - DNS_TYPE_NSEC = 0x002F - DNS_TYPE_DNSKEY = 0x0030 - DNS_TYPE_DHCID = 0x0031 - DNS_TYPE_UINFO = 0x0064 - DNS_TYPE_UID = 0x0065 - DNS_TYPE_GID = 0x0066 - DNS_TYPE_UNSPEC = 0x0067 - DNS_TYPE_ADDRS = 0x00f8 - DNS_TYPE_TKEY = 0x00f9 - DNS_TYPE_TSIG = 0x00fa - DNS_TYPE_IXFR = 0x00fb - DNS_TYPE_AXFR = 0x00fc - DNS_TYPE_MAILB = 0x00fd - DNS_TYPE_MAILA = 0x00fe - DNS_TYPE_ALL = 0x00ff - DNS_TYPE_ANY = 0x00ff - DNS_TYPE_WINS = 0xff01 - DNS_TYPE_WINSR = 0xff02 - DNS_TYPE_NBSTAT = 0xff01 -) - -const ( - DNS_INFO_NO_RECORDS = 0x251D -) - -const ( - // flags inside DNSRecord.Dw - DnsSectionQuestion = 0x0000 - DnsSectionAnswer = 0x0001 - DnsSectionAuthority = 0x0002 - DnsSectionAdditional = 0x0003 -) - -type DNSSRVData struct { - Target *uint16 - Priority uint16 - Weight uint16 - Port uint16 - Pad uint16 -} - -type DNSPTRData struct { - Host *uint16 -} - -type DNSMXData struct { - NameExchange *uint16 - Preference uint16 - Pad uint16 -} - -type DNSTXTData struct { - StringCount uint16 - StringArray [1]*uint16 -} - -type DNSRecord struct { - Next *DNSRecord - Name *uint16 - Type uint16 - Length uint16 - Dw uint32 - Ttl uint32 - Reserved uint32 - Data [40]byte -} - -const ( - TF_DISCONNECT = 1 - TF_REUSE_SOCKET = 2 - TF_WRITE_BEHIND = 4 - TF_USE_DEFAULT_WORKER = 0 - TF_USE_SYSTEM_THREAD = 16 - TF_USE_KERNEL_APC = 32 -) - -type TransmitFileBuffers struct { - Head uintptr - HeadLength uint32 - Tail uintptr - TailLength uint32 -} - -const ( - IFF_UP = 1 - IFF_BROADCAST = 2 - IFF_LOOPBACK = 4 - IFF_POINTTOPOINT = 8 - IFF_MULTICAST = 16 -) - -const SIO_GET_INTERFACE_LIST = 0x4004747F - -// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old. -// will be fixed to change variable type as suitable. - -type SockaddrGen [24]byte - -type InterfaceInfo struct { - Flags uint32 - Address SockaddrGen - BroadcastAddress SockaddrGen - Netmask SockaddrGen -} - -type IpAddressString struct { - String [16]byte -} - -type IpMaskString IpAddressString - -type IpAddrString struct { - Next *IpAddrString - IpAddress IpAddressString - IpMask IpMaskString - Context uint32 -} - -const MAX_ADAPTER_NAME_LENGTH = 256 -const MAX_ADAPTER_DESCRIPTION_LENGTH = 128 -const MAX_ADAPTER_ADDRESS_LENGTH = 8 - -type IpAdapterInfo struct { - Next *IpAdapterInfo - ComboIndex uint32 - AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]byte - Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte - AddressLength uint32 - Address [MAX_ADAPTER_ADDRESS_LENGTH]byte - Index uint32 - Type uint32 - DhcpEnabled uint32 - CurrentIpAddress *IpAddrString - IpAddressList IpAddrString - GatewayList IpAddrString - DhcpServer IpAddrString - HaveWins bool - PrimaryWinsServer IpAddrString - SecondaryWinsServer IpAddrString - LeaseObtained int64 - LeaseExpires int64 -} - -const MAXLEN_PHYSADDR = 8 -const MAX_INTERFACE_NAME_LEN = 256 -const MAXLEN_IFDESCR = 256 - -type MibIfRow struct { - Name [MAX_INTERFACE_NAME_LEN]uint16 - Index uint32 - Type uint32 - Mtu uint32 - Speed uint32 - PhysAddrLen uint32 - PhysAddr [MAXLEN_PHYSADDR]byte - AdminStatus uint32 - OperStatus uint32 - LastChange uint32 - InOctets uint32 - InUcastPkts uint32 - InNUcastPkts uint32 - InDiscards uint32 - InErrors uint32 - InUnknownProtos uint32 - OutOctets uint32 - OutUcastPkts uint32 - OutNUcastPkts uint32 - OutDiscards uint32 - OutErrors uint32 - OutQLen uint32 - DescrLen uint32 - Descr [MAXLEN_IFDESCR]byte -} - -type CertContext struct { - EncodingType uint32 - EncodedCert *byte - Length uint32 - CertInfo uintptr - Store Handle -} - -type CertChainContext struct { - Size uint32 - TrustStatus CertTrustStatus - ChainCount uint32 - Chains **CertSimpleChain - LowerQualityChainCount uint32 - LowerQualityChains **CertChainContext - HasRevocationFreshnessTime uint32 - RevocationFreshnessTime uint32 -} - -type CertSimpleChain struct { - Size uint32 - TrustStatus CertTrustStatus - NumElements uint32 - Elements **CertChainElement - TrustListInfo uintptr - HasRevocationFreshnessTime uint32 - RevocationFreshnessTime uint32 -} - -type CertChainElement struct { - Size uint32 - CertContext *CertContext - TrustStatus CertTrustStatus - RevocationInfo *CertRevocationInfo - IssuanceUsage *CertEnhKeyUsage - ApplicationUsage *CertEnhKeyUsage - ExtendedErrorInfo *uint16 -} - -type CertRevocationInfo struct { - Size uint32 - RevocationResult uint32 - RevocationOid *byte - OidSpecificInfo uintptr - HasFreshnessTime uint32 - FreshnessTime uint32 - CrlInfo uintptr // *CertRevocationCrlInfo -} - -type CertTrustStatus struct { - ErrorStatus uint32 - InfoStatus uint32 -} - -type CertUsageMatch struct { - Type uint32 - Usage CertEnhKeyUsage -} - -type CertEnhKeyUsage struct { - Length uint32 - UsageIdentifiers **byte -} - -type CertChainPara struct { - Size uint32 - RequestedUsage CertUsageMatch - RequstedIssuancePolicy CertUsageMatch - URLRetrievalTimeout uint32 - CheckRevocationFreshnessTime uint32 - RevocationFreshnessTime uint32 - CacheResync *Filetime -} - -type CertChainPolicyPara struct { - Size uint32 - Flags uint32 - ExtraPolicyPara uintptr -} - -type SSLExtraCertChainPolicyPara struct { - Size uint32 - AuthType uint32 - Checks uint32 - ServerName *uint16 -} - -type CertChainPolicyStatus struct { - Size uint32 - Error uint32 - ChainIndex uint32 - ElementIndex uint32 - ExtraPolicyStatus uintptr -} - -const ( - // do not reorder - HKEY_CLASSES_ROOT = 0x80000000 + iota - HKEY_CURRENT_USER - HKEY_LOCAL_MACHINE - HKEY_USERS - HKEY_PERFORMANCE_DATA - HKEY_CURRENT_CONFIG - HKEY_DYN_DATA - - KEY_QUERY_VALUE = 1 - KEY_SET_VALUE = 2 - KEY_CREATE_SUB_KEY = 4 - KEY_ENUMERATE_SUB_KEYS = 8 - KEY_NOTIFY = 16 - KEY_CREATE_LINK = 32 - KEY_WRITE = 0x20006 - KEY_EXECUTE = 0x20019 - KEY_READ = 0x20019 - KEY_WOW64_64KEY = 0x0100 - KEY_WOW64_32KEY = 0x0200 - KEY_ALL_ACCESS = 0xf003f -) - -const ( - // do not reorder - REG_NONE = iota - REG_SZ - REG_EXPAND_SZ - REG_BINARY - REG_DWORD_LITTLE_ENDIAN - REG_DWORD_BIG_ENDIAN - REG_LINK - REG_MULTI_SZ - REG_RESOURCE_LIST - REG_FULL_RESOURCE_DESCRIPTOR - REG_RESOURCE_REQUIREMENTS_LIST - REG_QWORD_LITTLE_ENDIAN - REG_DWORD = REG_DWORD_LITTLE_ENDIAN - REG_QWORD = REG_QWORD_LITTLE_ENDIAN -) - -type AddrinfoW struct { - Flags int32 - Family int32 - Socktype int32 - Protocol int32 - Addrlen uintptr - Canonname *uint16 - Addr uintptr - Next *AddrinfoW -} - -const ( - AI_PASSIVE = 1 - AI_CANONNAME = 2 - AI_NUMERICHOST = 4 -) - -type GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]byte -} - -var WSAID_CONNECTEX = GUID{ - 0x25a207b9, - 0xddf3, - 0x4660, - [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}, -} - -var WSAID_WSASENDMSG = GUID{ - 0xa441e712, - 0x754f, - 0x43ca, - [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, -} - -var WSAID_WSARECVMSG = GUID{ - 0xf689d7c8, - 0x6f1f, - 0x436b, - [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, -} - -const ( - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 - FILE_SKIP_SET_EVENT_ON_HANDLE = 2 -) - -const ( - WSAPROTOCOL_LEN = 255 - MAX_PROTOCOL_CHAIN = 7 - BASE_PROTOCOL = 1 - LAYERED_PROTOCOL = 0 - - XP1_CONNECTIONLESS = 0x00000001 - XP1_GUARANTEED_DELIVERY = 0x00000002 - XP1_GUARANTEED_ORDER = 0x00000004 - XP1_MESSAGE_ORIENTED = 0x00000008 - XP1_PSEUDO_STREAM = 0x00000010 - XP1_GRACEFUL_CLOSE = 0x00000020 - XP1_EXPEDITED_DATA = 0x00000040 - XP1_CONNECT_DATA = 0x00000080 - XP1_DISCONNECT_DATA = 0x00000100 - XP1_SUPPORT_BROADCAST = 0x00000200 - XP1_SUPPORT_MULTIPOINT = 0x00000400 - XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800 - XP1_MULTIPOINT_DATA_PLANE = 0x00001000 - XP1_QOS_SUPPORTED = 0x00002000 - XP1_UNI_SEND = 0x00008000 - XP1_UNI_RECV = 0x00010000 - XP1_IFS_HANDLES = 0x00020000 - XP1_PARTIAL_MESSAGE = 0x00040000 - XP1_SAN_SUPPORT_SDP = 0x00080000 - - PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001 - PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002 - PFL_HIDDEN = 0x00000004 - PFL_MATCHES_PROTOCOL_ZERO = 0x00000008 - PFL_NETWORKDIRECT_PROVIDER = 0x00000010 -) - -type WSAProtocolInfo struct { - ServiceFlags1 uint32 - ServiceFlags2 uint32 - ServiceFlags3 uint32 - ServiceFlags4 uint32 - ProviderFlags uint32 - ProviderId GUID - CatalogEntryId uint32 - ProtocolChain WSAProtocolChain - Version int32 - AddressFamily int32 - MaxSockAddr int32 - MinSockAddr int32 - SocketType int32 - Protocol int32 - ProtocolMaxOffset int32 - NetworkByteOrder int32 - SecurityScheme int32 - MessageSize uint32 - ProviderReserved uint32 - ProtocolName [WSAPROTOCOL_LEN + 1]uint16 -} - -type WSAProtocolChain struct { - ChainLen int32 - ChainEntries [MAX_PROTOCOL_CHAIN]uint32 -} - -type TCPKeepalive struct { - OnOff uint32 - Time uint32 - Interval uint32 -} - -type symbolicLinkReparseBuffer struct { - SubstituteNameOffset uint16 - SubstituteNameLength uint16 - PrintNameOffset uint16 - PrintNameLength uint16 - Flags uint32 - PathBuffer [1]uint16 -} - -type mountPointReparseBuffer struct { - SubstituteNameOffset uint16 - SubstituteNameLength uint16 - PrintNameOffset uint16 - PrintNameLength uint16 - PathBuffer [1]uint16 -} - -type reparseDataBuffer struct { - ReparseTag uint32 - ReparseDataLength uint16 - Reserved uint16 - - // GenericReparseBuffer - reparseBuffer byte -} - -const ( - FSCTL_GET_REPARSE_POINT = 0x900A8 - MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 - IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 - IO_REPARSE_TAG_SYMLINK = 0xA000000C - SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 -) - -const ( - ComputerNameNetBIOS = 0 - ComputerNameDnsHostname = 1 - ComputerNameDnsDomain = 2 - ComputerNameDnsFullyQualified = 3 - ComputerNamePhysicalNetBIOS = 4 - ComputerNamePhysicalDnsHostname = 5 - ComputerNamePhysicalDnsDomain = 6 - ComputerNamePhysicalDnsFullyQualified = 7 - ComputerNameMax = 8 -) - -const ( - MOVEFILE_REPLACE_EXISTING = 0x1 - MOVEFILE_COPY_ALLOWED = 0x2 - MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 - MOVEFILE_WRITE_THROUGH = 0x8 - MOVEFILE_CREATE_HARDLINK = 0x10 - MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 -) - -const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 - -const ( - IF_TYPE_OTHER = 1 - IF_TYPE_ETHERNET_CSMACD = 6 - IF_TYPE_ISO88025_TOKENRING = 9 - IF_TYPE_PPP = 23 - IF_TYPE_SOFTWARE_LOOPBACK = 24 - IF_TYPE_ATM = 37 - IF_TYPE_IEEE80211 = 71 - IF_TYPE_TUNNEL = 131 - IF_TYPE_IEEE1394 = 144 -) - -type SocketAddress struct { - Sockaddr *syscall.RawSockaddrAny - SockaddrLength int32 -} - -type IpAdapterUnicastAddress struct { - Length uint32 - Flags uint32 - Next *IpAdapterUnicastAddress - Address SocketAddress - PrefixOrigin int32 - SuffixOrigin int32 - DadState int32 - ValidLifetime uint32 - PreferredLifetime uint32 - LeaseLifetime uint32 - OnLinkPrefixLength uint8 -} - -type IpAdapterAnycastAddress struct { - Length uint32 - Flags uint32 - Next *IpAdapterAnycastAddress - Address SocketAddress -} - -type IpAdapterMulticastAddress struct { - Length uint32 - Flags uint32 - Next *IpAdapterMulticastAddress - Address SocketAddress -} - -type IpAdapterDnsServerAdapter struct { - Length uint32 - Reserved uint32 - Next *IpAdapterDnsServerAdapter - Address SocketAddress -} - -type IpAdapterPrefix struct { - Length uint32 - Flags uint32 - Next *IpAdapterPrefix - Address SocketAddress - PrefixLength uint32 -} - -type IpAdapterAddresses struct { - Length uint32 - IfIndex uint32 - Next *IpAdapterAddresses - AdapterName *byte - FirstUnicastAddress *IpAdapterUnicastAddress - FirstAnycastAddress *IpAdapterAnycastAddress - FirstMulticastAddress *IpAdapterMulticastAddress - FirstDnsServerAddress *IpAdapterDnsServerAdapter - DnsSuffix *uint16 - Description *uint16 - FriendlyName *uint16 - PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte - PhysicalAddressLength uint32 - Flags uint32 - Mtu uint32 - IfType uint32 - OperStatus uint32 - Ipv6IfIndex uint32 - ZoneIndices [16]uint32 - FirstPrefix *IpAdapterPrefix - /* more fields might be present here. */ -} - -const ( - IfOperStatusUp = 1 - IfOperStatusDown = 2 - IfOperStatusTesting = 3 - IfOperStatusUnknown = 4 - IfOperStatusDormant = 5 - IfOperStatusNotPresent = 6 - IfOperStatusLowerLayerDown = 7 -) - -// Console related constants used for the mode parameter to SetConsoleMode. See -// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. - -const ( - ENABLE_PROCESSED_INPUT = 0x1 - ENABLE_LINE_INPUT = 0x2 - ENABLE_ECHO_INPUT = 0x4 - ENABLE_WINDOW_INPUT = 0x8 - ENABLE_MOUSE_INPUT = 0x10 - ENABLE_INSERT_MODE = 0x20 - ENABLE_QUICK_EDIT_MODE = 0x40 - ENABLE_EXTENDED_FLAGS = 0x80 - ENABLE_AUTO_POSITION = 0x100 - ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200 - - ENABLE_PROCESSED_OUTPUT = 0x1 - ENABLE_WRAP_AT_EOL_OUTPUT = 0x2 - ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 - DISABLE_NEWLINE_AUTO_RETURN = 0x8 - ENABLE_LVB_GRID_WORLDWIDE = 0x10 -) - -type Coord struct { - X int16 - Y int16 -} - -type SmallRect struct { - Left int16 - Top int16 - Right int16 - Bottom int16 -} - -// Used with GetConsoleScreenBuffer to retreive information about a console -// screen buffer. See -// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str -// for details. - -type ConsoleScreenBufferInfo struct { - Size Coord - CursorPosition Coord - Attributes uint16 - Window SmallRect - MaximumWindowSize Coord -} diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go deleted file mode 100644 index fe0ddd0..0000000 --- a/vendor/golang.org/x/sys/windows/types_windows_386.go +++ /dev/null @@ -1,22 +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 windows - -type WSAData struct { - Version uint16 - HighVersion uint16 - Description [WSADESCRIPTION_LEN + 1]byte - SystemStatus [WSASYS_STATUS_LEN + 1]byte - MaxSockets uint16 - MaxUdpDg uint16 - VendorInfo *byte -} - -type Servent struct { - Name *byte - Aliases **byte - Port uint16 - Proto *byte -} diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go deleted file mode 100644 index 7e154c2..0000000 --- a/vendor/golang.org/x/sys/windows/types_windows_amd64.go +++ /dev/null @@ -1,22 +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 windows - -type WSAData struct { - Version uint16 - HighVersion uint16 - MaxSockets uint16 - MaxUdpDg uint16 - VendorInfo *byte - Description [WSADESCRIPTION_LEN + 1]byte - SystemStatus [WSASYS_STATUS_LEN + 1]byte -} - -type Servent struct { - Name *byte - Aliases **byte - Proto *byte - Port uint16 -} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go deleted file mode 100644 index c7b3b15..0000000 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ /dev/null @@ -1,2687 +0,0 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT - -package windows - -import ( - "syscall" - "unsafe" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modadvapi32 = NewLazySystemDLL("advapi32.dll") - modkernel32 = NewLazySystemDLL("kernel32.dll") - modshell32 = NewLazySystemDLL("shell32.dll") - modmswsock = NewLazySystemDLL("mswsock.dll") - modcrypt32 = NewLazySystemDLL("crypt32.dll") - modws2_32 = NewLazySystemDLL("ws2_32.dll") - moddnsapi = NewLazySystemDLL("dnsapi.dll") - modiphlpapi = NewLazySystemDLL("iphlpapi.dll") - modsecur32 = NewLazySystemDLL("secur32.dll") - modnetapi32 = NewLazySystemDLL("netapi32.dll") - moduserenv = NewLazySystemDLL("userenv.dll") - - procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") - procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") - procReportEventW = modadvapi32.NewProc("ReportEventW") - procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") - procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") - procCreateServiceW = modadvapi32.NewProc("CreateServiceW") - procOpenServiceW = modadvapi32.NewProc("OpenServiceW") - procDeleteService = modadvapi32.NewProc("DeleteService") - procStartServiceW = modadvapi32.NewProc("StartServiceW") - procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") - procControlService = modadvapi32.NewProc("ControlService") - procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") - procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") - procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") - procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") - procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") - procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") - procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") - procGetLastError = modkernel32.NewProc("GetLastError") - procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") - procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") - procFreeLibrary = modkernel32.NewProc("FreeLibrary") - procGetProcAddress = modkernel32.NewProc("GetProcAddress") - procGetVersion = modkernel32.NewProc("GetVersion") - procFormatMessageW = modkernel32.NewProc("FormatMessageW") - procExitProcess = modkernel32.NewProc("ExitProcess") - procCreateFileW = modkernel32.NewProc("CreateFileW") - procReadFile = modkernel32.NewProc("ReadFile") - procWriteFile = modkernel32.NewProc("WriteFile") - procSetFilePointer = modkernel32.NewProc("SetFilePointer") - procCloseHandle = modkernel32.NewProc("CloseHandle") - procGetStdHandle = modkernel32.NewProc("GetStdHandle") - procSetStdHandle = modkernel32.NewProc("SetStdHandle") - procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") - procFindNextFileW = modkernel32.NewProc("FindNextFileW") - procFindClose = modkernel32.NewProc("FindClose") - procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") - procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") - procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") - procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") - procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") - procDeleteFileW = modkernel32.NewProc("DeleteFileW") - procMoveFileW = modkernel32.NewProc("MoveFileW") - procMoveFileExW = modkernel32.NewProc("MoveFileExW") - procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") - procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") - procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") - procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") - procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") - procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") - procCancelIo = modkernel32.NewProc("CancelIo") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procCreateProcessW = modkernel32.NewProc("CreateProcessW") - procOpenProcess = modkernel32.NewProc("OpenProcess") - procTerminateProcess = modkernel32.NewProc("TerminateProcess") - procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") - procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") - procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") - procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") - procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") - procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") - procGetTempPathW = modkernel32.NewProc("GetTempPathW") - procCreatePipe = modkernel32.NewProc("CreatePipe") - procGetFileType = modkernel32.NewProc("GetFileType") - procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") - procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") - procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") - procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") - procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") - procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") - procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") - procSetFileTime = modkernel32.NewProc("SetFileTime") - procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") - procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") - procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") - procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") - procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") - procLocalFree = modkernel32.NewProc("LocalFree") - procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") - procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") - procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") - procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") - procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") - procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") - procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") - procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") - procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") - procVirtualLock = modkernel32.NewProc("VirtualLock") - procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") - procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") - procVirtualFree = modkernel32.NewProc("VirtualFree") - procVirtualProtect = modkernel32.NewProc("VirtualProtect") - procTransmitFile = modmswsock.NewProc("TransmitFile") - procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") - procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") - procCertOpenStore = modcrypt32.NewProc("CertOpenStore") - procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") - procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore") - procCertCloseStore = modcrypt32.NewProc("CertCloseStore") - procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") - procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") - procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") - procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") - procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") - procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") - procRegCloseKey = modadvapi32.NewProc("RegCloseKey") - procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") - procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") - procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") - procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") - procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") - procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") - procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") - procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") - procReadConsoleW = modkernel32.NewProc("ReadConsoleW") - procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") - procProcess32FirstW = modkernel32.NewProc("Process32FirstW") - procProcess32NextW = modkernel32.NewProc("Process32NextW") - procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") - procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") - procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") - procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") - procCreateEventW = modkernel32.NewProc("CreateEventW") - procCreateEventExW = modkernel32.NewProc("CreateEventExW") - procOpenEventW = modkernel32.NewProc("OpenEventW") - procSetEvent = modkernel32.NewProc("SetEvent") - procResetEvent = modkernel32.NewProc("ResetEvent") - procPulseEvent = modkernel32.NewProc("PulseEvent") - procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") - procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") - procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") - procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") - procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") - procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") - procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") - procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") - procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") - procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") - procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") - procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") - procGetVolumeInformationByHandleW = modkernel32.NewProc("GetVolumeInformationByHandleW") - procGetVolumeNameForVolumeMountPointW = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW") - procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW") - procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") - procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") - procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") - procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") - procWSAStartup = modws2_32.NewProc("WSAStartup") - procWSACleanup = modws2_32.NewProc("WSACleanup") - procWSAIoctl = modws2_32.NewProc("WSAIoctl") - procsocket = modws2_32.NewProc("socket") - procsetsockopt = modws2_32.NewProc("setsockopt") - procgetsockopt = modws2_32.NewProc("getsockopt") - procbind = modws2_32.NewProc("bind") - procconnect = modws2_32.NewProc("connect") - procgetsockname = modws2_32.NewProc("getsockname") - procgetpeername = modws2_32.NewProc("getpeername") - proclisten = modws2_32.NewProc("listen") - procshutdown = modws2_32.NewProc("shutdown") - procclosesocket = modws2_32.NewProc("closesocket") - procAcceptEx = modmswsock.NewProc("AcceptEx") - procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") - procWSARecv = modws2_32.NewProc("WSARecv") - procWSASend = modws2_32.NewProc("WSASend") - procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") - procWSASendTo = modws2_32.NewProc("WSASendTo") - procgethostbyname = modws2_32.NewProc("gethostbyname") - procgetservbyname = modws2_32.NewProc("getservbyname") - procntohs = modws2_32.NewProc("ntohs") - procgetprotobyname = modws2_32.NewProc("getprotobyname") - procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") - procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") - procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") - procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") - procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") - procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") - procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") - procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") - procGetACP = modkernel32.NewProc("GetACP") - procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") - procTranslateNameW = modsecur32.NewProc("TranslateNameW") - procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") - procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") - procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") - procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") - procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") - procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") - procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") - procGetLengthSid = modadvapi32.NewProc("GetLengthSid") - procCopySid = modadvapi32.NewProc("CopySid") - procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") - procFreeSid = modadvapi32.NewProc("FreeSid") - procEqualSid = modadvapi32.NewProc("EqualSid") - procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") - procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") - procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") - procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") -) - -func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DeregisterEventSource(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CloseServiceHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DeleteService(service Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetLastError() (lasterr error) { - r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) - if r0 != 0 { - lasterr = syscall.Errno(r0) - } - return -} - -func LoadLibrary(libname string) (handle Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(libname) - if err != nil { - return - } - return _LoadLibrary(_p0) -} - -func _LoadLibrary(libname *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(libname) - if err != nil { - return - } - return _LoadLibraryEx(_p0, zero, flags) -} - -func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FreeLibrary(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(procname) - if err != nil { - return - } - return _GetProcAddress(module, _p0) -} - -func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) - proc = uintptr(r0) - if proc == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVersion() (ver uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) - ver = uint32(r0) - if ver == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { - var _p0 *uint16 - if len(buf) > 0 { - _p0 = &buf[0] - } - r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ExitProcess(exitcode uint32) { - syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) - return -} - -func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] - } - r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] - } - r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { - r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) - newlowoffset = uint32(r0) - if newlowoffset == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CloseHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetStdHandle(stdhandle uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetStdHandle(stdhandle uint32, handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func findNextFile1(handle Handle, data *win32finddata1) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindClose(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetCurrentDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { - r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func RemoveDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DeleteFile(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func MoveFile(from *uint16, to *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetComputerName(buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetEndOfFile(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetSystemTimeAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) - return -} - -func GetSystemTimePreciseAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) - return -} - -func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) - rc = uint32(r0) - if rc == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CancelIo(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CancelIoEx(s Handle, o *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { - var _p0 uint32 - if inheritHandles { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid)) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func TerminateProcess(handle Handle, exitcode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetStartupInfo(startupInfo *StartupInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetCurrentProcess() (pseudoHandle Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0) - pseudoHandle = Handle(r0) - if pseudoHandle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { - var _p0 uint32 - if bInheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { - r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) - event = uint32(r0) - if event == 0xffffffff { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetFileType(filehandle Handle) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { - r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetEnvironmentStrings() (envs *uint16, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) - envs = (*uint16)(unsafe.Pointer(r0)) - if envs == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FreeEnvironmentStrings(envs *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetFileAttributes(name *uint16) (attrs uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - attrs = uint32(r0) - if attrs == INVALID_FILE_ATTRIBUTES { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetFileAttributes(name *uint16, attrs uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetCommandLine() (cmd *uint16) { - r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) - cmd = (*uint16)(unsafe.Pointer(r0)) - return -} - -func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { - r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) - argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) - if argv == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func LocalFree(hmem Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) - handle = Handle(r0) - if handle != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FlushFileBuffers(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) - addr = uintptr(r0) - if addr == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func UnmapViewOfFile(addr uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FlushViewOfFile(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func VirtualLock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func VirtualUnlock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) - value = uintptr(r0) - if value == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { - var _p0 uint32 - if watchSubTree { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) - store = Handle(r0) - if store == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) - context = (*CertContext)(unsafe.Pointer(r0)) - if context == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { - r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertCloseStore(store Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { - r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertFreeCertificateChain(ctx *CertChainContext) { - syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) - return -} - -func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) - context = (*CertContext)(unsafe.Pointer(r0)) - if context == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertFreeCertificateContext(ctx *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { - r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func RegCloseKey(key Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func getCurrentProcessId() (pid uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) - pid = uint32(r0) - return -} - -func GetConsoleMode(console Handle, mode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetConsoleMode(console Handle, mode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetCurrentThreadId() (id uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0) - id = uint32(r0) - return -} - -func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { - var _p0 uint32 - if inheritHandle { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) - handle = Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ResetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func PulseEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindVolumeClose(findVolume Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetDriveType(rootPathName *uint16) (driveType uint32) { - r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) - driveType = uint32(r0) - return -} - -func GetLogicalDrives() (drivesBitMask uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) - drivesBitMask = uint32(r0) - if drivesBitMask == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { - r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) - if r0 != 0 { - sockerr = syscall.Errno(r0) - } - return -} - -func WSACleanup() (err error) { - r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) - handle = Handle(r0) - if handle == InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { - r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { - r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func listen(s Handle, backlog int32) (err error) { - r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func shutdown(s Handle, how int32) (err error) { - r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Closesocket(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { - syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) - return -} - -func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) - if r1 == socket_error { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetHostByName(name string) (h *Hostent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return - } - return _GetHostByName(_p0) -} - -func _GetHostByName(name *byte) (h *Hostent, err error) { - r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - h = (*Hostent)(unsafe.Pointer(r0)) - if h == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetServByName(name string, proto string) (s *Servent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return - } - var _p1 *byte - _p1, err = syscall.BytePtrFromString(proto) - if err != nil { - return - } - return _GetServByName(_p0, _p1) -} - -func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { - r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) - s = (*Servent)(unsafe.Pointer(r0)) - if s == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func Ntohs(netshort uint16) (u uint16) { - r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) - u = uint16(r0) - return -} - -func GetProtoByName(name string) (p *Protoent, err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(name) - if err != nil { - return - } - return _GetProtoByName(_p0) -} - -func _GetProtoByName(name *byte) (p *Protoent, err error) { - r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) - p = (*Protoent)(unsafe.Pointer(r0)) - if p == nil { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - var _p0 *uint16 - _p0, status = syscall.UTF16PtrFromString(name) - if status != nil { - return - } - return _DnsQuery(_p0, qtype, options, extra, qrs, pr) -} - -func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) - if r0 != 0 { - status = syscall.Errno(r0) - } - return -} - -func DnsRecordListFree(rl *DNSRecord, freetype uint32) { - syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) - return -} - -func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { - r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) - same = r0 != 0 - return -} - -func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { - r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) - if r0 != 0 { - sockerr = syscall.Errno(r0) - } - return -} - -func FreeAddrInfoW(addrinfo *AddrinfoW) { - syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) - return -} - -func GetIfEntry(pIfRow *MibIfRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - -func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - -func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { - r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) - n = int32(r0) - if n == -1 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { - r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - -func GetACP() (acp uint32) { - r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) - acp = uint32(r0) - return -} - -func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { - r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) - nwrite = int32(r0) - if nwrite == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) - if r1&0xff == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { - r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) - if r0 != 0 { - neterr = syscall.Errno(r0) - } - return -} - -func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { - r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) - if r0 != 0 { - neterr = syscall.Errno(r0) - } - return -} - -func NetApiBufferFree(buf *byte) (neterr error) { - r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) - if r0 != 0 { - neterr = syscall.Errno(r0) - } - return -} - -func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetLengthSid(sid *SID) (len uint32) { - r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - len = uint32(r0) - return -} - -func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func FreeSid(sid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { - r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) - isEqual = r0 != 0 - return -} - -func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { - r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func OpenProcessToken(h Handle, access uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -}